# HG changeset patch # User Dremov Kirill (Nokia-D-MSW/Tampere) # Date 1261034091 -7200 # Node ID 33413c0669b99c64e9a11f55cdc79bef714676a7 Revision: 200949 Kit: 200951 diff -r 000000000000 -r 33413c0669b9 group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,131 @@ +/* +* Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Build information file for VPN components +* +*/ + +#include + +PRJ_EXPORTS + +#ifdef FF_VPN_CLIENT +../vpnengine/dmadengine/rom/dmadengine.iby CORE_MW_LAYER_IBY_EXPORT_PATH(dmadengine.iby) +../vpnengine/dmadipsecvpn/rom/dmadipsecvpn.iby CORE_MW_LAYER_IBY_EXPORT_PATH(dmadipsecvpn.iby) +../vpnengine/dmadpki/rom/dmadpki.iby CORE_MW_LAYER_IBY_EXPORT_PATH(dmadpki.iby) +../vpnengine/eventmediator/rom/eventmediator.iby CORE_MW_LAYER_IBY_EXPORT_PATH(eventmediator.iby) +../vpnengine/eventmediatorapi/rom/eventmediatorapi.iby CORE_MW_LAYER_IBY_EXPORT_PATH(eventmediatorapi.iby) +../vpnengine/eventviewer/rom/eventviewer.iby CORE_MW_LAYER_IBY_EXPORT_PATH(eventviewer.iby) +../vpnengine/ikepolparser/rom/ikepolparser.iby CORE_MW_LAYER_IBY_EXPORT_PATH(ikepolparser.iby) +../vpnengine/ikesocket/rom/ikesocket.iby CORE_MW_LAYER_IBY_EXPORT_PATH(ikesocket.iby) +../vpnengine/ikecert/rom/ikecert.iby CORE_MW_LAYER_IBY_EXPORT_PATH(ikecert.iby) +../vpnengine/kmdapi/rom/kmdapi.iby CORE_MW_LAYER_IBY_EXPORT_PATH(kmdapi.iby) +../vpnengine/kmdserver/rom/kmdserver.iby CORE_MW_LAYER_IBY_EXPORT_PATH(kmdserver.iby) +../vpnengine/ikeutils/rom/ikeutils.iby CORE_MW_LAYER_IBY_EXPORT_PATH(ikeutils.iby) +../vpnengine/ikev1lib/rom/ikev1lib.iby CORE_MW_LAYER_IBY_EXPORT_PATH(ikev1lib.iby) +../vpnengine/ikev2lib/rom/ikev2lib.iby CORE_MW_LAYER_IBY_EXPORT_PATH(ikev2lib.iby) +../vpnengine/pkiservice/rom/pkiservice.iby CORE_MW_LAYER_IBY_EXPORT_PATH(pkiservice.iby) +../vpnengine/pkiserviceapi/rom/pkiserviceapi.iby CORE_MW_LAYER_IBY_EXPORT_PATH(pkiserviceapi.iby) +../vpnengine/sit/rom/eventmedsit.iby CORE_MW_LAYER_IBY_EXPORT_PATH(eventmedsit.iby) +../vpnengine/utlbase64/rom/utlbase64.iby CORE_MW_LAYER_IBY_EXPORT_PATH(utlbase64.iby) +../vpnengine/utlcrypto/rom/utlcrypto.iby CORE_MW_LAYER_IBY_EXPORT_PATH(utlcrypto.iby) +../vpnengine/utlpkcs10/rom/utlpkcs10.iby CORE_MW_LAYER_IBY_EXPORT_PATH(utlpkcs10.iby) +../vpnengine/utlpkcs12/rom/utlpkcs12.iby CORE_MW_LAYER_IBY_EXPORT_PATH(utlpkcs12.iby) +../vpnengine/utlxml/rom/utlxml.iby CORE_MW_LAYER_IBY_EXPORT_PATH(utlxml.iby) +../vpnengine/vpncleaner/rom/vpncleaner.iby CORE_MW_LAYER_IBY_EXPORT_PATH(vpncleaner.iby) +../vpnengine/vpnconnagt/rom/vpnconnagt.iby CORE_MW_LAYER_IBY_EXPORT_PATH(vpnconnagt.iby) +../vpnengine/vpnmanager/rom/vpnmanager.iby CORE_MW_LAYER_IBY_EXPORT_PATH(vpnmanager.iby) +../vpnengine/vpnins/rom/vpnins.iby CORE_MW_LAYER_IBY_EXPORT_PATH(vpnins.iby) +../vpnengine/vpnipsecpolparser/rom/vpnipsecpolparser.iby CORE_MW_LAYER_IBY_EXPORT_PATH(vpnipsecpolparser.iby) + +../vpnui/vpnecomnotifier/rom/vpnecomnotifier.iby CORE_MW_LAYER_IBY_EXPORT_PATH(vpnecomnotifier.iby) +../vpnui/vpndialogmanager/rom/vpndialogmanager.iby CORE_MW_LAYER_IBY_EXPORT_PATH(vpndialogmanager.iby) +../vpnui/vpnmanagementui/rom/vpnmanagementui.iby CORE_MW_LAYER_IBY_EXPORT_PATH(vpnmanagementui.iby) +../vpnui/vpnpolins/rom/vpnpolins.iby CORE_MW_LAYER_IBY_EXPORT_PATH(vpnpolins.iby) + +../vpnui/vpnecomnotifier/rom/vpnecomnotifierResources.iby LANGUAGE_MW_LAYER_IBY_EXPORT_PATH(vpnecomnotifierResources.iby) +../vpnui/vpnmanagementui/rom/vpnmanagementuiResources.iby LANGUAGE_MW_LAYER_IBY_EXPORT_PATH(vpnmanagementuiResources.iby) + +#ifndef FF_GENERIC_ACCESS_NETWORK // UMA not supported +../vpnui/vpnpolicyrecognizer/rom/vpnpolicyrecognizer.iby CORE_MW_LAYER_IBY_EXPORT_PATH(vpnpolicyrecognizer.iby) +../rom/ipsecvpn.iby CORE_MW_LAYER_IBY_EXPORT_PATH(ipsecvpn.iby) +#endif + + +#endif // FF_VPN_CLIENT + +// vpnapi.dll should be in rom always +../vpnapiimpl/rom/vpnapi.iby CORE_MW_LAYER_IBY_EXPORT_PATH(vpnapi.iby) + +// export localised loc file +../vpnui/vpnecomnotifier/loc/vpnnotifier.loc MW_LAYER_LOC_EXPORT_PATH(vpnnotifier.loc) + +./vpnclient_version_update.flm /epoc32/tools/makefile_templates/vpnclient/vpnclient_version_update.flm +./vpnclient_version_update.xml /epoc32/tools/makefile_templates/vpnclient/vpnclient_version_update.xml + + +PRJ_MMPFILES + +// Update version information +#ifndef SBSV2 +gnumakefile vpnclient_version_update.make +#endif + +#include "../vpnc_plat/vpnapi/group/bld.inf" +#include "../vpnapiimpl/group/bld.inf" + +#include "../vpnengine/eventmediatorapi/group/bld.inf" +#include "../vpnengine/eventviewer/group/bld.inf" +#include "../vpnengine/vpnins/group/bld.inf" +#include "../vpnengine/ikepolparser/group/bld.inf" +#include "../vpnengine/utlbase64/group/bld.inf" +#include "../vpnengine/utlcrypto/group/bld.inf" +#include "../vpnengine/utlxml/group/bld.inf" +#include "../vpnengine/utlpkcs10/group/bld.inf" + +#include "../vpnengine/pkiserviceapi/group/bld.inf" +#include "../vpnengine/ikecert/group/bld.inf" +#include "../vpnengine/kmdapi/group/bld.inf" +#include "../vpnengine/kmdserver/group/bld.inf" +#include "../vpnengine/ikeutils/group/bld.inf" +#include "../vpnengine/ikev1lib/group/bld.inf" +#include "../vpnengine/ikev2lib/group/bld.inf" +#include "../vpnengine/vpnipsecpolparser/group/bld.inf" +#include "../vpnengine/sit/group/bld.inf" + +#include "../vpnengine/vpntcwrapper/group/bld.inf" +#include "../vpnui/vpnecomnotifier/group/bld.inf" +#include "../vpnui/vpndialogmanager/group/bld.inf" +#include "../vpnengine/eventmediator/group/bld.inf" +#include "../vpnengine/pkiservice/group/bld.inf" +#include "../vpnengine/vpnconnagt/group/bld.inf" +#include "../vpnengine/vpnmanager/group/bld.inf" +#include "../vpnui/vpnmanagementui/group/bld.inf" +#include "../vpnui/vpnpolins/group/bld.inf" +#include "../vpnui/vpnpolicyrecognizer/group/bld.inf" +#include "../vpnengine/vpncleaner/group/bld.inf" + +#include "../vpnengine/utlpkcs12/group/bld.inf" +#include "../vpnengine/dmadengine/group/bld.inf" +#include "../vpnengine/dmadipsecvpn/group/bld.inf" +#include "../vpnengine/dmadpki/group/bld.inf" +#include "../vpnengine/ikesocket/group/bld.inf" + +#include "../help/group/bld.inf" + +PRJ_EXTENSIONS + +#ifdef SBSV2 +START EXTENSION vpnclient/version_update vpnclient_vu +END +#endif diff -r 000000000000 -r 33413c0669b9 group/update_version_h.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/group/update_version_h.pl Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,85 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# Updates version.h information with current date. +# + +use strict; +use Cwd; +use POSIX qw(strftime); + +my $PLATFORM_LONG = "4_2"; +my $PLATFORM_SHORT = "42"; + +sub update_version_h +{ + my ($version_path, $platform) = @_; + + # Check path + if (! -e $version_path) + { + die "version.h can't be found from $version_path"; + } + + # Form version strings + my $version = strftime($platform."_%y%m%d", localtime()); + my $builddate = localtime(); + + # Backup + if (-e "$version_path.BACKUP") + { + chmod 0666, "$version_path.BACKUP"; + unlink "$version_path.BACKUP"; + } + chmod 0666, $version_path; + rename $version_path, "$version_path.BACKUP"; + + my ($infile, $outfile); + open $infile, "<$version_path.BACKUP" or die "Can't open $version_path.BACKUP : $!"; + open $outfile, ">$version_path" or die "Can't open $version_path : $!"; + while (<$infile>) + { + my $line = $_; + my $pattern1 = '_LIT\(KVersion.*?;'; + my $replacement1 = "_LIT(KVersion, \"$version\");"; + + my $pattern2 = '_LIT\(KBuildDate.*?;'; + my $replacement2 = "_LIT(KBuildDate, \"$builddate\");"; + + if ($line =~ s/$pattern1/$replacement1/g) + { + print "Updated KVersion\n"; + } + elsif ($line =~ s/$pattern2/$replacement2/g) + { + print "Updated KBuildDate\n"; + } + print $outfile $line; + } + close $infile; + close $outfile; +} + + +my $oldpwd = getcwd(); +chdir ".."; + +### VERSION.H ########### + +# version.h +update_version_h( + 'vpnengine/vpncommon/inc/version.h', + $PLATFORM_LONG); + +chdir $oldpwd; diff -r 000000000000 -r 33413c0669b9 group/vpnclient_version_update.flm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/group/vpnclient_version_update.flm Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,38 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Symbian Foundation License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# + +# ============================================================================ +# vpnclient_version_update.flm +# This flm will update the version of vpnclient into generated version.h file. +# +# Version update Function Like Makefile (FLM) +# The file destinations relative to EPOCROOT +# ============================================================================ + + +define updateversion +$(GUARD):=1 + +BITMAP:: $(EXTENSION_ROOT)/$(VU_TOOL) + $(call startrule,vpnclient_version_update,FORCESUCCESS) \ + cd $(EXTENSION_ROOT) && $(PERL) $(VU_TOOL) \ + $(call endrule,vpnclient_version_update) +endef + +ifeq ($($(GUARD)),) +$(eval -$(updateversion)) +endif + diff -r 000000000000 -r 33413c0669b9 group/vpnclient_version_update.make --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/group/vpnclient_version_update.make Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,4 @@ +MAKMAKE : + echo Update VpnClient version.h + perl update_version_h.pl +BLD FREEZE CLEANLIB RESOURCE LIB RELEASABLES CLEAN SAVESPACE FINAL: diff -r 000000000000 -r 33413c0669b9 group/vpnclient_version_update.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/group/vpnclient_version_update.xml Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,34 @@ + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r 33413c0669b9 help/data/xhtml.zip Binary file help/data/xhtml.zip has changed diff -r 000000000000 -r 33413c0669b9 help/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/help/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - Initial contribution +* +* Contributors: +* +* +* Description: +* Export help related files. +* +*/ + +#include +PRJ_EXPORTS +:zip ../data/xhtml.zip /epoc32/data/z/resource/ overwrite +:zip ../data/xhtml.zip /epoc32/winscw/c/resource/ overwrite + +../inc/vpn.hlp.hrh MW_LAYER_PLATFORM_EXPORT_PATH(csxhelp/vpn.hlp.hrh) + +#ifndef FF_GENERIC_ACCESS_NETWORK // UMA not supported +../rom/vpnclienthelps_variant.iby CUSTOMER_APP_LAYER_IBY_EXPORT_PATH(vpnclienthelps_variant.iby) +#endif \ No newline at end of file diff -r 000000000000 -r 33413c0669b9 help/inc/vpn.hlp.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/help/inc/vpn.hlp.hrh Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Symbian Foundation License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +// +// vpn.hlp.hrh generated by CSXHelp Utilities. +// + +#ifndef __VPN_HLP_HRH__ +#define __VPN_HLP_HRH__ + +_LIT(KSET_HLP_VPN_LOG_VIEW, "SET_HLP_VPN_LOG_VIEW"); // +_LIT(KSET_HLP_VPN_CONFIG_MAIN, "SET_HLP_VPN_CONFIG_MAIN"); // +_LIT(KSET_HLP_VPN_POLICY_VIEW, "SET_HLP_VPN_POLICY_VIEW"); // +_LIT(KSET_HLP_VPN_POLICY_SERVERS, "SET_HLP_VPN_POLICY_SERVERS"); // +_LIT(KSET_HLP_VPN_POLICY_SERVER_SET, "SET_HLP_VPN_POLICY_SERVER_SET"); // + +#endif \ No newline at end of file diff -r 000000000000 -r 33413c0669b9 help/rom/vpnclienthelps_variant.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/help/rom/vpnclienthelps_variant.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#ifndef __VPNCLIENTHELPS_VARIANT_IBY__ +#define __VPNCLIENTHELPS_VARIANT_IBY__ + +#if defined(FF_S60_HELPS_IN_USE) && defined(FF_VPN_CLIENT) + data=LOCALISE(DATAZ_\resource\xhtml\%02d\0x10200EC4\contents.zip, RESOURCE_FILES_DIR\xhtml\%02d\0x10200EC4\contents.zip) + data=LOCALISE(DATAZ_\resource\xhtml\%02d\0x10200EC4\index.xml, RESOURCE_FILES_DIR\xhtml\%02d\0x10200EC4\index.xml) + data=LOCALISE(DATAZ_\resource\xhtml\%02d\0x10200EC4\keywords.xml, RESOURCE_FILES_DIR\xhtml\%02d\0x10200EC4\keywords.xml) + data=LOCALISE(DATAZ_\resource\xhtml\%02d\0x10200EC4\meta.xml, RESOURCE_FILES_DIR\xhtml\%02d\0x10200EC4\meta.xml) +#endif + +#endif \ No newline at end of file diff -r 000000000000 -r 33413c0669b9 layers.sysdef.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layers.sysdef.xml Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,16 @@ + + +]> + + + + + + + + + + diff -r 000000000000 -r 33413c0669b9 package_definition.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/package_definition.xml Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r 33413c0669b9 rom/ipsecvpn.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rom/ipsecvpn.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Image description file for project +* vpnclient +* +*/ + + +#ifndef __IPSECVPN_IBY__ +#define __IPSECVPN_IBY__ + +#ifdef SYMBIAN_EXCLUDE_IPSEC + +REM Feature VPNCLIENT STUB SISSES not included in this rom + +#else + +data=ZSYSTEM\install\ipsecvpn.sis system\install\ipsecvpn.sis +data=ZSYSTEM\install\ipsecvpn_vpnpolins.sis system\install\ipsecvpn_vpnpolins.sis + +#endif // SYMBIAN_EXCLUDE_IPSEC + +#endif // __IPSECVPN_IBY__ diff -r 000000000000 -r 33413c0669b9 sysdef_1_4_0.dtd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysdef_1_4_0.dtd Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r 33413c0669b9 vpnapiimpl/BMARM/VPNAPIU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnapiimpl/BMARM/VPNAPIU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,18 @@ +EXPORTS + __8RVpnServ @ 1 NONAME R3UNUSED ; RVpnServ::RVpnServ(void) + CancelImport__8RVpnServ @ 2 NONAME R3UNUSED ; RVpnServ::CancelImport(void) + ChangePassword__8RVpnServRCt5TPckg1Zt4TBuf1i50R14TRequestStatus @ 3 NONAME R3UNUSED ; RVpnServ::ChangePassword(TPckg > const &, TRequestStatus &) + Close__8RVpnServ @ 4 NONAME R3UNUSED ; RVpnServ::Close(void) + Connect__8RVpnServ @ 5 NONAME R3UNUSED ; RVpnServ::Connect(void) + DeletePolicy__8RVpnServRCt4TBuf1i50 @ 6 NONAME R3UNUSED ; RVpnServ::DeletePolicy(TBuf<50> const &) + EnumeratePolicies__8RVpnServRi @ 7 NONAME R3UNUSED ; RVpnServ::EnumeratePolicies(int &) + GetPolicyDetails__8RVpnServRCt4TBuf1i50R17TVpnPolicyDetails @ 8 NONAME R3UNUSED ; RVpnServ::GetPolicyDetails(TBuf<50> const &, TVpnPolicyDetails &) + GetPolicyInfoList__8RVpnServPt13CArrayFixFlat1Z14TVpnPolicyInfo @ 9 NONAME R3UNUSED ; RVpnServ::GetPolicyInfoList(CArrayFixFlat *) + ImportPolicy__8RVpnServRC7TDesC16R14TRequestStatus @ 10 NONAME R3UNUSED ; RVpnServ::ImportPolicy(TDesC16 const &, TRequestStatus &) + Version__C8RVpnServ @ 11 NONAME R3UNUSED ; RVpnServ::Version(void) const + CancelChange__8RVpnServ @ 12 NONAME R3UNUSED ; RVpnServ::CancelChange(void) + GetPolicyData__8RVpnServRCt4TBuf1i50RP6HBufC8 @ 13 NONAME R3UNUSED ; RVpnServ::GetPolicyData(TBuf<50> const &, HBufC8 *&) + UpdatePolicyData__8RVpnServRCt4TBuf1i50RC6TDesC8 @ 14 NONAME R3UNUSED ; RVpnServ::UpdatePolicyData(TBuf<50> const &, TDesC8 const &) + UpdatePolicyDetails__8RVpnServR17TVpnPolicyDetails @ 15 NONAME R3UNUSED ; RVpnServ::UpdatePolicyDetails(TVpnPolicyDetails &) + AddPolicy__8RVpnServR17TVpnPolicyDetailsRC6TDesC8 @ 16 NONAME R3UNUSED ; RVpnServ::AddPolicy(TVpnPolicyDetails &, TDesC8 const &) + diff -r 000000000000 -r 33413c0669b9 vpnapiimpl/EABI/vpnapiU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnapiimpl/EABI/vpnapiU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,20 @@ +EXPORTS + _ZN8RVpnServ12CancelChangeEv @ 1 NONAME + _ZN8RVpnServ12CancelImportEv @ 2 NONAME + _ZN8RVpnServ12DeletePolicyERK4TBufILi50EE @ 3 NONAME + _ZN8RVpnServ12ImportPolicyERK7TDesC16R14TRequestStatus @ 4 NONAME + _ZN8RVpnServ13GetPolicyDataERK4TBufILi50EERP6HBufC8 @ 5 NONAME + _ZN8RVpnServ14ChangePasswordERK5TPckgI4TBufILi50EEER14TRequestStatus @ 6 NONAME + _ZN8RVpnServ16GetPolicyDetailsERK4TBufILi50EER17TVpnPolicyDetails @ 7 NONAME + _ZN8RVpnServ17EnumeratePoliciesERi @ 8 NONAME + _ZN8RVpnServ17GetPolicyInfoListEP13CArrayFixFlatI14TVpnPolicyInfoE @ 9 NONAME + _ZN8RVpnServ5CloseEv @ 10 NONAME + _ZN8RVpnServ7ConnectEv @ 11 NONAME + _ZN8RVpnServC1Ev @ 12 NONAME + _ZN8RVpnServC2Ev @ 13 NONAME + _ZNK8RVpnServ7VersionEv @ 14 NONAME + _ZN8RVpnServ16UpdatePolicyDataERK4TBufILi50EERK6TDesC8 @ 15 NONAME + _ZN8RVpnServ19UpdatePolicyDetailsERK17TVpnPolicyDetails @ 16 NONAME + _ZN8RVpnServ9AddPolicyER17TVpnPolicyDetailsRK6TDesC8 @ 17 NONAME + _ZN8RVpnServ19UpdatePolicyDetailsER17TVpnPolicyDetails @ 18 NONAME + diff -r 000000000000 -r 33413c0669b9 vpnapiimpl/bwins/VPNAPIU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnapiimpl/bwins/VPNAPIU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,19 @@ +EXPORTS + ??0RVpnServ@@QAE@XZ @ 1 NONAME ; public: __thiscall RVpnServ::RVpnServ(void) + ?CancelChange@RVpnServ@@QAEXXZ @ 2 NONAME ; public: void __thiscall RVpnServ::CancelChange(void) + ?CancelImport@RVpnServ@@QAEXXZ @ 3 NONAME ; public: void __thiscall RVpnServ::CancelImport(void) + ?ChangePassword@RVpnServ@@QAEXABV?$TPckg@V?$TBuf@$0DC@@@@@AAVTRequestStatus@@@Z @ 4 NONAME ; public: void __thiscall RVpnServ::ChangePassword(class TPckg > const &,class TRequestStatus &) + ?Close@RVpnServ@@QAEXXZ @ 5 NONAME ; public: void __thiscall RVpnServ::Close(void) + ?Connect@RVpnServ@@QAEHXZ @ 6 NONAME ; public: int __thiscall RVpnServ::Connect(void) + ?DeletePolicy@RVpnServ@@QAEHABV?$TBuf@$0DC@@@@Z @ 7 NONAME ; public: int __thiscall RVpnServ::DeletePolicy(class TBuf<50> const &) + ?EnumeratePolicies@RVpnServ@@QAEHAAH@Z @ 8 NONAME ; public: int __thiscall RVpnServ::EnumeratePolicies(int &) + ?GetPolicyDetails@RVpnServ@@QAEHABV?$TBuf@$0DC@@@AAUTVpnPolicyDetails@@@Z @ 9 NONAME ; public: int __thiscall RVpnServ::GetPolicyDetails(class TBuf<50> const &,struct TVpnPolicyDetails &) + ?GetPolicyInfoList@RVpnServ@@QAEHPAV?$CArrayFixFlat@UTVpnPolicyInfo@@@@@Z @ 10 NONAME ; public: int __thiscall RVpnServ::GetPolicyInfoList(class CArrayFixFlat *) + ?ImportPolicy@RVpnServ@@QAEXABVTDesC16@@AAVTRequestStatus@@@Z @ 11 NONAME ; public: void __thiscall RVpnServ::ImportPolicy(class TDesC16 const &,class TRequestStatus &) + ?Version@RVpnServ@@QBE?AVTVersion@@XZ @ 12 NONAME ; public: class TVersion __thiscall RVpnServ::Version(void)const + ?GetPolicyData@RVpnServ@@QAEHABV?$TBuf@$0DC@@@AAPAVHBufC8@@@Z @ 13 NONAME ; public: int __thiscall RVpnServ::GetPolicyData(class TBuf<50> const &,class HBufC8 * &) + ?AddPolicy@RVpnServ@@QAEHAAUTVpnPolicyDetails@@ABVTDesC8@@@Z @ 14 NONAME ; int RVpnServ::AddPolicy(struct TVpnPolicyDetails &, class TDesC8 const &) + ?UpdatePolicyData@RVpnServ@@QAEHABV?$TBuf@$0DC@@@ABVTDesC8@@@Z @ 15 NONAME ; int RVpnServ::UpdatePolicyData(class TBuf<50> const &, class TDesC8 const &) + ?UpdatePolicyDetails@RVpnServ@@QAEHABUTVpnPolicyDetails@@@Z @ 16 NONAME ; int RVpnServ::UpdatePolicyDetails(struct TVpnPolicyDetails const &) + ?UpdatePolicyDetails@RVpnServ@@QAEHAAUTVpnPolicyDetails@@@Z @ 17 NONAME ; int RVpnServ::UpdatePolicyDetails(struct TVpnPolicyDetails &) + diff -r 000000000000 -r 33413c0669b9 vpnapiimpl/data/vpnerr.ra --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnapiimpl/data/vpnerr.ra Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,490 @@ +/* +* Copyright (c) 2003-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Resource definitions for VPN API. +* +*/ + + +/* IPSec Policy API errors */ + +RESOURCE ARRAY r_error_array_ipsecpolapi_errors + { + items= + { + SINGLE_ERROR + { + text=r_error_EOpenSocketError; /* -5135 */ + }, + SINGLE_ERROR + { + text=r_error_EBindSocketError; /* -5136 */ + }, + SINGLE_ERROR + { + text=r_error_EOpenAlgorithmsFileError; /* -5137 */ + }, + SINGLE_ERROR + { + text=r_error_ESecpolSocketSetOptError; /* -5138 */ + }, + SINGLE_ERROR + { + text=r_error_EUnknownPolicyHandle; /* -5139 */ + }, + SINGLE_ERROR + { + text=r_error_EParsingError; /* -5140 */ + }, + SINGLE_ERROR + { + text=r_error_EWriteSocketError; /* -5141 */ + }, + SINGLE_ERROR + { + text=r_error_ESecpolReaderError; /* -5142 */ + }, + SINGLE_ERROR + { + text=r_error_ENoSelectorFound; /* -5143 */ + }, + SINGLE_ERROR + { + text=r_error_ENoMemory; /* -5144 */ + }, + SINGLE_ERROR + { + text=r_error_EInboundOutboundConflict; /* -5145 */ + }, + SINGLE_ERROR + { + text=r_error_ESelectorConflict; /* -5146 */ + }, + SINGLE_ERROR + { + text=r_error_ENoConflictInfoFound; /* -5147 */ + } + }; + } + +RESOURCE TBUF r_error_EOpenSocketError { buf=STRING_r_error_EOpenSocketError; } +RESOURCE TBUF r_error_EBindSocketError { buf=STRING_r_error_EBindSocketError; } +RESOURCE TBUF r_error_EOpenAlgorithmsFileError { buf=STRING_r_error_EOpenAlgorithmsFileError; } +RESOURCE TBUF r_error_ESecpolSocketSetOptError { buf=STRING_r_error_ESecpolSocketSetOptError; } +RESOURCE TBUF r_error_EUnknownPolicyHandle { buf=STRING_r_error_EUnknownPolicyHandle; } +RESOURCE TBUF r_error_EParsingError { buf=STRING_r_error_EParsingError; } +RESOURCE TBUF r_error_EWriteSocketError { buf=STRING_r_error_EWriteSocketError; } +RESOURCE TBUF r_error_ESecpolReaderError { buf=STRING_r_error_ESecpolReaderError; } +RESOURCE TBUF r_error_ENoSelectorFound { buf=STRING_r_error_ENoSelectorFound; } +RESOURCE TBUF r_error_ENoMemory { buf=STRING_r_error_ENoMemory; } +RESOURCE TBUF r_error_EInboundOutboundConflict { buf=STRING_r_error_EInboundOutboundConflict; } +RESOURCE TBUF r_error_ESelectorConflict { buf=STRING_r_error_ESelectorConflict; } +RESOURCE TBUF r_error_ENoConflictInfoFound { buf=STRING_r_error_ENoConflictInfoFound; } + +/* VPN API errors */ + +RESOURCE ARRAY r_error_array_vpnapi_errors + { + items= + { + SINGLE_ERROR + { + text=r_error_KVpnErrNoPolicyFile; /* -5229 */ + }, + SINGLE_ERROR + { + text=r_error_KVpnErrNoPolicyInfoFile; /* -5230 */ + }, + SINGLE_ERROR + { + text=r_error_KVpnErrInvalidPolicyFile; /* -5231 */ + }, + SINGLE_ERROR + { + text=r_error_KVpnErrPolicyNotFound; /* -5232 */ + }, + SINGLE_ERROR + { + text=r_error_KVpnErrInvalidCaCertFile; /* -5233 */ + }, + SINGLE_ERROR + { + text=r_error_KVpnErrPeerCertFileMissing; /* -5234 */ + }, + SINGLE_ERROR + { + text=r_error_KVpnErrInvalidUserCertFile; /* -5235 */ + }, + SINGLE_ERROR + { + text=r_error_KVpnErrInvalidUserPrivKeyFile; /* -5236 */ + }, + SINGLE_ERROR + { + text=r_error_KVpnErrImportOngoing; /* -5237 */ + }, + SINGLE_ERROR + { + text=r_error_KVpnErrPwdChangeOngoing; /* -5238 */ + }, + SINGLE_ERROR + { + text=r_error_KVpnErrPolicyCountChanged; /* -5239 */ + } + }; + } + +RESOURCE TBUF r_error_KVpnErrNoPolicyFile { buf=STRING_r_error_KVpnErrNoPolicyFile; } +RESOURCE TBUF r_error_KVpnErrNoPolicyInfoFile { buf=STRING_r_error_KVpnErrNoPolicyInfoFile; } +RESOURCE TBUF r_error_KVpnErrInvalidPolicyFile { buf=STRING_r_error_KVpnErrInvalidPolicyFile; } +RESOURCE TBUF r_error_KVpnErrPolicyNotFound { buf=STRING_r_error_KVpnErrPolicyNotFound; } +RESOURCE TBUF r_error_KVpnErrInvalidCaCertFile { buf=STRING_r_error_KVpnErrInvalidCaCertFile; } +RESOURCE TBUF r_error_KVpnErrPeerCertFileMissing { buf=STRING_r_error_KVpnErrPeerCertFileMissing; } +RESOURCE TBUF r_error_KVpnErrInvalidUserCertFile { buf=STRING_r_error_KVpnErrInvalidUserCertFile; } +RESOURCE TBUF r_error_KVpnErrInvalidUserPrivKeyFile { buf=STRING_r_error_KVpnErrInvalidUserPrivKeyFile; } +RESOURCE TBUF r_error_KVpnErrImportOngoing { buf=STRING_r_error_KVpnErrImportOngoing; } +RESOURCE TBUF r_error_KVpnErrPwdChangeOngoing { buf=STRING_r_error_KVpnErrPwdChangeOngoing; } +RESOURCE TBUF r_error_KVpnErrPolicyCountChanged { buf=STRING_r_error_KVpnErrPolicyCountChanged; } + +/* PKI Service API errors */ + +RESOURCE ARRAY r_error_array_pkiserviceapi_errors + { + items= + { + SINGLE_ERROR + { + text=r_error_KPKIErrWrongObjectType; /* -5240 */ + }, + SINGLE_ERROR + { + text=r_error_KPKIErrObjectUninitialized; /* -5241 */ + }, + SINGLE_ERROR + { + text=r_error_KPKIErrPassword; /* -5242 */ + }, + SINGLE_ERROR + { + text=r_error_KPKIErrServiceBusy; /* -5243 */ + }, + SINGLE_ERROR + { + text=r_error_KPKIErrCancel; /* -5244 */ + }, + SINGLE_ERROR + { + text=r_error_KPKIErrBufferTooShort; /* -5245 */ + }, + SINGLE_ERROR + { + text=r_error_KPKIErrCertRequestParam; /* -5246 */ + }, + SINGLE_ERROR + { + text=r_error_KPKIErrCertRequest; /* -5247 */ + }, + SINGLE_ERROR + { + text=r_error_KPKIErrNotFound; /* -5248 */ + }, + SINGLE_ERROR + { + text=r_error_KPKIErrAmbiguous; /* -5249 */ + }, + SINGLE_ERROR + { + text=r_error_KPKIErrNotSupported; /* -5250 */ + }, + SINGLE_ERROR + { + text=r_error_KPKIErrUnexpectedState; /* -5251 */ + }, + SINGLE_ERROR + { + text=r_error_KPKIErrKeyStoreEmpty; /* -5252 */ + } + }; + } + +RESOURCE TBUF r_error_KPKIErrWrongObjectType { buf=STRING_r_error_KPKIErrWrongObjectType; } +RESOURCE TBUF r_error_KPKIErrObjectUninitialized { buf=STRING_r_error_KPKIErrObjectUninitialized; } +RESOURCE TBUF r_error_KPKIErrPassword { buf=STRING_r_error_KPKIErrPassword; } +RESOURCE TBUF r_error_KPKIErrServiceBusy { buf=STRING_r_error_KPKIErrServiceBusy; } +RESOURCE TBUF r_error_KPKIErrCancel { buf=STRING_r_error_KPKIErrCancel; } +RESOURCE TBUF r_error_KPKIErrBufferTooShort { buf=STRING_r_error_KPKIErrBufferTooShort; } +RESOURCE TBUF r_error_KPKIErrCertRequestParam { buf=STRING_r_error_KPKIErrCertRequestParam; } +RESOURCE TBUF r_error_KPKIErrCertRequest { buf=STRING_r_error_KPKIErrCertRequest; } +RESOURCE TBUF r_error_KPKIErrNotFound { buf=STRING_r_error_KPKIErrNotFound; } +RESOURCE TBUF r_error_KPKIErrAmbiguous { buf=STRING_r_error_KPKIErrAmbiguous; } +RESOURCE TBUF r_error_KPKIErrNotSupported { buf=STRING_r_error_KPKIErrNotSupported; } +RESOURCE TBUF r_error_KPKIErrUnexpectedState { buf=STRING_r_error_KPKIErrUnexpectedState; } +RESOURCE TBUF r_error_KPKIErrKeyStoreEmpty { buf=STRING_r_error_KPKIErrKeyStoreEmpty; } + +/* KMD API errors */ + +RESOURCE ARRAY r_error_array_kmdapi_errors + { + items= + { + SINGLE_ERROR + { + text=r_error_KKmdTooWeakCryptoLib; /* -5253 */ + }, + SINGLE_ERROR + { + text=r_error_KKmdNoAlgorithmsFile; /* -5254 */ + }, + SINGLE_ERROR + { + text=r_error_KKmdIkePolicyFileErr; /* -5255 */ + }, + SINGLE_ERROR + { + text=r_error_KKmdIkeNegotFailed; /* -5256 */ + }, + SINGLE_ERROR + { + text=r_error_KKmdIkeNoResponse; /* -5257 */ + }, + SINGLE_ERROR + { + text=r_error_KKmdIkeNoProposalErr; /* -5258 */ + }, + SINGLE_ERROR + { + text=r_error_KKmdIkeAuthFailedErr; /* -5259 */ + }, + SINGLE_ERROR + { + text=r_error_KKmdIkePeerAuthFailed; /* -5260 */ + }, + SINGLE_ERROR + { + text=r_error_KKmdIkeNoCertFoundErr; /* -5261 */ + }, + SINGLE_ERROR + { + text=r_error_KKmdIkeNoPolicyErr; /* -5262 */ + } + }; + } + +RESOURCE TBUF r_error_KKmdTooWeakCryptoLib { buf=STRING_r_error_KKmdTooWeakCryptoLib; } +RESOURCE TBUF r_error_KKmdNoAlgorithmsFile { buf=STRING_r_error_KKmdNoAlgorithmsFile; } +RESOURCE TBUF r_error_KKmdIkePolicyFileErr { buf=STRING_r_error_KKmdIkePolicyFileErr; } +RESOURCE TBUF r_error_KKmdIkeNegotFailed { buf=STRING_r_error_KKmdIkeNegotFailed; } +RESOURCE TBUF r_error_KKmdIkeNoResponse { buf=STRING_r_error_KKmdIkeNoResponse; } +RESOURCE TBUF r_error_KKmdIkeNoProposalErr { buf=STRING_r_error_KKmdIkeNoProposalErr; } +RESOURCE TBUF r_error_KKmdIkeAuthFailedErr { buf=STRING_r_error_KKmdIkeAuthFailedErr; } +RESOURCE TBUF r_error_KKmdIkePeerAuthFailed { buf=STRING_r_error_KKmdIkePeerAuthFailed; } +RESOURCE TBUF r_error_KKmdIkeNoCertFoundErr { buf=STRING_r_error_KKmdIkeNoCertFoundErr; } +RESOURCE TBUF r_error_KKmdIkeNoPolicyErr { buf=STRING_r_error_KKmdIkeNoPolicyErr; } + +/* IKE policy parser errors */ + +RESOURCE ARRAY r_error_array_ikepolparser_errors + { + items= + { + SINGLE_ERROR + { + text=r_error_KSecParserErrMode; /* -5263 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrNotify; /* -5264 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrCommit; /* -5265 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrIpsecExpire; /* -5266 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrSendCert; /* -5267 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrInitialContact; /* -5268 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrResponderLifetime;/* -5269 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrReplayStatus; /* -5270 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrGroupDesc_II; /* -5271 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrProposal; /* -5272 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrEncrAlg; /* -5273 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrAuthMethod; /* -5274 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrHashAlg; /* -5275 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrGroupDesc; /* -5276 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrGroupType; /* -5277 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrLifeBytes; /* -5278 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrLifeSecs; /* -5279 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrPRF; /* -5280 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrPreKey; /* -5281 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrPreFormat; /* -5282 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrCA; /* -5283 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrOwnCerts; /* -5284 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrOwnName; /* -5285 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrOwnKey; /* -5286 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrPeerCerts; /* -5287 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrPeerAddr; /* -5288 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrPeerMask; /* -5289 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrMaxLifetimeSec; /* -5290 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrMaxLifetimeKB; /* -5291 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrMaxRetrans; /* -5292 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrNoSeparator; /* -5293 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrCRACKLAMType; /* -5294 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrUseIntAddr; /* -5295 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrUseNATProbe; /* -5296 */ + }, + SINGLE_ERROR + { + text=r_error_KSecParserErrUnknown; /* -5297 */ + } + }; + } + +RESOURCE TBUF r_error_KSecParserErrMode { buf=STRING_r_error_KSecParserErrMode; } +RESOURCE TBUF r_error_KSecParserErrNotify { buf=STRING_r_error_KSecParserErrNotify; } +RESOURCE TBUF r_error_KSecParserErrCommit { buf=STRING_r_error_KSecParserErrCommit; } +RESOURCE TBUF r_error_KSecParserErrIpsecExpire { buf=STRING_r_error_KSecParserErrIpsecExpire; } +RESOURCE TBUF r_error_KSecParserErrSendCert { buf=STRING_r_error_KSecParserErrSendCert; } +RESOURCE TBUF r_error_KSecParserErrInitialContact { buf=STRING_r_error_KSecParserErrInitialContact; } +RESOURCE TBUF r_error_KSecParserErrResponderLifetime { buf=STRING_r_error_KSecParserErrResponderLifetime; } +RESOURCE TBUF r_error_KSecParserErrReplayStatus { buf=STRING_r_error_KSecParserErrReplayStatus; } +RESOURCE TBUF r_error_KSecParserErrGroupDesc_II { buf=STRING_r_error_KSecParserErrGroupDesc_II; } +RESOURCE TBUF r_error_KSecParserErrProposal { buf=STRING_r_error_KSecParserErrProposal; } +RESOURCE TBUF r_error_KSecParserErrEncrAlg { buf=STRING_r_error_KSecParserErrEncrAlg; } +RESOURCE TBUF r_error_KSecParserErrAuthMethod { buf=STRING_r_error_KSecParserErrAuthMethod; } +RESOURCE TBUF r_error_KSecParserErrHashAlg { buf=STRING_r_error_KSecParserErrHashAlg; } +RESOURCE TBUF r_error_KSecParserErrGroupDesc { buf=STRING_r_error_KSecParserErrGroupDesc; } +RESOURCE TBUF r_error_KSecParserErrGroupType { buf=STRING_r_error_KSecParserErrGroupType; } +RESOURCE TBUF r_error_KSecParserErrLifeBytes { buf=STRING_r_error_KSecParserErrLifeBytes; } +RESOURCE TBUF r_error_KSecParserErrLifeSecs { buf=STRING_r_error_KSecParserErrLifeSecs; } +RESOURCE TBUF r_error_KSecParserErrPRF { buf=STRING_r_error_KSecParserErrPRF; } +RESOURCE TBUF r_error_KSecParserErrPreKey { buf=STRING_r_error_KSecParserErrPreKey; } +RESOURCE TBUF r_error_KSecParserErrPreFormat { buf=STRING_r_error_KSecParserErrPreFormat; } +RESOURCE TBUF r_error_KSecParserErrCA { buf=STRING_r_error_KSecParserErrCA; } +RESOURCE TBUF r_error_KSecParserErrOwnCerts { buf=STRING_r_error_KSecParserErrOwnCerts; } +RESOURCE TBUF r_error_KSecParserErrOwnName { buf=STRING_r_error_KSecParserErrOwnName; } +RESOURCE TBUF r_error_KSecParserErrOwnKey { buf=STRING_r_error_KSecParserErrOwnKey; } +RESOURCE TBUF r_error_KSecParserErrPeerCerts { buf=STRING_r_error_KSecParserErrPeerCerts; } +RESOURCE TBUF r_error_KSecParserErrPeerAddr { buf=STRING_r_error_KSecParserErrPeerAddr; } +RESOURCE TBUF r_error_KSecParserErrPeerMask { buf=STRING_r_error_KSecParserErrPeerMask; } +RESOURCE TBUF r_error_KSecParserErrMaxLifetimeSec { buf=STRING_r_error_KSecParserErrMaxLifetimeSec; } +RESOURCE TBUF r_error_KSecParserErrMaxLifetimeKB { buf=STRING_r_error_KSecParserErrMaxLifetimeKB; } +RESOURCE TBUF r_error_KSecParserErrMaxRetrans { buf=STRING_r_error_KSecParserErrMaxRetrans; } +RESOURCE TBUF r_error_KSecParserErrNoSeparator { buf=STRING_r_error_KSecParserErrNoSeparator; } +RESOURCE TBUF r_error_KSecParserErrCRACKLAMType { buf=STRING_r_error_KSecParserErrCRACKLAMType; } +RESOURCE TBUF r_error_KSecParserErrUseIntAddr { buf=STRING_r_error_KSecParserErrUseIntAddr; } +RESOURCE TBUF r_error_KSecParserErrUseNATProbe { buf=STRING_r_error_KSecParserErrUseNATProbe; } +RESOURCE TBUF r_error_KSecParserErrUnknown { buf=STRING_r_error_KSecParserErrUnknown; } + +RESOURCE ARRAY r_error_array_vpnapi_errors_2 + { + items= + { + SINGLE_ERROR + { + text=r_error_KVpnErrPolicySizeChanged; /* -5298 */ + } + }; + } + +RESOURCE TBUF r_error_KVpnErrPolicySizeChanged { buf=STRING_r_error_KVpnErrPolicySizeChanged; } diff -r 000000000000 -r 33413c0669b9 vpnapiimpl/data/vpnerr.rls --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnapiimpl/data/vpnerr.rls Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,117 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Resource definitions for VPN API. +* +*/ + +// IPSec Policy API errors + +rls_string STRING_r_error_EOpenSocketError "IPSec policy loading failed (socket open failed)" +rls_string STRING_r_error_EBindSocketError "IPSec policy loading failed (socket bind failed)" +rls_string STRING_r_error_EOpenAlgorithmsFileError "IPSec policy loading failed (algorithms configuration file not found)" +rls_string STRING_r_error_ESecpolSocketSetOptError "IPSec policy loading failed (socket options could not be set)" +rls_string STRING_r_error_EUnknownPolicyHandle "Unknown IPSec policy handle" +rls_string STRING_r_error_EParsingError "IPSec policy loading failed (invalid policy)" +rls_string STRING_r_error_EWriteSocketError "IPSec policy loading failed (socket write failed)" +rls_string STRING_r_error_ESecpolReaderError "IPSec event logging failed (socket error)" +rls_string STRING_r_error_ENoSelectorFound "No matching IPSec policy selector found" +rls_string STRING_r_error_ENoMemory "IPSec policy handling failed (no memory)" +rls_string STRING_r_error_EInboundOutboundConflict "IPSec policy loading failed (conflicting policy already active)" +rls_string STRING_r_error_ESelectorConflict "IPSec policy loading failed (conflicting policy already active)" +rls_string STRING_r_error_ENoConflictInfoFound "IPSec policy conflict information not found" + +// VPN API errors + +rls_string STRING_r_error_KVpnErrNoPolicyFile "VPN policy file not found" +rls_string STRING_r_error_KVpnErrNoPolicyInfoFile "VPN policy information file not found" +rls_string STRING_r_error_KVpnErrInvalidPolicyFile "Invalid VPN policy file" +rls_string STRING_r_error_KVpnErrPolicyNotFound "VPN policy not found" +rls_string STRING_r_error_KVpnErrInvalidCaCertFile "VPN CA certificate file not found or file is corrupted" +rls_string STRING_r_error_KVpnErrPeerCertFileMissing "VPN gateway certificate file not found" +rls_string STRING_r_error_KVpnErrInvalidUserCertFile "VPN user certificate file not found or file is corrupted" +rls_string STRING_r_error_KVpnErrInvalidUserPrivKeyFile "VPN user private key file not found, file is corrupted or wrong password used" +rls_string STRING_r_error_KVpnErrImportOngoing "VPN policy import already in progress" +rls_string STRING_r_error_KVpnErrPwdChangeOngoing "Password change already in progress" +rls_string STRING_r_error_KVpnErrPolicyCountChanged "VPN policy count has changed" + +// PKI Service API errors + +rls_string STRING_r_error_KPKIErrWrongObjectType "Wrong PKI object (key or certificate) type" +rls_string STRING_r_error_KPKIErrObjectUninitialized "PKI object (key or certificate) uninitialized" +rls_string STRING_r_error_KPKIErrPassword "PKI key store password error" +rls_string STRING_r_error_KPKIErrServiceBusy "PKI service is busy" +rls_string STRING_r_error_KPKIErrCancel "PKI service request cancelled" +rls_string STRING_r_error_KPKIErrBufferTooShort "Not enough space reserved for a PKI object (key or certificate)" +rls_string STRING_r_error_KPKIErrCertRequestParam "Parameter error in certificate request" +rls_string STRING_r_error_KPKIErrCertRequest "Generating certificate request failed" +rls_string STRING_r_error_KPKIErrNotFound "Key or certificate not found" +rls_string STRING_r_error_KPKIErrAmbiguous "Key or certificate selection was ambiguous" +rls_string STRING_r_error_KPKIErrNotSupported "Function not supported" +rls_string STRING_r_error_KPKIErrUnexpectedState "Unexpected state encountered" +rls_string STRING_r_error_KPKIErrKeyStoreEmpty "Logon or ChangePassword is impossible because the key store is empty" + +// IKE policy parser errors + +rls_string STRING_r_error_KSecParserErrMode "Invalid VPN policy (invalid IKE mode value)" +rls_string STRING_r_error_KSecParserErrNotify "Invalid VPN policy (invalid IKE notify value)" +rls_string STRING_r_error_KSecParserErrCommit "Invalid VPN policy (invalid IKE commit value)" +rls_string STRING_r_error_KSecParserErrIpsecExpire "Invalid VPN policy (invalid IKE expire value)" +rls_string STRING_r_error_KSecParserErrSendCert "Invalid VPN policy (invalid IKE send certificate value)" +rls_string STRING_r_error_KSecParserErrInitialContact "Invalid VPN policy (invalid IKE initial contact value)" +rls_string STRING_r_error_KSecParserErrResponderLifetime "Invalid VPN policy (invalid IKE responder lifetime value)" +rls_string STRING_r_error_KSecParserErrReplayStatus "Invalid VPN policy (invalid IKE replay status value)" +rls_string STRING_r_error_KSecParserErrGroupDesc_II "Invalid VPN policy (invalid IKE group description II value)" +rls_string STRING_r_error_KSecParserErrProposal "Invalid VPN policy (invalid IKE proposal)" +rls_string STRING_r_error_KSecParserErrEncrAlg "Invalid VPN policy (invalid IKE encryption algorithm value)" +rls_string STRING_r_error_KSecParserErrAuthMethod "Invalid VPN policy (invalid IKE authentication method value)" +rls_string STRING_r_error_KSecParserErrHashAlg "Invalid VPN policy (invalid IKE hash algorithm value)" +rls_string STRING_r_error_KSecParserErrGroupDesc "Invalid VPN policy (invalid IKE group description value)" +rls_string STRING_r_error_KSecParserErrGroupType "Invalid VPN policy (invalid IKE group type value)" +rls_string STRING_r_error_KSecParserErrLifeBytes "Invalid VPN policy (invalid IKE lifetime bytes value)" +rls_string STRING_r_error_KSecParserErrLifeSecs "Invalid VPN policy (invalid IKE lifetime seconds value)" +rls_string STRING_r_error_KSecParserErrPRF "Invalid VPN policy (invalid IKE PRF value)" +rls_string STRING_r_error_KSecParserErrPreKey "Invalid VPN policy (invalid IKE preshared key value)" +rls_string STRING_r_error_KSecParserErrPreFormat "Invalid VPN policy (invalid IKE preshared key format value)" +rls_string STRING_r_error_KSecParserErrCA "Invalid VPN policy (invalid IKE CA value)" +rls_string STRING_r_error_KSecParserErrOwnCerts "Invalid VPN policy (invalid IKE own certificate value)" +rls_string STRING_r_error_KSecParserErrOwnName "Invalid VPN policy (invalid IKE own name value)" +rls_string STRING_r_error_KSecParserErrOwnKey "Invalid VPN policy (invalid IKE own key value)" +rls_string STRING_r_error_KSecParserErrPeerCerts "Invalid VPN policy (invalid IKE peer certificate value)" +rls_string STRING_r_error_KSecParserErrPeerAddr "Invalid VPN policy (invalid IKE peer address value)" +rls_string STRING_r_error_KSecParserErrPeerMask "Invalid VPN policy (invalid IKE peer mask value)" +rls_string STRING_r_error_KSecParserErrMaxLifetimeSec "Invalid VPN policy (invalid IKE max. lifetime seconds value)" +rls_string STRING_r_error_KSecParserErrMaxLifetimeKB "Invalid VPN policy (invalid IKE max. lifetime kilobytes value)" +rls_string STRING_r_error_KSecParserErrMaxRetrans "Invalid VPN policy (invalid IKE max. retransmissions value)" +rls_string STRING_r_error_KSecParserErrNoSeparator "Invalid VPN policy (no separator)" +rls_string STRING_r_error_KSecParserErrCRACKLAMType "Invalid VPN policy (invalid IKE CRACK LAM type value)" +rls_string STRING_r_error_KSecParserErrUseIntAddr "Invalid VPN policy (invalid IKE use internal addressing value)" +rls_string STRING_r_error_KSecParserErrUseNATProbe "Invalid VPN policy (invalid IKE use NAT probe value)" +rls_string STRING_r_error_KSecParserErrUnknown "Invalid VPN policy (unknown error)" + +// KMD API errors + +rls_string STRING_r_error_KKmdTooWeakCryptoLib "Crypto library is too weak" +rls_string STRING_r_error_KKmdNoAlgorithmsFile "VPN Configuration error (Algorithms.conf cannot be found)" +rls_string STRING_r_error_KKmdIkePolicyFileErr "VPN Configuration error (Error in IKE configuration)" +rls_string STRING_r_error_KKmdIkeNegotFailed "IKE Phase 1 negotiation failed" +rls_string STRING_r_error_KKmdIkeNoResponse "IKE Phase 1 negotiation failed (no proper response from peer)" +rls_string STRING_r_error_KKmdIkeNoProposalErr "IKE Phase 1 negotiation failed (no proposal chosen by peer)" +rls_string STRING_r_error_KKmdIkeAuthFailedErr "IKE Phase 1 negotiation failed (local end authentication failed)" +rls_string STRING_r_error_KKmdIkePeerAuthFailed "IKE Phase 1 negotiation failed (peer authentication failed)" +rls_string STRING_r_error_KKmdIkeNoCertFoundErr "IKE Phase 1 negotiation failed (proper certificate not found)" +rls_string STRING_r_error_KKmdIkeNoPolicyErr "IKE Phase 1 negotiation failed (no IKE policy section found" + +// VPN API errors 2 + +rls_string STRING_r_error_KVpnErrPolicySizeChanged "VPN policy size has changed" diff -r 000000000000 -r 33413c0669b9 vpnapiimpl/data/vpnerr.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnapiimpl/data/vpnerr.rss Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,100 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Resource definitions for VPN API. +* +*/ + + +NAME VPNE + +#include +#include +#include "vpnerr.rls" + +RESOURCE RSS_SIGNATURE { } + +// The error code range reserved by Symbian for IPSec and IPSec +// VPN modules is [-5135, -5299] (165 error code values in total). +// From this range, the sub-range [-5154, -5228] is reserved to +// ipsec6. This leaves two sub-ranges, [-5135, -5153] and +// [-5229, -5299] for use by the IPSec VPN modules. +// From these two ranges, error code values are allocated +// as follows: +// +// - IPSec Policy API: [-5135, -5147] (13 values) +// - VPN API: [-5229, -5239] (11 values) +// - PKI Service API: [-5240, -5252] (13 values) +// - KMD API: [-5253, -5262] (10 values) +// - IKE Policy Parser: [-5263, -5297] (35 values) +// - VPN API 2: [-5298, -5298] (1 value) +// +// To add new error codes: +// - Add a new range to the above list (just for clarity) +// - Add a new ERROR_ARRAY definition to the below +// ERROR_SET resource with startError set to the +// beginning of the new error code range +// - Add a new ARRAY resource to the vpnerr.ra +// resource file corresponding to the new ERROR_ARRAY +// definition. In the ARRAY resource, add a single +// SINGLE_ERROR definition for each error code that your +// source code uses. +// NOTE. The error code value associated with each +// SINGLE_ERROR definition depends on the startError +// value of corresponding ERROR_ARRAY definition and +// the position of the SINGLE_ERROR definition. +// - Add the necessary TBUF resources to the vpnerr.ra +// file add the corresponding rls_string definitions +// to the vpnerr.rls file. +// - Set the error code constant values in your source code +// to be same as the implicit values of the corresponding +// SINGLE_ERROR definitions in the vpnerr.ra file. + +RESOURCE ERROR_SET r_error_set_vpn + { + errorarrays= + { + ERROR_ARRAY + { + startError=-5135; + errors=r_error_array_ipsecpolapi_errors; + }, + ERROR_ARRAY + { + startError=-5229; + errors=r_error_array_vpnapi_errors; + }, + ERROR_ARRAY + { + startError=-5240; + errors=r_error_array_pkiserviceapi_errors; + }, + ERROR_ARRAY + { + startError=-5253; + errors=r_error_array_kmdapi_errors; + }, + ERROR_ARRAY + { + startError=-5263; + errors=r_error_array_ikepolparser_errors; + }, + ERROR_ARRAY + { + startError=-5298; + errors=r_error_array_vpnapi_errors_2; + } + }; + } + +#include "vpnerr.ra" diff -r 000000000000 -r 33413c0669b9 vpnapiimpl/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnapiimpl/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file provides the information required for building the module. +* +*/ + +#include + +PRJ_MMPFILES +vpnapi.mmp diff -r 000000000000 -r 33413c0669b9 vpnapiimpl/group/vpnapi.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnapiimpl/group/vpnapi.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2000-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project vpnapi + +* +*/ + + + + +#include + + + +TARGET vpnapi.dll + +TARGETTYPE dll + +UID 0x1000008d 0x101FD285 + + + +CAPABILITY ALL -Tcb + +VENDORID VID_DEFAULT + + + +SOURCEPATH ../src + +SOURCE vpnapi.cpp + + + +SOURCEPATH ../../vpnengine/vpncommon/src + +SOURCE clistatic.cpp + + + +// The resource file containing IPSec VPN error messages, + +// generated for the system error resolver. + +SOURCEPATH ../data + +START RESOURCE vpnerr.rss + +TARGETPATH /RESOURCE/ERRORS + +LANGUAGE_IDS + +END + + + +USERINCLUDE ../inc + +USERINCLUDE ../../vpnengine/vpnmanager/inc + +USERINCLUDE ../../vpnengine/vpncommon/inc + + + +MW_LAYER_SYSTEMINCLUDE + + + +LIBRARY euser.lib + + + diff -r 000000000000 -r 33413c0669b9 vpnapiimpl/rom/vpnapi.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnapiimpl/rom/vpnapi.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Image description file for project vpnapi +* +*/ + + +#ifndef __VPNAPI_IBY__ +#define __VPNAPI_IBY__ + +data=MULTI_LINGUIFY(RSC ZRESOURCE\Errors\vpnerr ERROR_RESOURCE_DIR\vpnerr) +file=ABI_DIR\BUILD_DIR\vpnapi.dll SHARED_LIB_DIR\vpnapi.dll + +#endif // __VPNAPI_IBY__ diff -r 000000000000 -r 33413c0669b9 vpnapiimpl/src/vpnapi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnapiimpl/src/vpnapi.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,484 @@ +/* +* Copyright (c) 2003-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: The VPN API allows Symbian OS applications and servers +* to perform VPN-specific operations. +* +*/ + + +#include "vpnapi.h" +#include "vpnmanagerserverdefs.h" +#include "clistatic.h" + +EXPORT_C RVpnServ::RVpnServ() : RSessionBase() +/** + * Constructor + */ + { + } + +EXPORT_C TInt RVpnServ::Connect() +/** + * Opens a connection (session) to the VPN Manager server. + * + * @return KErrNone if the connection succeeds, a system-wide error code + * if not. + */ + { + const TInt KVpnManagerServerStackSize = 0x4000; + const TInt KVpnManagerServerInitHeapSize = 0x1000; + const TInt KVpnManagerServerMaxHeapSize = 0x1000000; + + TInt retry = 2; + + for (;;) + { + TInt r=CreateSession(KVpnManagerServer, + Version(), + KDefaultMessageSlots); + + if (r!=KErrNotFound && r!=KErrServerTerminated) + return r; + if (--retry==0) + return r; + r = Launcher::LaunchServer(KVpnManagerServer, KVpnManagerFile, + KVpnManagerUid3, KVpnManagerServerInitHeapSize, + KVpnManagerServerMaxHeapSize, KVpnManagerServerStackSize); + + if (r!=KErrNone && r!=KErrAlreadyExists) + return r; + } + } + +EXPORT_C void RVpnServ::Close() +/** + * Closes the connection (session) to the VPN Manager server. + */ + { + RSessionBase::Close(); + } + +EXPORT_C TVersion RVpnServ::Version() const +/** + * Returns the version of the server with which this client is compatible. + * + * @return The version + */ + { + return TVersion(KVpnManagerMajorVersionNumber, + KVpnManagerMinorVersionNumber, + KVpnManagerBuildVersionNumber); + } + +EXPORT_C void RVpnServ::ImportPolicy(const TDesC& aDir, TRequestStatus& aStatus) +/** + * Imports one or more VPN policies to the policy store + * maintained by the VPN Manager. + * + * The files that constitute the VPN policies are assumed + * to reside in the specified directory. For each policy, + * the files are: + *
    + *
  1. Policy file (REQUIRED)
  2. + *
  3. Policy information file (REQUIRED)
  4. + *
  5. CA certificate files (REQUIRED)
  6. + *
  7. Client/user private key and certificate files (OPTIONAL)
  8. + *
  9. Gateway (peer) certificate files
  10. + *
+ * + * The files must follow a certain naming convention and + * utilize certain file formats. The naming convention and the file + * formats are specified in a separate document. + * + * The policies in this case can refer to the CA certificates + * via a BIN type reference (i.e. a certificate file name). + * If they do, certificates with the specified names must be + * imported at the same time with the policy. + * + * The policy being imported can be marked as hidden by + * including the value of the KHiddenPolicyIndicator constant + * (defined in vpnapidefs.h) in the description section of policy + * informationation file. + * + * The return value is returned in the aStatus argument + * when the request completes. This can be one of: + * + *
    + *
  1. KErrNone The import was successful
  2. + *
  3. \ A VPN error code if the import fails for some + * identified reason
  4. + *
  5. \ A system-wide error code if an out-of-resource + * error occurred while processing the request
  6. + *
+ * + * @param aDir An absolute path to a directory that contains the + * files that constitute the VPN policy. NOTE. As this method is + * asynchronous, this reference must point to a variable that + * remains valid until this method is complete (i.e. it cannot be + * e.g. a local variable of the calling method) + * @param aStatus [out] A reference to the standard request status + * object. On request completion, contains the return code of the request. + * + */ + { + SendReceive(EVpnImportPolicy, TIpcArgs(&aDir), aStatus); + } + +EXPORT_C void RVpnServ::CancelImport() +/** + * Cancels an ongoing policy import operation. + */ + { + SendReceive(EVpnCancelImport, TIpcArgs(NULL)); + } + +EXPORT_C TInt RVpnServ::EnumeratePolicies(TInt& aCount) +/** + * Returns the number of installed, visible VPN policies. + * Policies marked as hidden (by including the + * KHiddenPolicyIndicator in the iDescription policy details + * field) are not included in the count. + * + * @param aCount [out] The policy count + * + * @return KErrNone, if the request was processed successfully; + * \ A system-wide error code if the request + * failed for some unexpected reason. + */ + { + TPckg pckgPolicyCount(aCount); + + return SendReceive(EVpnEnumeratePolicies, TIpcArgs(&pckgPolicyCount)); + } + +EXPORT_C TInt RVpnServ::GetPolicyInfoList(CArrayFixFlat* aPolicyInfoList) +/** + * Fills the given list with information about the installed, visible + * policies. The method resizes the list according to the number of + * installed policies. Policies marked as hidden (by including the + * KHiddenPolicyIndicator in the iDescription policy details field) + * are not included in the listing. + * + * @param aPolicyInfoList A reference to a pointer to a list + * of policy information structures. + * + * @return \ A system-wide error code if the request + * failed for some unexpected reason. + */ + { + TInt ret = KErrNone; + + // Get the current policy count + TInt policyCount; + ret = EnumeratePolicies(policyCount); + if (ret != KErrNone) + { + return ret; + } + + // If there are no policies, we can stop here + if (policyCount == 0) + { + return KErrNone; + } + + // Make sure that the (client-side) policy + // info array has the correct size + TRAP(ret, aPolicyInfoList->ResizeL(policyCount)); + if (ret != KErrNone) + { + return ret; + } + + // Create a writable descriptor in this thread's address space + // where the server will write the policy information list + TPtr8 policyList((TUint8*)&aPolicyInfoList->At(0), policyCount * aPolicyInfoList->Length()); + + return SendReceive(EVpnGetPolicyInfo, TIpcArgs(policyCount, &policyList)); + } + +EXPORT_C TInt RVpnServ::GetPolicyDetails(const TVpnPolicyId& aPolicyId, TVpnPolicyDetails& aPolicyDetails) +/** + * Returns detailed information about the specified policy. + * + * @param aPolicyId The ID of the policy to return information + * about + * @param aPolicyDetails [out] Detailed policy information + * + * @return KErrNone, if the request was processed successfully; + * KVpnErrPolicyNotFound, if the specified policy was not found; + * \ A system-wide error code if the request + * failed for some unexpected reason. + */ + { + TPckg pckgPolicyId(aPolicyId); + TPckg pckgPolicyDetails(aPolicyDetails); + + return SendReceive(EVpnGetPolicyDetails, TIpcArgs(&pckgPolicyId, &pckgPolicyDetails)); + } + +EXPORT_C TInt RVpnServ::DeletePolicy(const TVpnPolicyId& aPolicyId) +/** + * Deletes the specified policy from the VPN policy store + * maintained by the VPN Manager. + * + * NOTE. The policy is deleted even if its active. + * + * @param aPolicyId The ID of the policy to delete + * + * @return KErrNone, if the request was processed successfully; + * KVpnErrPolicyNotFound, if the policy was not found; + * \ A system-wide error code if the request + * failed for some unexpected reason. + */ + { + TPckg pckgPolicyId(aPolicyId); + + return SendReceive(EVpnDeletePolicy, TIpcArgs(&pckgPolicyId)); + } + +EXPORT_C void RVpnServ::ChangePassword(const TPckg& aPolicyId, TRequestStatus& aStatus) +/** + * Initiates a user dialogue for changing the password that is used + * to protect the private keys associated with the installed VPN + * policies. + * + * The return value is returned in the aStatus argument + * when the request completes. This can be one of: + *
    + *
  1. KErrNone, if the request was processed successfully
  2. + *
  3. \ A system-wide error code if the request + * failed for some unexpected reason
  4. + *
+ * + * + * @param aPolicyId The ID of the policy whose associated key + * protection password is to be changed (NOTE 1. this parameter has + * no effect at the moment as all private keys are protected with + * the same password. NOTE 2: As this method is asynchronous, this + * reference must point to a variable that remains valid until this + * method is complete (i.e. it cannot be e.g. a local variable of + * the calling method)) + * + * @param aStatus [out] A reference to the standard request status + * object. On request completion, contains the return code of the request. + * + */ + { + SendReceive(EVpnChangePassword, TIpcArgs(&aPolicyId), aStatus); + } + +EXPORT_C void RVpnServ::CancelChange() +/** + * Cancels an ongoing password changing operation. + */ + { + SendReceive(EVpnCancelChange, TIpcArgs(NULL)); + } + +EXPORT_C TInt RVpnServ::GetPolicyData(const TVpnPolicyId& aPolicyId, HBufC8*& aPolicyData) +/** + * Returns policy data. + */ + { + TInt ret = KErrNone; + TRAP(ret, DoGetPolicyDataL(aPolicyId, aPolicyData)); + return ret; + } + +void RVpnServ::DoGetPolicyDataL(const TVpnPolicyId& aPolicyId, HBufC8*& aPolicyData) + { + TPckg pckgPolicyId(aPolicyId); + + // First get the policy size + TInt policySize; + TPckg policySizePckg(policySize); + + User::LeaveIfError(SendReceive(EVpnGetPolicySize, TIpcArgs(&pckgPolicyId, &policySizePckg))); + + // Allocate a buffer to hold the policy data + HBufC8* policyData = HBufC8::NewL(policySize); + CleanupStack::PushL(policyData); + + TPtr8 policyDataPtr = policyData->Des(); + + // Fetch the policy data + User::LeaveIfError(SendReceive(EVpnGetPolicyData, TIpcArgs(&pckgPolicyId, &policySizePckg, &policyDataPtr))); + + aPolicyData = policyData; + + CleanupStack::Pop(); // policyData + } + +// Additions to make it easier to implement OMA DM based VPN policy management + +EXPORT_C TInt RVpnServ::AddPolicy(TVpnPolicyDetails& aPolicyDetails, const TDesC8& aPolicyData) +/** + * Adds a new VPN policy to the policy store maintained by the + * VPN Manager. + * + * The policy details in this case CAN include a (globally + * unique) policy ID for the policy. This policy ID is defined + * by the policy author according to the author's own rules. + * This is the ID that becomes also the local ID of the policy. + * In other words, a single global ID is used to identify a + * policy both inside and outside the device. + * If a policy with the specified ID already exists in the + * policy store, the method returns KErrAlreadyExists. + * If the policy ID is missing from policy details argument on + * input, a globally unique ID is automatically created for the + * policy. This ID is placed in the policy details argument on + * output. + * + * The policy details must also include a non-empty policy name. + * If a name is missing, the method returns KErrArgument. + * If the proposed policy name is already in use, a sequence number + * is added to the policy name. The new policy name is placed in + * the policy details argument on output. + * + * The policy data argument contains the policy content in the + * text format described in separate VPN policy format documentation. + * If the policy data argument is empty, the method returns the + * KErrArgument error code. The policy data does not include any + * PKI objects, as the assumption is that the PKI data associated + * with the policy is placed in the device's PKI store via some + * other mechanism and APIs. The policy in this case must refer to + * the CA certificates via some other reference type than BIN + * (file reference). BIN type references are supported only when + * policies are imported to the policy store with the ImportPolicy + * method. All supported reference types are described in the IKE + * policy format documentation. + * + * The policy being added can be marked as hidden by + * including the descriptor KHiddenPolicyIndicator in the + * iDescription field of the policy details argument. + * The policy is assumed to be visible if the iDescription + * field does not contain the KHiddenPolicyIndicator + * descriptor. + * + * @param aPolicyDetails Details (metadata) about the policy + * @param aPolicyData The policy data (content) + * + * @return KErrNone if the addition was successful; + * KErrArgument, if the policy ID is missing from policy details; + * \ A VPN error code if the addition fails for some + * identified reason; + * \ A system-wide error code if an out-of-resource + * error occurred while processing the request. + */ + { + TPckg pckgPolicyDetails(aPolicyDetails); + + return SendReceive(EVpnAddPolicy, TIpcArgs(&pckgPolicyDetails, &aPolicyData)); + } + +EXPORT_C TInt RVpnServ::UpdatePolicyDetails(TVpnPolicyDetails& aPolicyDetails) +/** + * Updates the details of the specified VPN policy. + * The ID of the policy whose details are to be + * updated is specified in the policy details + * argument. If the ID is missing, the method returns + * KErrArgument. If a policy with the specified ID + * cannot be found, the method returns KVpnErrPolicyNotFound. + * + * The policy details must include a non-empty policy name. + * If a name is missing, the method returns KErrArgument. + * If the policy details contain a new name for the policy, + * the new name is checked agains existing other policy names. + * If the name is already in use, a sequence number is added + * to the policy name. The new policy name is placed in the + * policy details argument on output. + * + * The policy being updated can be marked as hidden by + * including the descriptor KHiddenPolicyIndicator in the + * iDescription field of the policy details argument. + * The policy is assumed to be visible if the iDescription + * field does not contain the KHiddenPolicyIndicator + * descriptor. + * + * @param aPolicyDetails Detailed policy information + * + * @return KErrNone, if the update was successful; + * \ A VPN error code if the addition fails for some + * identified reason; + * \ A system-wide error code if an out-of-resource + * error occurred while processing the request. + * + */ + { + TPckg pckgPolicyDetails(aPolicyDetails); + + return SendReceive(EVpnUpdatePolicyDetails, TIpcArgs(&pckgPolicyDetails)); + } + +EXPORT_C TInt RVpnServ::UpdatePolicyDetails(const TVpnPolicyDetails& aPolicyDetails) +/** + * Updates the details of the specified VPN policy. + * The ID of the policy whose details are to be + * updated is specified in the policy details + * argument. If the ID is missing, the method returns + * KErrArgument. If a policy with the specified ID + * cannot be found, the method returns KVpnErrPolicyNotFound. + * + * The policy details must include a non-empty policy name. + * If a name is missing, the method returns KErrArgument. + * If the policy details contain a new name for the policy, + * the new name is checked agains existing other policy names. + * If the name is already in use, a sequence number is added + * to the policy name. The new policy name is placed in the + * policy details argument on output. + * + * The policy being updated can be marked as hidden by + * including the descriptor KHiddenPolicyIndicator in the + * iDescription field of the policy details argument. + * The policy is assumed to be visible if the iDescription + * field does not contain the KHiddenPolicyIndicator + * descriptor. + * + * @param aPolicyDetails Detailed policy information + * + * @return KErrNone, if the update was successful; + * \ A VPN error code if the addition fails for some + * identified reason; + * \ A system-wide error code if an out-of-resource + * error occurred while processing the request. + */ + { + TPckg pckgPolicyDetails(aPolicyDetails); + + return SendReceive(EVpnUpdatePolicyDetails, TIpcArgs(&pckgPolicyDetails)); + } + + +EXPORT_C TInt RVpnServ::UpdatePolicyData(const TVpnPolicyId& aPolicyId, const TDesC8& aPolicyData) +/** + * Updates the data of the specified VPN policy. If a policy with the + * specified ID cannot be found, the method returns the + * KVpnErrPolicyNotFound error code. If the policy ID or data argument + * is empty, the method returns the KErrArgument error code. + * + * @param aPolicyId The ID of the policy to update + * @param aPolicyData The policy data + * + * @return KErrNone, if the update was successful; + * \ A VPN error code if the update fails for some + * identified reason; + * \ A system-wide error code if an out-of-resource + * error occurred while processing the request. + */ + { + TPckg pckgPolicyId(aPolicyId); + + return SendReceive(EVpnUpdatePolicyData, TIpcArgs(&pckgPolicyId, &aPolicyData)); + } diff -r 000000000000 -r 33413c0669b9 vpnc_plat/vpnapi/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnc_plat/vpnapi/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Build information file for project vpnapi +* +*/ + + +#include + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + ../inc/vpnapidefs.h /epoc32/include/vpnapidefs.h + ../inc/vpnapidefs.h MW_LAYER_PLATFORM_EXPORT_PATH(vpnapidefs.h) + ../inc/vpnnotifierdefs.h MW_LAYER_PLATFORM_EXPORT_PATH(vpnnotifierdefs.h) + ../inc/vpnapi.h MW_LAYER_PLATFORM_EXPORT_PATH(vpnapi.h) diff -r 000000000000 -r 33413c0669b9 vpnc_plat/vpnapi/inc/vpnapi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnc_plat/vpnapi/inc/vpnapi.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,129 @@ +/* +* Copyright (c) 2003-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: The VPN API allows Symbian OS applications and servers +* to perform VPN-specific operations. +* +*/ + + +/** + @file + @released + @publishedPartner + + VPN API + */ + +#ifndef __VPNAPI_H__ +#define __VPNAPI_H__ + +#include +#include + +#include "vpnapidefs.h" + +/** + * @mainpage VPN API + * + * @section intro Overview + * + * The VPN API allows Symbian OS applications and servers to perform + * VPN-specific operations, especially those related to VPN policies. + * The operations include: + *
    + *
  • Importing policies
  • + *
  • Listing policies
  • + *
  • Finding out detailed information about the policies
  • + *
  • Deleting policies
  • + *
  • (*Deprecated) Changing the password that is used to protect the private keys + * associated with the policies
  • + *
+ * + * NOTE. Direct policy activation/deactivation is not possible through this API. + * This is because the use of VPNs is based on the activation/deactivation + * of VPN IAPs and policy activation/deactivation is a (hidden) part of this + * process. The activation/deactivation of VPN IAPs is similar to the + * activation/deactivation of any other IAPs and is thus performed via + * standard Symbian OS interfaces. + */ + +class RVpnServ : public RSessionBase +/** + * An API that allows client applications to manage VPN policies and + * the password that is used to protect private keys used for VPN + * authentication. + * + * The API follows the standard Symbian OS client-server + * programming patterns. + * + */ + { +public: + IMPORT_C RVpnServ(void); + + IMPORT_C TInt Connect(); + IMPORT_C void Close(); + + IMPORT_C TVersion Version() const; + + IMPORT_C void ImportPolicy(const TDesC& aDir, TRequestStatus& aStatus); + IMPORT_C void CancelImport(); + + IMPORT_C TInt EnumeratePolicies(TInt& aCount); + IMPORT_C TInt GetPolicyInfoList( + CArrayFixFlat* aPolicyInfoList); + + IMPORT_C TInt GetPolicyDetails( + const TVpnPolicyId& aPolicyId, TVpnPolicyDetails& aPolicyDetails); + + IMPORT_C TInt DeletePolicy(const TVpnPolicyId& aPolicyId); + + /** + * ChangePassword / CancelChange + * *Deprecated!! -> To Be removed + * (Completes immediately with KErrNotSupported) + * + * @since S60 3.0 + * @param aPolicyId Policy id + * @param aStatus async operation status. + */ + IMPORT_C void ChangePassword( + const TPckg& aPolicyId, TRequestStatus& aStatus); + IMPORT_C void CancelChange(); + + IMPORT_C TInt GetPolicyData( + const TVpnPolicyId& aPolicyId, HBufC8*& aPolicyData); + + // New methods to facilitate OMA DM based VPN policy management + + IMPORT_C TInt AddPolicy( + TVpnPolicyDetails& aPolicyDetails, const TDesC8& aPolicyData); + + IMPORT_C TInt UpdatePolicyDetails( + const TVpnPolicyDetails& aPolicyDetails); + + IMPORT_C TInt UpdatePolicyData( + const TVpnPolicyId& aPolicyId, const TDesC8& aPolicyData); + + IMPORT_C TInt UpdatePolicyDetails(TVpnPolicyDetails& aPolicyDetails); + +private: // implementation + void DoGetPolicyDataL( + const TVpnPolicyId& aPolicyId, HBufC8*& aPolicyData); + }; + +/** Another name for the API class */ +typedef RVpnServ RVpnApi; + +#endif // __VPNAPI_H__ diff -r 000000000000 -r 33413c0669b9 vpnc_plat/vpnapi/inc/vpnapidefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnc_plat/vpnapi/inc/vpnapidefs.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,111 @@ +/* +* Copyright (c) 2003-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: VPN API definitions. +* +*/ + + +/** + @file + @released + @publishedPartner + + VPN API definitions + */ + +#ifndef __VPNAPIDEFS_H__ +#define __VPNAPIDEFS_H__ + +// VPN API error codes +// NOTE! The error code values below MUST be kept in sync with +// the corresponding error code values defined together by +// vpnapi/data/vpnerr.rss and vpnapi/data/vpnerr.ra +const TInt KVpnErrNoPolicyFile = -5229; +const TInt KVpnErrNoPolicyInfoFile = -5230; +const TInt KVpnErrInvalidPolicyFile = -5231; +const TInt KVpnErrPolicyNotFound = -5232; +const TInt KVpnErrInvalidCaCertFile = -5233; +const TInt KVpnErrPeerCertFileMissing = -5234; +const TInt KVpnErrInvalidUserCertFile = -5235; +const TInt KVpnErrInvalidUserPrivKeyFile = -5236; +const TInt KVpnErrImportOngoing = -5237; +const TInt KVpnErrPwdChangeOngoing = -5238; +const TInt KVpnErrPolicyCountChanged = -5239; +const TInt KVpnErrPolicySizeChanged = -5239; + +// Deprecated error code definitions +const TInt KVpnErrCaCertFileMissing = -5233; +const TInt KVpnErrUserCertFileMissing = -5235; +const TInt KVpnErrUserPrivKeyFileMissing = -5236; + +// Other constants +const TInt KMaxIdLength = 50; +const TInt KMaxNameLength = 128; +const TInt KMaxVersionLength = 16; +const TInt KMaxDescriptionLength = 256; + +// Type definitions +typedef TBuf TVpnPolicyId; +typedef TBuf8 TVpnPolicyId8; + +typedef TBuf TVpnPolicyName; + +/** + * Policy usage status + */ +enum TPolicyUsageStatus + { + EUsageStatusUnknown = 1, ///< For some reason, the usage status could not be found out + EUsageStatusUnused, ///< The policy is neither assigned to any IAP nor active + EUsageStatusAssignedToIap, ///< The policy is assigned to one or more IAPs but is not currently active + EUsageStatusActive, ///< The policy is assigned to one or more IAPs and is currently active + }; + +/** + * Policy PKI status + */ +enum TPolicyPkiStatus + { + EPkiStatusUnknown = 1, ///< For some reason, the PKI status could not be found out + EPkiStatusReady, ///< The PKI information is present + EPkiStatusNoCert, ///< At least one of the required certificates is missing + EPkiStatusCertExpired, ///< At least one of the required certificates has expired + EPkiStatusCertNotValidYet, ///< At least one of the required certificates is not yet valid + }; + +/** + * A compact policy information structure + */ +struct TVpnPolicyInfo + { + TVpnPolicyId iId; ///< Policy ID + TVpnPolicyName iName; ///< Policy name + }; + +/** + * A more detailed policy information structure + */ +struct TVpnPolicyDetails : public TVpnPolicyInfo + { + TBuf iDescription; ///< A short description of the policy + TBuf iVersion; ///< The version number of the policy + TBuf iIssuerName; ///< The name of the organization or person who created the policy + TBuf iContactInfo; ///< The phone number, email address, URL or other kind of issuer contact information + TPolicyUsageStatus iUsageStatus; ///< Policy usage status + TPolicyPkiStatus iPkiStatus; ///< Policy usage status + }; + +_LIT(KHiddenPolicyIndicator, "<>"); + +#endif diff -r 000000000000 -r 33413c0669b9 vpnc_plat/vpnapi/inc/vpnnotifierdefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnc_plat/vpnapi/inc/vpnnotifierdefs.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,184 @@ +/* +* Copyright (c) 2003-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: VPN notifier definitions +* +*/ + + +#ifndef __VPNNOTIFIERDEFS_H__ +#define __VPNNOTIFIERDEFS_H__ + +/** + @file + @released + @publishedPartner + + VPN Notifier definitions +*/ +class TNoteDialog + { +public: + enum TDialogId + { + EInfo = -10, + EWarning, + EError + }; + }; + +class TVpnDialogInfo + { +public: + TVpnDialogInfo() + { + iDialogId = 0; + iNoteDialogId = 0; + } + + TVpnDialogInfo(TInt aDialogId, TInt aNoteDialogId) + { + iDialogId = aDialogId; + iNoteDialogId = aNoteDialogId; + } + + TInt DialogId() {return iDialogId;} + TInt NoteDialogId() {return iNoteDialogId;} + +private: + TInt iDialogId; + TInt iNoteDialogId; + }; + +class TVpnDialogOutput + { +public: + TVpnDialogOutput() + { + Clear(); + } + void Clear() + { + iOutBuf.SetLength(0); + iOutBuf2.SetLength(0); + iOutInt = 0; + iOutInt2 = 0; + } + +public: + TBuf<256> iOutBuf; + TBuf<64> iOutBuf2; + TInt iOutInt; + TInt iOutInt2; + }; + +// typedefs for backward compatibility +// typedef new_type old_type +typedef TVpnDialogInfo TIPSecDialogInfo; +typedef TVpnDialogOutput TIPSecDialogOutput; + + +// +// KMD notifier definitions +// +const TUid KUidKmdDialogNotifier = {0x101F513F}; + +_LIT(KKmdNotifierResource, "\\resource\\KMDNOTIFIER.RSC"); + +class TKmdDialog + { +public: + enum TDialogId + { + EUserPwd = 1, // MUST be greater than the last value in enum TNoteDialog::TDialogId + ESecurIdPin, + ESecurIdNextPin, + EChallengeResponse, + EUsername + }; + //added here for backward compatibility + enum TDialogId_OLD_STYLE + { + //EUserPwd = 1, // MUST be greater than the last value in enum TNoteDialog::TDialogId + ESecurIDPIN = 2, + ESecurIDNextPIN + }; + }; + +class TKmdNoteDialog + { +public: + enum TTextId + { + ELamTypeNotSupported = 1, + EAuthenticationFailed, + ECryptoLibraryTooWeak + }; + //added here for backward compatibility + enum TTextId_OLD_STYLE + { + ELAMTypeNotSupported = 1//, + //EAuthenticationFailed, + //ECryptoLibraryTooWeak + }; + }; + +// typedefs for backward compatibility +// typedef existing_type old_type +typedef TKmdDialog TKMDDialog; + +typedef TKmdNoteDialog TKMDNoteDialog; + +// +// PKI notifier definitions +// +_LIT(KPkiNotifierResource,"\\resource\\PKINOTIFIER.RSC"); + +const TUid KUidPkiDialogNotifier = {0x101FAE08}; + +class TPkiDialog + { +public: + enum TDialogId + { + EEnterPwd = 1, // MUST be greater than the last value in enum TNoteDialog::TDialogId (vpnnotifierdefs.h) + EChangeActivePwd, + EInstallVpnPwd, + ECurrentVpnPwd, + EChangePwd, + EDefinePwd, + EEnterImportPwd + }; + }; + +class TPkiNoteDialog + { +public: + enum TTextId + { + EWrongSecurityPwdNote = 1, + EWrongActivatePwdNote, + EActivatePwdErrorNote, + EPwdConfirmationNote, + ECryptoLibraryTooWeak, + EPwdTooShort, + EPwdEmpty + }; + }; + +// typedefs for backward compatibility +// typedef new_type old_type +typedef TPkiDialog TIPSecDialog; +typedef TPkiNoteDialog TIPSecNoteDialog; // this was only used in pkinotifier (ipsecnotifier) + +#endif // __VPNNOTIFIERDEFS_H__ diff -r 000000000000 -r 33413c0669b9 vpnc_plat/vpnapi/vpn_api.metaxml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnc_plat/vpnapi/vpn_api.metaxml Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,18 @@ + + + VPN API + API for managing VPN policies. + c++ + vpn + + + + + + + + + yes + no + + diff -r 000000000000 -r 33413c0669b9 vpnclient_sis/group/ErrRd diff -r 000000000000 -r 33413c0669b9 vpnclient_sis/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnclient_sis/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2008-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file provides the information required for building the +* VPN Client sis files. +* +* +*/ + + + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS + +PRJ_MMPFILES + gnumakefile update_versions.mk + gnumakefile vpnclient_sis.mk + +// End of File diff -r 000000000000 -r 33413c0669b9 vpnclient_sis/group/nokia_vpn_acuins_armv5.pkg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnclient_sis/group/nokia_vpn_acuins_armv5.pkg Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,36 @@ +; +; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +; All rights reserved. +; This component and the accompanying materials are made available +; under the terms of "Eclipse Public License v1.0" +; which accompanies this distribution, and is available +; at the URL "http://www.eclipse.org/legal/epl-v10.html". +; +; Initial Contributors: +; Nokia Corporation - initial contribution. +; +; Contributors: +; +; Description: Package file for project Acu Policy Installer +; + + +; LANGUAGES +; - None (English only by default) + +; INSTALLATION HEADER +#{"Nokia VPN Server Installer"},(0xA0000132),32,08,0124, TYPE=SA, RU + +; Product / platform version compatibility - S60 5.1 and 5.2 +[0x10283160],0,0,0,{"Series60ProductID"} +[0x20022e6d],0,0,0,{"Series60ProductID"} + +; List of localised vendor names - one per language. +; At least one must be provided (English [EN]). +%{"Nokia"} + +; Unique Vendor Name +:"Nokia" + +; LIST OF FILES +; No files! diff -r 000000000000 -r 33413c0669b9 vpnclient_sis/group/nokia_vpn_client_localised_armv5_udeb.pkg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnclient_sis/group/nokia_vpn_client_localised_armv5_udeb.pkg Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,763 @@ +; +; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +; All rights reserved. +; This component and the accompanying materials are made available +; under the terms of "Eclipse Public License v1.0" +; which accompanies this distribution, and is available +; at the URL "http://www.eclipse.org/legal/epl-v10.html". +; +; Initial Contributors: +; Nokia Corporation - initial contribution. +; +; Contributors: +; +; Description: Package file for project VPN Client. udeb +; + + +; LANGUAGES +; - None (English only by default) +&EN,FR,GE,SP,IT,SW,DA,NO,FI,AM,PO,TU,IC,RU,HU,DU,CS,SK,PL,SL,TC,HK,ZH,JA,TH,AR,TL,BG,HR,ET,FA,CF,EL,HE,IN,LV,LT,MS,BP,RO,SR,LS,UK,UR,VI,44,102,103 + +; INSTALLATION HEADER +; UID of acuagentcrypto +#{"Nokia VPN", + "Cl. VPN Nokia", + "Nokia VPN-Clnt.", + "Nokia VPN", + "Client Nokia VPN", + "Nokia VPN-klient", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN", + "Cli. VPN Nokia", + "Nokia VPN is.", + "Nokia VPN", + "Клиент Nokia VPN", + "Nokia VPN", + "Nokia VPN-cl.", + "Nokia VPN kl.", + "VPN Nokia", + "Klient Nokia VPN", + "Odj. NZO Nokia", + "諾基亞VPN用戶端", + "諾基亞VPN客戶端", + "诺基亚VPN客户端", + "Nokia VPN クライアント", + "Nokia VPN client", + "Nokia VPN", + "Nokia VPN client", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN klient", + "مشتري Nokia VPN", + "RPV Nokia", + "Πελάτης της Nokia VPN", + "לקוח Nokia VPN", + "Klien VPN Nokia", + "Nokia VPN", + "Nokia VPT kl.", + "Klien Nokia VPN", + "VPN Nokia", + "Client Nokia RVP", + "Nokia VPN klijent", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN client", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN"}, +(0x101F5147),32,08,0124, TYPE=SA, RU + +; Product / platform version compatibility - S60 5.1 +[0x10283160],0,0,0,{ +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID"} + +; Product / platform version compatibility - S60 5.2 +[0x20022e6d],0,0,0,{ +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID"} + +; List of localised vendor names - one per language. +%{"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia"} + +; The non-localised, globally unique vendor name (mandatory) +:"Nokia" + +; *"RDtest.key","RDtest.cer" +; *"rd-key.pem","rd.cer" + +; LIST OF FILES + +;/////////////////////////////////////////////// + +; ipsecpolparser; remove later +"\epoc32\release\armv5\udeb\vpnipsecpolparser.dll"-"!:\sys\bin\vpnipsecpolparser.dll" + +; VPN Connection Agent +"\epoc32\release\armv5\udeb\vpnconnagt.agt"-"!:\sys\bin\vpnconnagt.agt" + +; VPN Policy Parser +"\epoc32\release\armv5\udeb\ikepolparser.dll"-"!:\sys\bin\ikepolparser.dll" + +; Symmetric crypto API wrapper +"\epoc32\release\armv5\udeb\utlcrypto.dll"-"!:\sys\bin\utlcrypto.dll" + +; Key Management Daemon +"\epoc32\release\armv5\udeb\kmdserver.exe"-"!:\sys\bin\kmdserver.exe" + +; Key Management Daemon API +"\epoc32\release\armv5\udeb\kmdapi.dll"-"!:\sys\bin\kmdapi.dll" +"\epoc32\release\armv5\udeb\ikecert.dll"-"!:\sys\bin\ikecert.dll" +"\epoc32\release\armv5\udeb\ikev1lib.dll"-"!:\sys\bin\ikev1lib.dll" +"\epoc32\release\armv5\udeb\ikev2lib.dll"-"!:\sys\bin\ikev2lib.dll" + +; IKEUTILS library +"\epoc32\release\armv5\udeb\ikeutils.dll"-"!:\sys\bin\ikeutils.dll" + +; IKE socket plugin +"\epoc32\release\armv5\udeb\ikesocket.dll"-"!:\sys\bin\ikesocket.dll" + +; VPN DM +"\epoc32\release\armv5\udeb\dmadengine.dll"-"!:\sys\bin\dmadengine.dll" +"\epoc32\release\armv5\udeb\dmadipsecvpn.dll"-"!:\sys\bin\dmadipsecvpn.dll" +"\epoc32\data\z\resource\plugins\dmadipsecvpn.rsc"-"!:\resource\plugins\dmadipsecvpn.rsc" +"\epoc32\release\armv5\udeb\dmadpki.dll"-"!:\sys\bin\dmadpki.dll" +"\epoc32\data\z\resource\plugins\dmadpki.rsc"-"!:\resource\plugins\dmadpki.rsc" + + +; VPN API ( include by platform ) +;"\epoc32\release\armv5\udeb\vpnapi.dll"-"!:\sys\bin\vpnapi.dll" + +;"\epoc32\data\z\resource\errors\vpnerr.r01"-"!:\resource\Errors\vpnerr.r01" +;"\epoc32\data\z\resource\errors\vpnerr.rsc"-"!:\resource\Errors\vpnerr.rsc" + +; VPN Management UI +"\epoc32\release\armv5\udeb\vpnmanagementui.dll"-"!:\sys\bin\vpnmanagementui.dll" + +{ +"\epoc32\data\z\resource\vpnmanagementuirsc.r01" +"\epoc32\data\z\resource\vpnmanagementuirsc.r02" +"\epoc32\data\z\resource\vpnmanagementuirsc.r03" +"\epoc32\data\z\resource\vpnmanagementuirsc.r04" +"\epoc32\data\z\resource\vpnmanagementuirsc.r05" +"\epoc32\data\z\resource\vpnmanagementuirsc.r06" +"\epoc32\data\z\resource\vpnmanagementuirsc.r07" +"\epoc32\data\z\resource\vpnmanagementuirsc.r08" +"\epoc32\data\z\resource\vpnmanagementuirsc.r09" +"\epoc32\data\z\resource\vpnmanagementuirsc.r10" +"\epoc32\data\z\resource\vpnmanagementuirsc.r13" +"\epoc32\data\z\resource\vpnmanagementuirsc.r14" +"\epoc32\data\z\resource\vpnmanagementuirsc.r15" +"\epoc32\data\z\resource\vpnmanagementuirsc.r16" +"\epoc32\data\z\resource\vpnmanagementuirsc.r17" +"\epoc32\data\z\resource\vpnmanagementuirsc.r18" +"\epoc32\data\z\resource\vpnmanagementuirsc.r25" +"\epoc32\data\z\resource\vpnmanagementuirsc.r26" +"\epoc32\data\z\resource\vpnmanagementuirsc.r27" +"\epoc32\data\z\resource\vpnmanagementuirsc.r28" +"\epoc32\data\z\resource\vpnmanagementuirsc.r29" +"\epoc32\data\z\resource\vpnmanagementuirsc.r30" +"\epoc32\data\z\resource\vpnmanagementuirsc.r31" +"\epoc32\data\z\resource\vpnmanagementuirsc.r32" +"\epoc32\data\z\resource\vpnmanagementuirsc.r33" +"\epoc32\data\z\resource\vpnmanagementuirsc.r37" +"\epoc32\data\z\resource\vpnmanagementuirsc.r39" +"\epoc32\data\z\resource\vpnmanagementuirsc.r42" +"\epoc32\data\z\resource\vpnmanagementuirsc.r45" +"\epoc32\data\z\resource\vpnmanagementuirsc.r49" +"\epoc32\data\z\resource\vpnmanagementuirsc.r50" +"\epoc32\data\z\resource\vpnmanagementuirsc.r51" +"\epoc32\data\z\resource\vpnmanagementuirsc.r54" +"\epoc32\data\z\resource\vpnmanagementuirsc.r57" +"\epoc32\data\z\resource\vpnmanagementuirsc.r59" +"\epoc32\data\z\resource\vpnmanagementuirsc.r67" +"\epoc32\data\z\resource\vpnmanagementuirsc.r68" +"\epoc32\data\z\resource\vpnmanagementuirsc.r70" +"\epoc32\data\z\resource\vpnmanagementuirsc.r76" +"\epoc32\data\z\resource\vpnmanagementuirsc.r78" +"\epoc32\data\z\resource\vpnmanagementuirsc.r79" +"\epoc32\data\z\resource\vpnmanagementuirsc.r83" +"\epoc32\data\z\resource\vpnmanagementuirsc.r93" +"\epoc32\data\z\resource\vpnmanagementuirsc.r94" +"\epoc32\data\z\resource\vpnmanagementuirsc.r96" +"\epoc32\data\z\resource\vpnmanagementuirsc.r44" +"\epoc32\data\z\resource\vpnmanagementuirsc.r102" +"\epoc32\data\z\resource\vpnmanagementuirsc.r103" +}-"!:\resource\vpnmanagementuirsc.rsc" + +; icon and GS plugin registration file +"\epoc32\data\z\resource\apps\vpnmanagementui.mif"-"!:\resource\apps\vpnmanagementui.mif" +"\epoc32\data\Z\resource\plugins\vpnmanagementui.rsc"-"!:\resource\plugins\vpnmanagementui.rsc" + +; VPN help resources +; Localized help files are missing, thus use only EE +; Help resources should be already in ROM but content can be updated from SIS package +;"\epoc32\data\Z\resource\xhtml\01\0x10200EC4\index.xml"-"!:\resource\xhtml\01\0x10200EC4\index.xml" +;{ +;"\epoc32\data\z\resource\help\vpn.h01" +;"\epoc32\data\z\resource\help\vpn.h02" +;"\epoc32\data\z\resource\help\vpn.h03" +;"\epoc32\data\z\resource\help\vpn.h04" +;"\epoc32\data\z\resource\help\vpn.h05" +;"\epoc32\data\z\resource\help\vpn.h06" +;"\epoc32\data\z\resource\help\vpn.h07" +;"\epoc32\data\z\resource\help\vpn.h08" +;"\epoc32\data\z\resource\help\vpn.h09" +;"\epoc32\data\z\resource\help\vpn.h10" +;"\epoc32\data\z\resource\help\vpn.h13" +;"\epoc32\data\z\resource\help\vpn.h14" +;"\epoc32\data\z\resource\help\vpn.h15" +;"\epoc32\data\z\resource\help\vpn.h16" +;"\epoc32\data\z\resource\help\vpn.h17" +;"\epoc32\data\z\resource\help\vpn.h18" +;"\epoc32\data\z\resource\help\vpn.h25" +;"\epoc32\data\z\resource\help\vpn.h26" +;"\epoc32\data\z\resource\help\vpn.h27" +;"\epoc32\data\z\resource\help\vpn.h28" +;"\epoc32\data\z\resource\help\vpn.h29" +;"\epoc32\data\z\resource\help\vpn.h30" +;"\epoc32\data\z\resource\help\vpn.h31" +;"\epoc32\data\z\resource\help\vpn.h32" +;"\epoc32\data\z\resource\help\vpn.h33" +;"\epoc32\data\z\resource\help\vpn.h37" +;"\epoc32\data\z\resource\help\vpn.h39" +;"\epoc32\data\z\resource\help\vpn.h42" +;"\epoc32\data\z\resource\help\vpn.h45" +;"\epoc32\data\z\resource\help\vpn.h49" +;"\epoc32\data\z\resource\help\vpn.h01" +;"\epoc32\data\z\resource\help\vpn.h51" +;"\epoc32\data\z\resource\help\vpn.h54" +;"\epoc32\data\z\resource\help\vpn.h57" +;"\epoc32\data\z\resource\help\vpn.h01" +;"\epoc32\data\z\resource\help\vpn.h59" +;"\epoc32\data\z\resource\help\vpn.h67" +;"\epoc32\data\z\resource\help\vpn.h68" +;"\epoc32\data\z\resource\help\vpn.h70" +;"\epoc32\data\z\resource\help\vpn.h76" +;"\epoc32\data\z\resource\help\vpn.h78" +;"\epoc32\data\z\resource\help\vpn.h79" +;"\epoc32\data\z\resource\help\vpn.h83" +;"\epoc32\data\z\resource\help\vpn.h93" +;"\epoc32\data\z\resource\help\vpn.h01" +;"\epoc32\data\z\resource\help\vpn.h01" +;}-"!:\resource\help\vpn.hlp" + +; PKI Services Server +"\epoc32\release\armv5\udeb\pkiservice.exe"-"!:\sys\bin\pkiservice.exe" + +; PKI Services API +"\epoc32\release\armv5\udeb\pkiserviceapi.dll"-"!:\sys\bin\pkiserviceapi.dll" + +; PKCS#10 Module +"\epoc32\release\armv5\udeb\utlpkcs10.dll"-"!:\sys\bin\utlpkcs10.dll" + +; PKCS#12 Module +"\epoc32\release\armv5\udeb\utlpkcs12.dll"-"!:\sys\bin\utlpkcs12.dll" + +; Base64 Module +"\epoc32\release\armv5\udeb\utlbase64.dll"-"!:\sys\bin\utlbase64.dll" + +; Socket Interaction Thread +"\epoc32\release\armv5\udeb\eventmedsit.dll"-"!:\sys\bin\eventmedsit.dll" + +; Event Viewer +"\epoc32\release\armv5\udeb\eventviewer.dll"-"!:\sys\bin\eventviewer.dll" + +"\epoc32\data\z\resource\vpnlogmessages.rsc"-"!:\resource\vpnlogmessages.rsc" + +; Terminal control stubs (for downwards compatibility) +"\epoc32\release\armv5\udeb\vpntcwrapper.dll"-"!:\sys\bin\vpntcwrapper.dll" + +; VPN dialog manager +"\epoc32\release\armv5\udeb\vpndialogmanager.dll"-"!:\sys\bin\vpndialogmanager.dll" + +; VPN ECOM Notifier plug-in +"\epoc32\release\armv5\udeb\vpnecomnotifier.dll"-"!:\sys\bin\vpnecomnotifier.dll" + +"\epoc32\data\z\resource\plugins\vpnecomnotifier.rsc"-"!:\resource\plugins\vpnecomnotifier.rsc" + +{ +"\epoc32\data\z\resource\vpnecomnotifier.r01" +"\epoc32\data\z\resource\vpnecomnotifier.r02" +"\epoc32\data\z\resource\vpnecomnotifier.r03" +"\epoc32\data\z\resource\vpnecomnotifier.r04" +"\epoc32\data\z\resource\vpnecomnotifier.r05" +"\epoc32\data\z\resource\vpnecomnotifier.r06" +"\epoc32\data\z\resource\vpnecomnotifier.r07" +"\epoc32\data\z\resource\vpnecomnotifier.r08" +"\epoc32\data\z\resource\vpnecomnotifier.r09" +"\epoc32\data\z\resource\vpnecomnotifier.r10" +"\epoc32\data\z\resource\vpnecomnotifier.r13" +"\epoc32\data\z\resource\vpnecomnotifier.r14" +"\epoc32\data\z\resource\vpnecomnotifier.r15" +"\epoc32\data\z\resource\vpnecomnotifier.r16" +"\epoc32\data\z\resource\vpnecomnotifier.r17" +"\epoc32\data\z\resource\vpnecomnotifier.r18" +"\epoc32\data\z\resource\vpnecomnotifier.r25" +"\epoc32\data\z\resource\vpnecomnotifier.r26" +"\epoc32\data\z\resource\vpnecomnotifier.r27" +"\epoc32\data\z\resource\vpnecomnotifier.r28" +"\epoc32\data\z\resource\vpnecomnotifier.r29" +"\epoc32\data\z\resource\vpnecomnotifier.r30" +"\epoc32\data\z\resource\vpnecomnotifier.r31" +"\epoc32\data\z\resource\vpnecomnotifier.r32" +"\epoc32\data\z\resource\vpnecomnotifier.r33" +"\epoc32\data\z\resource\vpnecomnotifier.r37" +"\epoc32\data\z\resource\vpnecomnotifier.r39" +"\epoc32\data\z\resource\vpnecomnotifier.r42" +"\epoc32\data\z\resource\vpnecomnotifier.r45" +"\epoc32\data\z\resource\vpnecomnotifier.r49" +"\epoc32\data\z\resource\vpnecomnotifier.r50" +"\epoc32\data\z\resource\vpnecomnotifier.r51" +"\epoc32\data\z\resource\vpnecomnotifier.r54" +"\epoc32\data\z\resource\vpnecomnotifier.r57" +"\epoc32\data\z\resource\vpnecomnotifier.r59" +"\epoc32\data\z\resource\vpnecomnotifier.r67" +"\epoc32\data\z\resource\vpnecomnotifier.r68" +"\epoc32\data\z\resource\vpnecomnotifier.r70" +"\epoc32\data\z\resource\vpnecomnotifier.r76" +"\epoc32\data\z\resource\vpnecomnotifier.r78" +"\epoc32\data\z\resource\vpnecomnotifier.r79" +"\epoc32\data\z\resource\vpnecomnotifier.r83" +"\epoc32\data\z\resource\vpnecomnotifier.r93" +"\epoc32\data\z\resource\vpnecomnotifier.r94" +"\epoc32\data\z\resource\vpnecomnotifier.r96" +"\epoc32\data\z\resource\vpnecomnotifier.r44" +"\epoc32\data\z\resource\vpnecomnotifier.r102" +"\epoc32\data\z\resource\vpnecomnotifier.r103" +}-"!:\resource\vpnecomnotifier.rsc" + +; XML Parser +"\epoc32\release\armv5\udeb\utlxml.dll"-"!:\sys\bin\utlxml.dll" + +; During installation check languages that HW supports +; and install resources only for them. +; EN - 01 - English +IF EXISTS ("z:\resource\avkon.r01") +"\epoc32\data\z\resource\vpnecomnotifier.r01"-"!:\resource\vpnecomnotifier.r01" +"\epoc32\data\z\resource\vpnmanagementuirsc.r01"-"!:\resource\vpnmanagementui.r01" +IF NOT EXISTS ("z:\resource\xhtml\01\0x10200EC4\index.xml") +"\epoc32\data\Z\resource\xhtml\01\0x10200EC4\index.xml"-"!:\resource\xhtml\01\0x10200EC4\index.xml" +"\epoc32\data\Z\resource\xhtml\01\0x10200EC4\keywords.xml"-"!:\resource\xhtml\01\0x10200EC4\keywords.xml" +"\epoc32\data\Z\resource\xhtml\01\0x10200EC4\meta.xml"-"!:\resource\xhtml\01\0x10200EC4\meta.xml" +"\epoc32\data\Z\resource\xhtml\01\0x10200EC4\contents.zip"-"!:\resource\xhtml\01\0x10200EC4\contents.zip" +ENDIF +ENDIF +; FR - 02 - French +IF EXISTS ("z:\resource\avkon.r02") +"\epoc32\data\z\resource\vpnecomnotifier.r02"-"!:\resource\vpnecomnotifier.r02" +"\epoc32\data\z\resource\vpnmanagementuirsc.r02"-"!:\resource\vpnmanagementui.r02" +ENDIF +; GE - 03 - German +IF EXISTS ("z:\resource\avkon.r03") +"\epoc32\data\z\resource\vpnecomnotifier.r03"-"!:\resource\vpnecomnotifier.r03" +"\epoc32\data\z\resource\vpnmanagementuirsc.r03"-"!:\resource\vpnmanagementui.r03" +ENDIF +; SP - 04 - Spanish +IF EXISTS ("z:\resource\avkon.r04") +"\epoc32\data\z\resource\vpnecomnotifier.r04"-"!:\resource\vpnecomnotifier.r04" +"\epoc32\data\z\resource\vpnmanagementuirsc.r04"-"!:\resource\vpnmanagementui.r04" +ENDIF +; IT - 05 - Italian +IF EXISTS ("z:\resource\avkon.r05") +"\epoc32\data\z\resource\vpnecomnotifier.r05"-"!:\resource\vpnecomnotifier.r05" +"\epoc32\data\z\resource\vpnmanagementuirsc.r05"-"!:\resource\vpnmanagementui.r05" +ENDIF +; SW - 06 - Swedish +IF EXISTS ("z:\resource\avkon.r06") +"\epoc32\data\z\resource\vpnecomnotifier.r06"-"!:\resource\vpnecomnotifier.r06" +"\epoc32\data\z\resource\vpnmanagementuirsc.r06"-"!:\resource\vpnmanagementui.r06" +ENDIF +; DA - 07 - Danish +IF EXISTS ("z:\resource\avkon.r07") +"\epoc32\data\z\resource\vpnecomnotifier.r07"-"!:\resource\vpnecomnotifier.r07" +"\epoc32\data\z\resource\vpnmanagementuirsc.r07"-"!:\resource\vpnmanagementui.r07" +ENDIF +; NO - 08 - Norwegian +IF EXISTS ("z:\resource\avkon.r08") +"\epoc32\data\z\resource\vpnecomnotifier.r08"-"!:\resource\vpnecomnotifier.r08" +"\epoc32\data\z\resource\vpnmanagementuirsc.r08"-"!:\resource\vpnmanagementui.r08" +ENDIF +; FI - 09 - Finnish +IF EXISTS ("z:\resource\avkon.r09") +"\epoc32\data\z\resource\vpnecomnotifier.r09"-"!:\resource\vpnecomnotifier.r09" +"\epoc32\data\z\resource\vpnmanagementuirsc.r09"-"!:\resource\vpnmanagementui.r09" +ENDIF +; AM - 10 - American +IF EXISTS ("z:\resource\avkon.r10") +"\epoc32\data\z\resource\vpnecomnotifier.r10"-"!:\resource\vpnecomnotifier.r10" +"\epoc32\data\z\resource\vpnmanagementuirsc.r10"-"!:\resource\vpnmanagementui.r10" +ENDIF +; PO - 13 - Portuguese +IF EXISTS ("z:\resource\avkon.r13") +"\epoc32\data\z\resource\vpnecomnotifier.r13"-"!:\resource\vpnecomnotifier.r13" +"\epoc32\data\z\resource\vpnmanagementuirsc.r13"-"!:\resource\vpnmanagementui.r13" +ENDIF +; TU - 14 - Turkish +IF EXISTS ("z:\resource\avkon.r14") +"\epoc32\data\z\resource\vpnecomnotifier.r14"-"!:\resource\vpnecomnotifier.r14" +"\epoc32\data\z\resource\vpnmanagementuirsc.r14"-"!:\resource\vpnmanagementui.r14" +ENDIF +; IC - 15 - Icelandic +IF EXISTS ("z:\resource\avkon.r15") +"\epoc32\data\z\resource\vpnecomnotifier.r15"-"!:\resource\vpnecomnotifier.r15" +"\epoc32\data\z\resource\vpnmanagementuirsc.r15"-"!:\resource\vpnmanagementui.r15" +ENDIF +; RU - 16 - Russian +IF EXISTS ("z:\resource\avkon.r16") +"\epoc32\data\z\resource\vpnecomnotifier.r16"-"!:\resource\vpnecomnotifier.r16" +"\epoc32\data\z\resource\vpnmanagementuirsc.r16"-"!:\resource\vpnmanagementui.r16" +ENDIF +; HU - 17 - Hungarian +IF EXISTS ("z:\resource\avkon.r17") +"\epoc32\data\z\resource\vpnecomnotifier.r17"-"!:\resource\vpnecomnotifier.r17" +"\epoc32\data\z\resource\vpnmanagementuirsc.r17"-"!:\resource\vpnmanagementui.r17" +ENDIF +; DU - 18 - Dutch +IF EXISTS ("z:\resource\avkon.r18") +"\epoc32\data\z\resource\vpnecomnotifier.r18"-"!:\resource\vpnecomnotifier.r18" +"\epoc32\data\z\resource\vpnmanagementuirsc.r18"-"!:\resource\vpnmanagementui.r18" +ENDIF +; CS - 25 - Czech +IF EXISTS ("z:\resource\avkon.r25") +"\epoc32\data\z\resource\vpnecomnotifier.r25"-"!:\resource\vpnecomnotifier.r25" +"\epoc32\data\z\resource\vpnmanagementuirsc.r25"-"!:\resource\vpnmanagementui.r25" +ENDIF +; SK - 26 - Slovak +IF EXISTS ("z:\resource\avkon.r26") +"\epoc32\data\z\resource\vpnecomnotifier.r26"-"!:\resource\vpnecomnotifier.r26" +"\epoc32\data\z\resource\vpnmanagementuirsc.r26"-"!:\resource\vpnmanagementui.r26" +ENDIF +; PL - 27 - Polish +IF EXISTS ("z:\resource\avkon.r27") +"\epoc32\data\z\resource\vpnecomnotifier.r27"-"!:\resource\vpnecomnotifier.r27" +"\epoc32\data\z\resource\vpnmanagementuirsc.r27"-"!:\resource\vpnmanagementui.r27" +ENDIF +; SL - 28 - Slovenian +IF EXISTS ("z:\resource\avkon.r28") +"\epoc32\data\z\resource\vpnecomnotifier.r28"-"!:\resource\vpnecomnotifier.r28" +"\epoc32\data\z\resource\vpnmanagementuirsc.r28"-"!:\resource\vpnmanagementui.r28" +ENDIF +; TC - 29 - TaiwanChinese +IF EXISTS ("z:\resource\avkon.r29") +"\epoc32\data\z\resource\vpnecomnotifier.r29"-"!:\resource\vpnecomnotifier.r29" +"\epoc32\data\z\resource\vpnmanagementuirsc.r29"-"!:\resource\vpnmanagementui.r29" +ENDIF +; HK - 30 - HongKongChinese +IF EXISTS ("z:\resource\avkon.r30") +"\epoc32\data\z\resource\vpnecomnotifier.r30"-"!:\resource\vpnecomnotifier.r30" +"\epoc32\data\z\resource\vpnmanagementuirsc.r30"-"!:\resource\vpnmanagementui.r30" +ENDIF +; ZH - 31 - PrcChinese +IF EXISTS ("z:\resource\avkon.r31") +"\epoc32\data\z\resource\vpnecomnotifier.r31"-"!:\resource\vpnecomnotifier.r31" +"\epoc32\data\z\resource\vpnmanagementuirsc.r31"-"!:\resource\vpnmanagementui.r31" +ENDIF +; JA - 32 - Japanese +IF EXISTS ("z:\resource\avkon.r32") +"\epoc32\data\z\resource\vpnecomnotifier.r32"-"!:\resource\vpnecomnotifier.r32" +"\epoc32\data\z\resource\vpnmanagementuirsc.r32"-"!:\resource\vpnmanagementui.r32" +ENDIF +; TH - 33 - Thai +IF EXISTS ("z:\resource\avkon.r33") +"\epoc32\data\z\resource\vpnecomnotifier.r33"-"!:\resource\vpnecomnotifier.r33" +"\epoc32\data\z\resource\vpnmanagementuirsc.r33"-"!:\resource\vpnmanagementui.r33" +ENDIF +; AR - 37 - Arabic +IF EXISTS ("z:\resource\avkon.r37") +"\epoc32\data\z\resource\vpnecomnotifier.r37"-"!:\resource\vpnecomnotifier.r37" +"\epoc32\data\z\resource\vpnmanagementuirsc.r37"-"!:\resource\vpnmanagementui.r37" +ENDIF +; TL - 39 - Tagalog +IF EXISTS ("z:\resource\avkon.r39") +"\epoc32\data\z\resource\vpnecomnotifier.r39"-"!:\resource\vpnecomnotifier.r39" +"\epoc32\data\z\resource\vpnmanagementuirsc.r39"-"!:\resource\vpnmanagementui.r39" +ENDIF +; BG - 42 - Bulgarian +IF EXISTS ("z:\resource\avkon.r42") +"\epoc32\data\z\resource\vpnecomnotifier.r42"-"!:\resource\vpnecomnotifier.r42" +"\epoc32\data\z\resource\vpnmanagementuirsc.r42"-"!:\resource\vpnmanagementui.r42" +ENDIF +; HR - 45 - Croatian +IF EXISTS ("z:\resource\avkon.r45") +"\epoc32\data\z\resource\vpnecomnotifier.r45"-"!:\resource\vpnecomnotifier.r45" +"\epoc32\data\z\resource\vpnmanagementuirsc.r45"-"!:\resource\vpnmanagementui.r45" +ENDIF +; ET - 49 - Estonian +IF EXISTS ("z:\resource\avkon.r49") +"\epoc32\data\z\resource\vpnecomnotifier.r49"-"!:\resource\vpnecomnotifier.r49" +"\epoc32\data\z\resource\vpnmanagementuirsc.r49"-"!:\resource\vpnmanagementui.r49" +ENDIF +; FA - 50 - Farsi +IF EXISTS ("z:\resource\avkon.r50") +"\epoc32\data\z\resource\vpnecomnotifier.r50"-"!:\resource\vpnecomnotifier.r50" +"\epoc32\data\z\resource\vpnmanagementuirsc.r50"-"!:\resource\vpnmanagementui.r50" +ENDIF +; CF - 51 - CanadianFrench +IF EXISTS ("z:\resource\avkon.r51") +"\epoc32\data\z\resource\vpnecomnotifier.r51"-"!:\resource\vpnecomnotifier.r51" +"\epoc32\data\z\resource\vpnmanagementuirsc.r51"-"!:\resource\vpnmanagementui.r51" +ENDIF +; EL - 54 - Greek +IF EXISTS ("z:\resource\avkon.r54") +"\epoc32\data\z\resource\vpnecomnotifier.r54"-"!:\resource\vpnecomnotifier.r54" +"\epoc32\data\z\resource\vpnmanagementuirsc.r54"-"!:\resource\vpnmanagementui.r54" +ENDIF +; HE - 57 - Hebrew +IF EXISTS ("z:\resource\avkon.r57") +"\epoc32\data\z\resource\vpnecomnotifier.r57"-"!:\resource\vpnecomnotifier.r57" +"\epoc32\data\z\resource\vpnmanagementuirsc.r57"-"!:\resource\vpnmanagementui.r57" +ENDIF +; IN - 59 - Indonesian +IF EXISTS ("z:\resource\avkon.r59") +"\epoc32\data\z\resource\vpnecomnotifier.r59"-"!:\resource\vpnecomnotifier.r59" +"\epoc32\data\z\resource\vpnmanagementuirsc.r59"-"!:\resource\vpnmanagementui.r59" +ENDIF +; LV - 67 - Latvian +IF EXISTS ("z:\resource\avkon.r67") +"\epoc32\data\z\resource\vpnecomnotifier.r67"-"!:\resource\vpnecomnotifier.r67" +"\epoc32\data\z\resource\vpnmanagementuirsc.r67"-"!:\resource\vpnmanagementui.r67" +ENDIF +; LT - 68 - Lithuanian +IF EXISTS ("z:\resource\avkon.r68") +"\epoc32\data\z\resource\vpnecomnotifier.r68"-"!:\resource\vpnecomnotifier.r68" +"\epoc32\data\z\resource\vpnmanagementuirsc.r68"-"!:\resource\vpnmanagementui.r68" +ENDIF +; MS - 70 - Malay +IF EXISTS ("z:\resource\avkon.r70") +"\epoc32\data\z\resource\vpnecomnotifier.r70"-"!:\resource\vpnecomnotifier.r70" +"\epoc32\data\z\resource\vpnmanagementuirsc.r70"-"!:\resource\vpnmanagementui.r70" +ENDIF +; BP - 76 - BrazilianPortuguese +IF EXISTS ("z:\resource\avkon.r76") +"\epoc32\data\z\resource\vpnecomnotifier.r76"-"!:\resource\vpnecomnotifier.r76" +"\epoc32\data\z\resource\vpnmanagementuirsc.r76"-"!:\resource\vpnmanagementui.r76" +ENDIF +; RO - 78 - Romanian +IF EXISTS ("z:\resource\avkon.r78") +"\epoc32\data\z\resource\vpnecomnotifier.r78"-"!:\resource\vpnecomnotifier.r78" +"\epoc32\data\z\resource\vpnmanagementuirsc.r78"-"!:\resource\vpnmanagementui.r78" +ENDIF +; SR - 79 - Serbian +IF EXISTS ("z:\resource\avkon.r79") +"\epoc32\data\z\resource\vpnecomnotifier.r79"-"!:\resource\vpnecomnotifier.r79" +"\epoc32\data\z\resource\vpnmanagementuirsc.r79"-"!:\resource\vpnmanagementui.r79" +ENDIF +; LS - 83 - LatinAmericanSpanish +IF EXISTS ("z:\resource\avkon.r83") +"\epoc32\data\z\resource\vpnecomnotifier.r83"-"!:\resource\vpnecomnotifier.r83" +"\epoc32\data\z\resource\vpnmanagementuirsc.r83"-"!:\resource\vpnmanagementui.r83" +ENDIF +; UK - 93 - Ukrainian +IF EXISTS ("z:\resource\avkon.r93") +"\epoc32\data\z\resource\vpnecomnotifier.r93"-"!:\resource\vpnecomnotifier.r93" +"\epoc32\data\z\resource\vpnmanagementuirsc.r93"-"!:\resource\vpnmanagementui.r93" +ENDIF +; UR - 94 - Urdu +IF EXISTS ("z:\resource\avkon.r94") +"\epoc32\data\z\resource\vpnecomnotifier.r94"-"!:\resource\vpnecomnotifier.r94" +"\epoc32\data\z\resource\vpnmanagementuirsc.r94"-"!:\resource\vpnmanagementui.r94" +ENDIF +; VI - 96 - Vietnamese +IF EXISTS ("z:\resource\avkon.r96") +"\epoc32\data\z\resource\vpnecomnotifier.r96"-"!:\resource\vpnecomnotifier.r96" +"\epoc32\data\z\resource\vpnmanagementuirsc.r96"-"!:\resource\vpnmanagementui.r96" +ENDIF +; - 44 - Catalan +IF EXISTS ("z:\resource\avkon.r44") +"\epoc32\data\z\resource\vpnecomnotifier.r44"-"!:\resource\vpnecomnotifier.r44" +"\epoc32\data\z\resource\vpnmanagementuirsc.r44"-"!:\resource\vpnmanagementui.r44" +ENDIF +; - 102 - Basque +IF EXISTS ("z:\resource\avkon.r102") +"\epoc32\data\z\resource\vpnecomnotifier.r102"-"!:\resource\vpnecomnotifier.r102" +"\epoc32\data\z\resource\vpnmanagementuirsc.r102"-"!:\resource\vpnmanagementui.r102" +; Helps do not support language id 102 yet +;IF NOT EXISTS ("z:\resource\xhtml\102\0x10200EC4\index.xml") +;"\epoc32\data\Z\resource\xhtml\102\0x10200EC4\index.xml"-"!:\resource\xhtml\102\0x10200EC4\index.xml" +;"\epoc32\data\Z\resource\xhtml\102\0x10200EC4\keywords.xml"-"!:\resource\xhtml\102\0x10200EC4\keywords.xml" +;"\epoc32\data\Z\resource\xhtml\102\0x10200EC4\meta.xml"-"!:\resource\xhtml\102\0x10200EC4\meta.xml" +;"\epoc32\data\Z\resource\xhtml\102\0x10200EC4\contents.zip"-"!:\resource\xhtml\102\0x10200EC4\contents.zip" +;ENDIF +ENDIF +; - 103 - Galicia +IF EXISTS ("z:\resource\avkon.r103") +"\epoc32\data\z\resource\vpnecomnotifier.r103"-"!:\resource\vpnecomnotifier.r103" +"\epoc32\data\z\resource\vpnmanagementuirsc.r103"-"!:\resource\vpnmanagementui.r103" +; Helps do not support language 103 yet +;IF NOT EXISTS ("z:\resource\xhtml\103\0x10200EC4\index.xml") +;"\epoc32\data\Z\resource\xhtml\103\0x10200EC4\index.xml"-"!:\resource\xhtml\103\0x10200EC4\index.xml" +;"\epoc32\data\Z\resource\xhtml\103\0x10200EC4\keywords.xml"-"!:\resource\xhtml\103\0x10200EC4\keywords.xml" +;"\epoc32\data\Z\resource\xhtml\103\0x10200EC4\meta.xml"-"!:\resource\xhtml\103\0x10200EC4\meta.xml" +;"\epoc32\data\Z\resource\xhtml\103\0x10200EC4\contents.zip"-"!:\resource\xhtml\103\0x10200EC4\contents.zip" +;ENDIF +ENDIF + +"\epoc32\release\armv5\udeb\vpnpolicyrecognizer.dll"-"!:\sys\bin\vpnpolicyrecognizer.dll" +"\epoc32\data\z\resource\plugins\vpnpolicyrecognizer.rsc"-"!:\resource\plugins\vpnpolicyrecognizer.rsc" + +"\epoc32\release\armv5\udeb\vpnpolins.exe"-"!:\sys\bin\vpnpolins.exe" +"\epoc32\data\z\private\10003a3f\apps\vpnpolins_reg.rsc"-"!:\Private\10003a3f\import\apps\vpnpolins_reg.rsc" +; Embedded VPN Policy Installer sis file +@"mVPN_vpnpolins_armv5.sis",(0xA0000131) + +; +; VPN Cleaner +; +"\epoc32\release\armv5\udeb\vpncleaner.exe"-"!:\sys\bin\vpncleaner.exe",FR,RR,RW +; +; The following modules must not be deleted before VPN Cleaner has been run: +; VPN Manager +"\epoc32\release\armv5\udeb\vpnmanager.exe"-"!:\sys\bin\vpnmanager.exe" +; Event Mediator +"\epoc32\release\armv5\udeb\eventmed.exe"-"!:\sys\bin\eventmed.exe" +; "\epoc32\winscw\c\private\101FD288\backup_registration.xml"-"!:\Private\101FD288\backup_registration.xml" +; Event Mediator API +"\epoc32\release\armv5\udeb\eventmedapi.dll"-"!:\sys\bin\eventmedapi.dll" + +; VPN Installer +; "101f877b.txt"-"c:\Private\10202be9\persists\101f877b.txt" +"\epoc32\release\armv5\udeb\vpnins.exe"-"!:\sys\bin\vpnins.exe",FR,RI,RW diff -r 000000000000 -r 33413c0669b9 vpnclient_sis/group/nokia_vpn_client_localised_armv5_urel.pkg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnclient_sis/group/nokia_vpn_client_localised_armv5_urel.pkg Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,762 @@ +; +; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +; All rights reserved. +; This component and the accompanying materials are made available +; under the terms of "Eclipse Public License v1.0" +; which accompanies this distribution, and is available +; at the URL "http://www.eclipse.org/legal/epl-v10.html". +; +; Initial Contributors: +; Nokia Corporation - initial contribution. +; +; Contributors: +; +; Description: Package file for project VPN Client. urel +; + + +; LANGUAGES +; - None (English only by default) +&EN,FR,GE,SP,IT,SW,DA,NO,FI,AM,PO,TU,IC,RU,HU,DU,CS,SK,PL,SL,TC,HK,ZH,JA,TH,AR,TL,BG,HR,ET,FA,CF,EL,HE,IN,LV,LT,MS,BP,RO,SR,LS,UK,UR,VI,44,102,103 + +; INSTALLATION HEADER +; UID of acuagentcrypto +#{"Nokia VPN", + "Cl. VPN Nokia", + "Nokia VPN-Clnt.", + "Nokia VPN", + "Client Nokia VPN", + "Nokia VPN-klient", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN", + "Cli. VPN Nokia", + "Nokia VPN is.", + "Nokia VPN", + "Клиент Nokia VPN", + "Nokia VPN", + "Nokia VPN-cl.", + "Nokia VPN kl.", + "VPN Nokia", + "Klient Nokia VPN", + "Odj. NZO Nokia", + "諾基亞VPN用戶端", + "諾基亞VPN客戶端", + "诺基亚VPN客户端", + "Nokia VPN クライアント", + "Nokia VPN client", + "Nokia VPN", + "Nokia VPN client", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN klient", + "مشتري Nokia VPN", + "RPV Nokia", + "Πελάτης της Nokia VPN", + "לקוח Nokia VPN", + "Klien VPN Nokia", + "Nokia VPN", + "Nokia VPT kl.", + "Klien Nokia VPN", + "VPN Nokia", + "Client Nokia RVP", + "Nokia VPN klijent", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN client", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN"}, +(0x101F5147),32,08,0124, TYPE=SA, RU + +; Product / platform version compatibility - S60 5.1 +[0x10283160],0,0,0,{ +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID"} + +; Product / platform version compatibility - S60 5.2 +[0x20022e6d],0,0,0,{ +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID"} + +; List of localised vendor names - one per language. +%{"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia"} + +; The non-localised, globally unique vendor name (mandatory) +:"Nokia" + +; *"RDtest.key","RDtest.cer" +; *"rd-key.pem","rd.cer" + +; LIST OF FILES + +;/////////////////////////////////////////////// + +; ipsecpolparser; remove later +"\epoc32\release\armv5\urel\vpnipsecpolparser.dll"-"!:\sys\bin\vpnipsecpolparser.dll" + +; VPN Connection Agent +"\epoc32\release\armv5\urel\vpnconnagt.agt"-"!:\sys\bin\vpnconnagt.agt" + +; VPN Policy Parser +"\epoc32\release\armv5\urel\ikepolparser.dll"-"!:\sys\bin\ikepolparser.dll" + +; Symmetric crypto API wrapper +"\epoc32\release\armv5\urel\utlcrypto.dll"-"!:\sys\bin\utlcrypto.dll" + +; Key Management Daemon +"\epoc32\release\armv5\urel\kmdserver.exe"-"!:\sys\bin\kmdserver.exe" + +; Key Management Daemon API +"\epoc32\release\armv5\urel\kmdapi.dll"-"!:\sys\bin\kmdapi.dll" +"\epoc32\release\armv5\urel\ikecert.dll"-"!:\sys\bin\ikecert.dll" +"\epoc32\release\armv5\urel\ikev1lib.dll"-"!:\sys\bin\ikev1lib.dll" +"\epoc32\release\armv5\urel\ikev2lib.dll"-"!:\sys\bin\ikev2lib.dll" + +; IKEUTILS library +"\epoc32\release\armv5\urel\ikeutils.dll"-"!:\sys\bin\ikeutils.dll" + +; IKE socket plugin +"\epoc32\release\armv5\urel\ikesocket.dll"-"!:\sys\bin\ikesocket.dll" + +; VPN DM +"\epoc32\release\armv5\urel\dmadengine.dll"-"!:\sys\bin\dmadengine.dll" +"\epoc32\release\armv5\urel\dmadipsecvpn.dll"-"!:\sys\bin\dmadipsecvpn.dll" +"\epoc32\data\z\resource\plugins\dmadipsecvpn.rsc"-"!:\resource\plugins\dmadipsecvpn.rsc" +"\epoc32\release\armv5\urel\dmadpki.dll"-"!:\sys\bin\dmadpki.dll" +"\epoc32\data\z\resource\plugins\dmadpki.rsc"-"!:\resource\plugins\dmadpki.rsc" + + +; VPN API (comes with platform) +;"\epoc32\release\armv5\urel\vpnapi.dll"-"!:\sys\bin\vpnapi.dll" + +;"\epoc32\data\z\resource\errors\vpnerr.r01"-"!:\resource\Errors\vpnerr.r01" +;"\epoc32\data\z\resource\errors\vpnerr.rsc"-"!:\resource\Errors\vpnerr.rsc" + +; VPN Management UI +"\epoc32\release\armv5\urel\vpnmanagementui.dll"-"!:\sys\bin\vpnmanagementui.dll" + +{ +"\epoc32\data\z\resource\vpnmanagementuirsc.r01" +"\epoc32\data\z\resource\vpnmanagementuirsc.r02" +"\epoc32\data\z\resource\vpnmanagementuirsc.r03" +"\epoc32\data\z\resource\vpnmanagementuirsc.r04" +"\epoc32\data\z\resource\vpnmanagementuirsc.r05" +"\epoc32\data\z\resource\vpnmanagementuirsc.r06" +"\epoc32\data\z\resource\vpnmanagementuirsc.r07" +"\epoc32\data\z\resource\vpnmanagementuirsc.r08" +"\epoc32\data\z\resource\vpnmanagementuirsc.r09" +"\epoc32\data\z\resource\vpnmanagementuirsc.r10" +"\epoc32\data\z\resource\vpnmanagementuirsc.r13" +"\epoc32\data\z\resource\vpnmanagementuirsc.r14" +"\epoc32\data\z\resource\vpnmanagementuirsc.r15" +"\epoc32\data\z\resource\vpnmanagementuirsc.r16" +"\epoc32\data\z\resource\vpnmanagementuirsc.r17" +"\epoc32\data\z\resource\vpnmanagementuirsc.r18" +"\epoc32\data\z\resource\vpnmanagementuirsc.r25" +"\epoc32\data\z\resource\vpnmanagementuirsc.r26" +"\epoc32\data\z\resource\vpnmanagementuirsc.r27" +"\epoc32\data\z\resource\vpnmanagementuirsc.r28" +"\epoc32\data\z\resource\vpnmanagementuirsc.r29" +"\epoc32\data\z\resource\vpnmanagementuirsc.r30" +"\epoc32\data\z\resource\vpnmanagementuirsc.r31" +"\epoc32\data\z\resource\vpnmanagementuirsc.r32" +"\epoc32\data\z\resource\vpnmanagementuirsc.r33" +"\epoc32\data\z\resource\vpnmanagementuirsc.r37" +"\epoc32\data\z\resource\vpnmanagementuirsc.r39" +"\epoc32\data\z\resource\vpnmanagementuirsc.r42" +"\epoc32\data\z\resource\vpnmanagementuirsc.r45" +"\epoc32\data\z\resource\vpnmanagementuirsc.r49" +"\epoc32\data\z\resource\vpnmanagementuirsc.r50" +"\epoc32\data\z\resource\vpnmanagementuirsc.r51" +"\epoc32\data\z\resource\vpnmanagementuirsc.r54" +"\epoc32\data\z\resource\vpnmanagementuirsc.r57" +"\epoc32\data\z\resource\vpnmanagementuirsc.r59" +"\epoc32\data\z\resource\vpnmanagementuirsc.r67" +"\epoc32\data\z\resource\vpnmanagementuirsc.r68" +"\epoc32\data\z\resource\vpnmanagementuirsc.r70" +"\epoc32\data\z\resource\vpnmanagementuirsc.r76" +"\epoc32\data\z\resource\vpnmanagementuirsc.r78" +"\epoc32\data\z\resource\vpnmanagementuirsc.r79" +"\epoc32\data\z\resource\vpnmanagementuirsc.r83" +"\epoc32\data\z\resource\vpnmanagementuirsc.r93" +"\epoc32\data\z\resource\vpnmanagementuirsc.r94" +"\epoc32\data\z\resource\vpnmanagementuirsc.r96" +"\epoc32\data\z\resource\vpnmanagementuirsc.r44" +"\epoc32\data\z\resource\vpnmanagementuirsc.r102" +"\epoc32\data\z\resource\vpnmanagementuirsc.r103" +}-"!:\resource\vpnmanagementuirsc.rsc" + +; icon and GS plugin registration file +"\epoc32\data\z\resource\apps\vpnmanagementui.mif"-"!:\resource\apps\vpnmanagementui.mif" +"\epoc32\data\Z\resource\plugins\vpnmanagementui.rsc"-"!:\resource\plugins\vpnmanagementui.rsc" + +; VPN help resources (not localized yet) +; Help resources should be already in ROM but content can be updated from SIS package +;"\epoc32\data\Z\resource\xhtml\01\0x10200EC4\contents.zip"-"!:\resource\xhtml\01\0x10200EC4\contents.zip" +;"\epoc32\data\Z\resource\xhtml\01\0x10200EC4\index.xml"-"!:\resource\xhtml\01\0x10200EC4\index.xml" +;"\epoc32\data\Z\resource\xhtml\01\0x10200EC4\keywords.xml"-"!:\resource\xhtml\01\0x10200EC4\keywords.xml" +;"\epoc32\data\Z\resource\xhtml\01\0x10200EC4\meta.xml"-"!:\resource\xhtml\01\0x10200EC4\meta.xml" +;{ +;"\epoc32\data\z\resource\help\vpn.h01" +;"\epoc32\data\z\resource\help\vpn.h02" +;"\epoc32\data\z\resource\help\vpn.h03" +;"\epoc32\data\z\resource\help\vpn.h04" +;"\epoc32\data\z\resource\help\vpn.h05" +;"\epoc32\data\z\resource\help\vpn.h06" +;"\epoc32\data\z\resource\help\vpn.h07" +;"\epoc32\data\z\resource\help\vpn.h08" +;"\epoc32\data\z\resource\help\vpn.h09" +;"\epoc32\data\z\resource\help\vpn.h10" +;"\epoc32\data\z\resource\help\vpn.h13" +;"\epoc32\data\z\resource\help\vpn.h14" +;"\epoc32\data\z\resource\help\vpn.h15" +;"\epoc32\data\z\resource\help\vpn.h16" +;"\epoc32\data\z\resource\help\vpn.h17" +;"\epoc32\data\z\resource\help\vpn.h18" +;"\epoc32\data\z\resource\help\vpn.h25" +;"\epoc32\data\z\resource\help\vpn.h26" +;"\epoc32\data\z\resource\help\vpn.h27" +;"\epoc32\data\z\resource\help\vpn.h28" +;"\epoc32\data\z\resource\help\vpn.h29" +;"\epoc32\data\z\resource\help\vpn.h30" +;"\epoc32\data\z\resource\help\vpn.h31" +;"\epoc32\data\z\resource\help\vpn.h32" +;"\epoc32\data\z\resource\help\vpn.h33" +;"\epoc32\data\z\resource\help\vpn.h37" +;"\epoc32\data\z\resource\help\vpn.h39" +;"\epoc32\data\z\resource\help\vpn.h42" +;"\epoc32\data\z\resource\help\vpn.h45" +;"\epoc32\data\z\resource\help\vpn.h49" +;"\epoc32\data\z\resource\help\vpn.h01" +;"\epoc32\data\z\resource\help\vpn.h51" +;"\epoc32\data\z\resource\help\vpn.h54" +;"\epoc32\data\z\resource\help\vpn.h57" +;"\epoc32\data\z\resource\help\vpn.h01" +;"\epoc32\data\z\resource\help\vpn.h59" +;"\epoc32\data\z\resource\help\vpn.h67" +;"\epoc32\data\z\resource\help\vpn.h68" +;"\epoc32\data\z\resource\help\vpn.h70" +;"\epoc32\data\z\resource\help\vpn.h76" +;"\epoc32\data\z\resource\help\vpn.h78" +;"\epoc32\data\z\resource\help\vpn.h79" +;"\epoc32\data\z\resource\help\vpn.h83" +;"\epoc32\data\z\resource\help\vpn.h93" +;"\epoc32\data\z\resource\help\vpn.h01" +;"\epoc32\data\z\resource\help\vpn.h01" +;}-"!:\resource\help\vpn.hlp" + +; PKI Services Server +"\epoc32\release\armv5\urel\pkiservice.exe"-"!:\sys\bin\pkiservice.exe" +; PKI Services API +"\epoc32\release\armv5\urel\pkiserviceapi.dll"-"!:\sys\bin\pkiserviceapi.dll" + + +; PKCS#10 Module +"\epoc32\release\armv5\urel\utlpkcs10.dll"-"!:\sys\bin\utlpkcs10.dll" +; PKCS#12 Module +"\epoc32\release\armv5\urel\utlpkcs12.dll"-"!:\sys\bin\utlpkcs12.dll" +; Base64 Module +"\epoc32\release\armv5\urel\utlbase64.dll"-"!:\sys\bin\utlbase64.dll" +; Socket Interaction Thread +"\epoc32\release\armv5\urel\eventmedsit.dll"-"!:\sys\bin\eventmedsit.dll" +; Event Viewer +"\epoc32\release\armv5\urel\eventviewer.dll"-"!:\sys\bin\eventviewer.dll" +; +"\epoc32\data\z\resource\vpnlogmessages.rsc"-"!:\resource\vpnlogmessages.rsc" + +; Terminal control stubs (for downwards compatibility) +"\epoc32\release\armv5\urel\vpntcwrapper.dll"-"!:\sys\bin\vpntcwrapper.dll" + +; VPN dialog manager +"\epoc32\release\armv5\urel\vpndialogmanager.dll"-"!:\sys\bin\vpndialogmanager.dll" + +; VPN ECOM Notifier plug-in +"\epoc32\release\armv5\urel\vpnecomnotifier.dll"-"!:\sys\bin\vpnecomnotifier.dll" + +"\epoc32\data\z\resource\plugins\vpnecomnotifier.rsc"-"!:\resource\plugins\vpnecomnotifier.rsc" + +{ +"\epoc32\data\z\resource\vpnecomnotifier.r01" +"\epoc32\data\z\resource\vpnecomnotifier.r02" +"\epoc32\data\z\resource\vpnecomnotifier.r03" +"\epoc32\data\z\resource\vpnecomnotifier.r04" +"\epoc32\data\z\resource\vpnecomnotifier.r05" +"\epoc32\data\z\resource\vpnecomnotifier.r06" +"\epoc32\data\z\resource\vpnecomnotifier.r07" +"\epoc32\data\z\resource\vpnecomnotifier.r08" +"\epoc32\data\z\resource\vpnecomnotifier.r09" +"\epoc32\data\z\resource\vpnecomnotifier.r10" +"\epoc32\data\z\resource\vpnecomnotifier.r13" +"\epoc32\data\z\resource\vpnecomnotifier.r14" +"\epoc32\data\z\resource\vpnecomnotifier.r15" +"\epoc32\data\z\resource\vpnecomnotifier.r16" +"\epoc32\data\z\resource\vpnecomnotifier.r17" +"\epoc32\data\z\resource\vpnecomnotifier.r18" +"\epoc32\data\z\resource\vpnecomnotifier.r25" +"\epoc32\data\z\resource\vpnecomnotifier.r26" +"\epoc32\data\z\resource\vpnecomnotifier.r27" +"\epoc32\data\z\resource\vpnecomnotifier.r28" +"\epoc32\data\z\resource\vpnecomnotifier.r29" +"\epoc32\data\z\resource\vpnecomnotifier.r30" +"\epoc32\data\z\resource\vpnecomnotifier.r31" +"\epoc32\data\z\resource\vpnecomnotifier.r32" +"\epoc32\data\z\resource\vpnecomnotifier.r33" +"\epoc32\data\z\resource\vpnecomnotifier.r37" +"\epoc32\data\z\resource\vpnecomnotifier.r39" +"\epoc32\data\z\resource\vpnecomnotifier.r42" +"\epoc32\data\z\resource\vpnecomnotifier.r45" +"\epoc32\data\z\resource\vpnecomnotifier.r49" +"\epoc32\data\z\resource\vpnecomnotifier.r50" +"\epoc32\data\z\resource\vpnecomnotifier.r51" +"\epoc32\data\z\resource\vpnecomnotifier.r54" +"\epoc32\data\z\resource\vpnecomnotifier.r57" +"\epoc32\data\z\resource\vpnecomnotifier.r59" +"\epoc32\data\z\resource\vpnecomnotifier.r67" +"\epoc32\data\z\resource\vpnecomnotifier.r68" +"\epoc32\data\z\resource\vpnecomnotifier.r70" +"\epoc32\data\z\resource\vpnecomnotifier.r76" +"\epoc32\data\z\resource\vpnecomnotifier.r78" +"\epoc32\data\z\resource\vpnecomnotifier.r79" +"\epoc32\data\z\resource\vpnecomnotifier.r83" +"\epoc32\data\z\resource\vpnecomnotifier.r93" +"\epoc32\data\z\resource\vpnecomnotifier.r94" +"\epoc32\data\z\resource\vpnecomnotifier.r96" +"\epoc32\data\z\resource\vpnecomnotifier.r44" +"\epoc32\data\z\resource\vpnecomnotifier.r102" +"\epoc32\data\z\resource\vpnecomnotifier.r103" +}-"!:\resource\vpnecomnotifier.rsc" + +; XML Parser +"\epoc32\release\armv5\urel\utlxml.dll"-"!:\sys\bin\utlxml.dll" + +; Install only languages that HW supports +; EN - 01 - English +IF EXISTS ("z:\resource\avkon.r01") +"\epoc32\data\z\resource\vpnecomnotifier.r01"-"!:\resource\vpnecomnotifier.r01" +"\epoc32\data\z\resource\vpnmanagementuirsc.r01"-"!:\resource\vpnmanagementui.r01" +IF NOT EXISTS ("z:\resource\xhtml\01\0x10200EC4\index.xml") +"\epoc32\data\Z\resource\xhtml\01\0x10200EC4\index.xml"-"!:\resource\xhtml\01\0x10200EC4\index.xml" +"\epoc32\data\Z\resource\xhtml\01\0x10200EC4\keywords.xml"-"!:\resource\xhtml\01\0x10200EC4\keywords.xml" +"\epoc32\data\Z\resource\xhtml\01\0x10200EC4\meta.xml"-"!:\resource\xhtml\01\0x10200EC4\meta.xml" +"\epoc32\data\Z\resource\xhtml\01\0x10200EC4\contents.zip"-"!:\resource\xhtml\01\0x10200EC4\contents.zip" +ENDIF +ENDIF +; FR - 02 - French +IF EXISTS ("z:\resource\avkon.r02") +"\epoc32\data\z\resource\vpnecomnotifier.r02"-"!:\resource\vpnecomnotifier.r02" +"\epoc32\data\z\resource\vpnmanagementuirsc.r02"-"!:\resource\vpnmanagementui.r02" +ENDIF +; GE - 03 - German +IF EXISTS ("z:\resource\avkon.r03") +"\epoc32\data\z\resource\vpnecomnotifier.r03"-"!:\resource\vpnecomnotifier.r03" +"\epoc32\data\z\resource\vpnmanagementuirsc.r03"-"!:\resource\vpnmanagementui.r03" +ENDIF +; SP - 04 - Spanish +IF EXISTS ("z:\resource\avkon.r04") +"\epoc32\data\z\resource\vpnecomnotifier.r04"-"!:\resource\vpnecomnotifier.r04" +"\epoc32\data\z\resource\vpnmanagementuirsc.r04"-"!:\resource\vpnmanagementui.r04" +ENDIF +; IT - 05 - Italian +IF EXISTS ("z:\resource\avkon.r05") +"\epoc32\data\z\resource\vpnecomnotifier.r05"-"!:\resource\vpnecomnotifier.r05" +"\epoc32\data\z\resource\vpnmanagementuirsc.r05"-"!:\resource\vpnmanagementui.r05" +ENDIF +; SW - 06 - Swedish +IF EXISTS ("z:\resource\avkon.r06") +"\epoc32\data\z\resource\vpnecomnotifier.r06"-"!:\resource\vpnecomnotifier.r06" +"\epoc32\data\z\resource\vpnmanagementuirsc.r06"-"!:\resource\vpnmanagementui.r06" +ENDIF +; DA - 07 - Danish +IF EXISTS ("z:\resource\avkon.r07") +"\epoc32\data\z\resource\vpnecomnotifier.r07"-"!:\resource\vpnecomnotifier.r07" +"\epoc32\data\z\resource\vpnmanagementuirsc.r07"-"!:\resource\vpnmanagementui.r07" +ENDIF +; NO - 08 - Norwegian +IF EXISTS ("z:\resource\avkon.r08") +"\epoc32\data\z\resource\vpnecomnotifier.r08"-"!:\resource\vpnecomnotifier.r08" +"\epoc32\data\z\resource\vpnmanagementuirsc.r08"-"!:\resource\vpnmanagementui.r08" +ENDIF +; FI - 09 - Finnish +IF EXISTS ("z:\resource\avkon.r09") +"\epoc32\data\z\resource\vpnecomnotifier.r09"-"!:\resource\vpnecomnotifier.r09" +"\epoc32\data\z\resource\vpnmanagementuirsc.r09"-"!:\resource\vpnmanagementui.r09" +ENDIF +; AM - 10 - American +IF EXISTS ("z:\resource\avkon.r10") +"\epoc32\data\z\resource\vpnecomnotifier.r10"-"!:\resource\vpnecomnotifier.r10" +"\epoc32\data\z\resource\vpnmanagementuirsc.r10"-"!:\resource\vpnmanagementui.r10" +ENDIF +; PO - 13 - Portuguese +IF EXISTS ("z:\resource\avkon.r13") +"\epoc32\data\z\resource\vpnecomnotifier.r13"-"!:\resource\vpnecomnotifier.r13" +"\epoc32\data\z\resource\vpnmanagementuirsc.r13"-"!:\resource\vpnmanagementui.r13" +ENDIF +; TU - 14 - Turkish +IF EXISTS ("z:\resource\avkon.r14") +"\epoc32\data\z\resource\vpnecomnotifier.r14"-"!:\resource\vpnecomnotifier.r14" +"\epoc32\data\z\resource\vpnmanagementuirsc.r14"-"!:\resource\vpnmanagementui.r14" +ENDIF +; IC - 15 - Icelandic +IF EXISTS ("z:\resource\avkon.r15") +"\epoc32\data\z\resource\vpnecomnotifier.r15"-"!:\resource\vpnecomnotifier.r15" +"\epoc32\data\z\resource\vpnmanagementuirsc.r15"-"!:\resource\vpnmanagementui.r15" +ENDIF +; RU - 16 - Russian +IF EXISTS ("z:\resource\avkon.r16") +"\epoc32\data\z\resource\vpnecomnotifier.r16"-"!:\resource\vpnecomnotifier.r16" +"\epoc32\data\z\resource\vpnmanagementuirsc.r16"-"!:\resource\vpnmanagementui.r16" +ENDIF +; HU - 17 - Hungarian +IF EXISTS ("z:\resource\avkon.r17") +"\epoc32\data\z\resource\vpnecomnotifier.r17"-"!:\resource\vpnecomnotifier.r17" +"\epoc32\data\z\resource\vpnmanagementuirsc.r17"-"!:\resource\vpnmanagementui.r17" +ENDIF +; DU - 18 - Dutch +IF EXISTS ("z:\resource\avkon.r18") +"\epoc32\data\z\resource\vpnecomnotifier.r18"-"!:\resource\vpnecomnotifier.r18" +"\epoc32\data\z\resource\vpnmanagementuirsc.r18"-"!:\resource\vpnmanagementui.r18" +ENDIF +; CS - 25 - Czech +IF EXISTS ("z:\resource\avkon.r25") +"\epoc32\data\z\resource\vpnecomnotifier.r25"-"!:\resource\vpnecomnotifier.r25" +"\epoc32\data\z\resource\vpnmanagementuirsc.r25"-"!:\resource\vpnmanagementui.r25" +ENDIF +; SK - 26 - Slovak +IF EXISTS ("z:\resource\avkon.r26") +"\epoc32\data\z\resource\vpnecomnotifier.r26"-"!:\resource\vpnecomnotifier.r26" +"\epoc32\data\z\resource\vpnmanagementuirsc.r26"-"!:\resource\vpnmanagementui.r26" +ENDIF +; PL - 27 - Polish +IF EXISTS ("z:\resource\avkon.r27") +"\epoc32\data\z\resource\vpnecomnotifier.r27"-"!:\resource\vpnecomnotifier.r27" +"\epoc32\data\z\resource\vpnmanagementuirsc.r27"-"!:\resource\vpnmanagementui.r27" +ENDIF +; SL - 28 - Slovenian +IF EXISTS ("z:\resource\avkon.r28") +"\epoc32\data\z\resource\vpnecomnotifier.r28"-"!:\resource\vpnecomnotifier.r28" +"\epoc32\data\z\resource\vpnmanagementuirsc.r28"-"!:\resource\vpnmanagementui.r28" +ENDIF +; TC - 29 - TaiwanChinese +IF EXISTS ("z:\resource\avkon.r29") +"\epoc32\data\z\resource\vpnecomnotifier.r29"-"!:\resource\vpnecomnotifier.r29" +"\epoc32\data\z\resource\vpnmanagementuirsc.r29"-"!:\resource\vpnmanagementui.r29" +ENDIF +; HK - 30 - HongKongChinese +IF EXISTS ("z:\resource\avkon.r30") +"\epoc32\data\z\resource\vpnecomnotifier.r30"-"!:\resource\vpnecomnotifier.r30" +"\epoc32\data\z\resource\vpnmanagementuirsc.r30"-"!:\resource\vpnmanagementui.r30" +ENDIF +; ZH - 31 - PrcChinese +IF EXISTS ("z:\resource\avkon.r31") +"\epoc32\data\z\resource\vpnecomnotifier.r31"-"!:\resource\vpnecomnotifier.r31" +"\epoc32\data\z\resource\vpnmanagementuirsc.r31"-"!:\resource\vpnmanagementui.r31" +ENDIF +; JA - 32 - Japanese +IF EXISTS ("z:\resource\avkon.r32") +"\epoc32\data\z\resource\vpnecomnotifier.r32"-"!:\resource\vpnecomnotifier.r32" +"\epoc32\data\z\resource\vpnmanagementuirsc.r32"-"!:\resource\vpnmanagementui.r32" +ENDIF +; TH - 33 - Thai +IF EXISTS ("z:\resource\avkon.r33") +"\epoc32\data\z\resource\vpnecomnotifier.r33"-"!:\resource\vpnecomnotifier.r33" +"\epoc32\data\z\resource\vpnmanagementuirsc.r33"-"!:\resource\vpnmanagementui.r33" +ENDIF +; AR - 37 - Arabic +IF EXISTS ("z:\resource\avkon.r37") +"\epoc32\data\z\resource\vpnecomnotifier.r37"-"!:\resource\vpnecomnotifier.r37" +"\epoc32\data\z\resource\vpnmanagementuirsc.r37"-"!:\resource\vpnmanagementui.r37" +ENDIF +; TL - 39 - Tagalog +IF EXISTS ("z:\resource\avkon.r39") +"\epoc32\data\z\resource\vpnecomnotifier.r39"-"!:\resource\vpnecomnotifier.r39" +"\epoc32\data\z\resource\vpnmanagementuirsc.r39"-"!:\resource\vpnmanagementui.r39" +ENDIF +; BG - 42 - Bulgarian +IF EXISTS ("z:\resource\avkon.r42") +"\epoc32\data\z\resource\vpnecomnotifier.r42"-"!:\resource\vpnecomnotifier.r42" +"\epoc32\data\z\resource\vpnmanagementuirsc.r42"-"!:\resource\vpnmanagementui.r42" +ENDIF +; HR - 45 - Croatian +IF EXISTS ("z:\resource\avkon.r45") +"\epoc32\data\z\resource\vpnecomnotifier.r45"-"!:\resource\vpnecomnotifier.r45" +"\epoc32\data\z\resource\vpnmanagementuirsc.r45"-"!:\resource\vpnmanagementui.r45" +ENDIF +; ET - 49 - Estonian +IF EXISTS ("z:\resource\avkon.r49") +"\epoc32\data\z\resource\vpnecomnotifier.r49"-"!:\resource\vpnecomnotifier.r49" +"\epoc32\data\z\resource\vpnmanagementuirsc.r49"-"!:\resource\vpnmanagementui.r49" +ENDIF +; FA - 50 - Farsi +IF EXISTS ("z:\resource\avkon.r50") +"\epoc32\data\z\resource\vpnecomnotifier.r50"-"!:\resource\vpnecomnotifier.r50" +"\epoc32\data\z\resource\vpnmanagementuirsc.r50"-"!:\resource\vpnmanagementui.r50" +ENDIF +; CF - 51 - CanadianFrench +IF EXISTS ("z:\resource\avkon.r51") +"\epoc32\data\z\resource\vpnecomnotifier.r51"-"!:\resource\vpnecomnotifier.r51" +"\epoc32\data\z\resource\vpnmanagementuirsc.r51"-"!:\resource\vpnmanagementui.r51" +ENDIF +; EL - 54 - Greek +IF EXISTS ("z:\resource\avkon.r54") +"\epoc32\data\z\resource\vpnecomnotifier.r54"-"!:\resource\vpnecomnotifier.r54" +"\epoc32\data\z\resource\vpnmanagementuirsc.r54"-"!:\resource\vpnmanagementui.r54" +ENDIF +; HE - 57 - Hebrew +IF EXISTS ("z:\resource\avkon.r57") +"\epoc32\data\z\resource\vpnecomnotifier.r57"-"!:\resource\vpnecomnotifier.r57" +"\epoc32\data\z\resource\vpnmanagementuirsc.r57"-"!:\resource\vpnmanagementui.r57" +ENDIF +; IN - 59 - Indonesian +IF EXISTS ("z:\resource\avkon.r59") +"\epoc32\data\z\resource\vpnecomnotifier.r59"-"!:\resource\vpnecomnotifier.r59" +"\epoc32\data\z\resource\vpnmanagementuirsc.r59"-"!:\resource\vpnmanagementui.r59" +ENDIF +; LV - 67 - Latvian +IF EXISTS ("z:\resource\avkon.r67") +"\epoc32\data\z\resource\vpnecomnotifier.r67"-"!:\resource\vpnecomnotifier.r67" +"\epoc32\data\z\resource\vpnmanagementuirsc.r67"-"!:\resource\vpnmanagementui.r67" +ENDIF +; LT - 68 - Lithuanian +IF EXISTS ("z:\resource\avkon.r68") +"\epoc32\data\z\resource\vpnecomnotifier.r68"-"!:\resource\vpnecomnotifier.r68" +"\epoc32\data\z\resource\vpnmanagementuirsc.r68"-"!:\resource\vpnmanagementui.r68" +ENDIF +; MS - 70 - Malay +IF EXISTS ("z:\resource\avkon.r70") +"\epoc32\data\z\resource\vpnecomnotifier.r70"-"!:\resource\vpnecomnotifier.r70" +"\epoc32\data\z\resource\vpnmanagementuirsc.r70"-"!:\resource\vpnmanagementui.r70" +ENDIF +; BP - 76 - BrazilianPortuguese +IF EXISTS ("z:\resource\avkon.r76") +"\epoc32\data\z\resource\vpnecomnotifier.r76"-"!:\resource\vpnecomnotifier.r76" +"\epoc32\data\z\resource\vpnmanagementuirsc.r76"-"!:\resource\vpnmanagementui.r76" +ENDIF +; RO - 78 - Romanian +IF EXISTS ("z:\resource\avkon.r78") +"\epoc32\data\z\resource\vpnecomnotifier.r78"-"!:\resource\vpnecomnotifier.r78" +"\epoc32\data\z\resource\vpnmanagementuirsc.r78"-"!:\resource\vpnmanagementui.r78" +ENDIF +; SR - 79 - Serbian +IF EXISTS ("z:\resource\avkon.r79") +"\epoc32\data\z\resource\vpnecomnotifier.r79"-"!:\resource\vpnecomnotifier.r79" +"\epoc32\data\z\resource\vpnmanagementuirsc.r79"-"!:\resource\vpnmanagementui.r79" +ENDIF +; LS - 83 - LatinAmericanSpanish +IF EXISTS ("z:\resource\avkon.r83") +"\epoc32\data\z\resource\vpnecomnotifier.r83"-"!:\resource\vpnecomnotifier.r83" +"\epoc32\data\z\resource\vpnmanagementuirsc.r83"-"!:\resource\vpnmanagementui.r83" +ENDIF +; UK - 93 - Ukrainian +IF EXISTS ("z:\resource\avkon.r93") +"\epoc32\data\z\resource\vpnecomnotifier.r93"-"!:\resource\vpnecomnotifier.r93" +"\epoc32\data\z\resource\vpnmanagementuirsc.r93"-"!:\resource\vpnmanagementui.r93" +ENDIF +; UR - 94 - Urdu +IF EXISTS ("z:\resource\avkon.r94") +"\epoc32\data\z\resource\vpnecomnotifier.r94"-"!:\resource\vpnecomnotifier.r94" +"\epoc32\data\z\resource\vpnmanagementuirsc.r94"-"!:\resource\vpnmanagementui.r94" +ENDIF +; VI - 96 - Vietnamese +IF EXISTS ("z:\resource\avkon.r96") +"\epoc32\data\z\resource\vpnecomnotifier.r96"-"!:\resource\vpnecomnotifier.r96" +"\epoc32\data\z\resource\vpnmanagementuirsc.r96"-"!:\resource\vpnmanagementui.r96" +ENDIF +; - 44 - Catalan +IF EXISTS ("z:\resource\avkon.r44") +"\epoc32\data\z\resource\vpnecomnotifier.r44"-"!:\resource\vpnecomnotifier.r44" +"\epoc32\data\z\resource\vpnmanagementuirsc.r44"-"!:\resource\vpnmanagementui.r44" +ENDIF +; - 102 - Basque +IF EXISTS ("z:\resource\avkon.r102") +"\epoc32\data\z\resource\vpnecomnotifier.r102"-"!:\resource\vpnecomnotifier.r102" +"\epoc32\data\z\resource\vpnmanagementuirsc.r102"-"!:\resource\vpnmanagementui.r102" +; Helps do not support language id 102 yet +;IF NOT EXISTS ("z:\resource\xhtml\102\0x10200EC4\index.xml") +;"\epoc32\data\Z\resource\xhtml\102\0x10200EC4\index.xml"-"!:\resource\xhtml\102\0x10200EC4\index.xml" +;"\epoc32\data\Z\resource\xhtml\102\0x10200EC4\keywords.xml"-"!:\resource\xhtml\102\0x10200EC4\keywords.xml" +;"\epoc32\data\Z\resource\xhtml\102\0x10200EC4\meta.xml"-"!:\resource\xhtml\102\0x10200EC4\meta.xml" +;"\epoc32\data\Z\resource\xhtml\102\0x10200EC4\contents.zip"-"!:\resource\xhtml\102\0x10200EC4\contents.zip" +;ENDIF +ENDIF +; - 103 - Galicia +IF EXISTS ("z:\resource\avkon.r103") +"\epoc32\data\z\resource\vpnecomnotifier.r103"-"!:\resource\vpnecomnotifier.r103" +"\epoc32\data\z\resource\vpnmanagementuirsc.r103"-"!:\resource\vpnmanagementui.r103" +; Helps do not support language 103 yet +;IF NOT EXISTS ("z:\resource\xhtml\103\0x10200EC4\index.xml") +;"\epoc32\data\Z\resource\xhtml\103\0x10200EC4\index.xml"-"!:\resource\xhtml\103\0x10200EC4\index.xml" +;"\epoc32\data\Z\resource\xhtml\103\0x10200EC4\keywords.xml"-"!:\resource\xhtml\103\0x10200EC4\keywords.xml" +;"\epoc32\data\Z\resource\xhtml\103\0x10200EC4\meta.xml"-"!:\resource\xhtml\103\0x10200EC4\meta.xml" +;"\epoc32\data\Z\resource\xhtml\103\0x10200EC4\contents.zip"-"!:\resource\xhtml\103\0x10200EC4\contents.zip" +;ENDIF +ENDIF + +"\epoc32\release\armv5\urel\vpnpolicyrecognizer.dll"-"!:\sys\bin\vpnpolicyrecognizer.dll" +"\epoc32\data\z\resource\plugins\vpnpolicyrecognizer.rsc"-"!:\resource\plugins\vpnpolicyrecognizer.rsc" + + +"\epoc32\release\armv5\urel\vpnpolins.exe"-"!:\sys\bin\vpnpolins.exe" +"\epoc32\data\z\private\10003a3f\apps\vpnpolins_reg.rsc"-"!:\Private\10003a3f\import\apps\vpnpolins_reg.rsc" +; Embedded VPN Policy Installer sis file +@"mVPN_vpnpolins_armv5.sis",(0xA0000131) + +; +; VPN Cleaner +; +"\epoc32\release\armv5\urel\vpncleaner.exe"-"!:\sys\bin\vpncleaner.exe",FR,RR,RW +; +; The following modules must not be deleted before VPN Cleaner has been run: +; VPN Manager +"\epoc32\release\armv5\urel\vpnmanager.exe"-"!:\sys\bin\vpnmanager.exe" + +; Event Mediator +"\epoc32\release\armv5\urel\eventmed.exe"-"!:\sys\bin\eventmed.exe" +; "\epoc32\winscw\c\private\101FD288\backup_registration.xml"-"!:\Private\101FD288\backup_registration.xml" +; Event Mediator API +"\epoc32\release\armv5\urel\eventmedapi.dll"-"!:\sys\bin\eventmedapi.dll" + +; VPN Installer +; "101f877b.txt"-"c:\Private\10202be9\persists\101f877b.txt" +"\epoc32\release\armv5\urel\vpnins.exe"-"!:\sys\bin\vpnins.exe",FR,RI,RW diff -r 000000000000 -r 33413c0669b9 vpnclient_sis/group/nokia_vpn_vpnpolins_armv5.pkg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnclient_sis/group/nokia_vpn_vpnpolins_armv5.pkg Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,36 @@ +; +; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +; All rights reserved. +; This component and the accompanying materials are made available +; under the terms of "Eclipse Public License v1.0" +; which accompanies this distribution, and is available +; at the URL "http://www.eclipse.org/legal/epl-v10.html". +; +; Initial Contributors: +; Nokia Corporation - initial contribution. +; +; Contributors: +; +; Description: Package file for project VPNPolIns +; + + +; LANGUAGES +; - None (English only by default) + +; INSTALLATION HEADER +#{"Nokia VPN Policy Installer"},(0xA0000131),32,08,0124, TYPE=SA, RU + +; Product / platform version compatibility - S60 5.1 and 5.2 +[0x10283160],0,0,0,{"Series60ProductID"} +[0x20022e6d],0,0,0,{"Series60ProductID"} + +; List of localised vendor names - one per language. +; At least one must be provided (English [EN]). +%{"Nokia"} + +; Unique Vendor Name +:"Nokia" + +; LIST OF FILES +; No files! diff -r 000000000000 -r 33413c0669b9 vpnclient_sis/group/update_versions.mk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnclient_sis/group/update_versions.mk Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,27 @@ +# +# Copyright (c) 2008-2008 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: Calls version update script +# + +do_nothing : + @rem do_nothing + +MAKMAKE : do_nothing + +BLD : + @echo Updating versions.. + perl update_versions.pl + @echo Update done! + +FREEZE LIB CLEANLIB RESOURCE RELEASABLES CLEAN FINAL SAVESPACE : do_nothing \ No newline at end of file diff -r 000000000000 -r 33413c0669b9 vpnclient_sis/group/update_versions.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnclient_sis/group/update_versions.pl Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,120 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# Updates pkg-files' and vpnclient_sis.mk's version information with current date. +# Creates temporary pkg-files with updated version. +# + +use strict; +use POSIX qw(strftime); +use File::Copy; + + +my $PLATFORM = "42"; + +# +# Creates a temp file and replaces line +# +sub replace_line_and_create_temp +{ + # arguments + my ($pattern, $replacement, $path) = @_; + + # create temp file + my $temp_path = "temp_".$path; + if (-e $temp_path) + { + chmod 0666, $temp_path; + unlink $temp_path; + } + copy($path, $temp_path); + chmod 0666, $temp_path; + + # update version information + my ($infile, $outfile); + open $infile, "<".$path or die "Can't open $path : $!"; + open $outfile, ">".$temp_path or die "Can't open $temp_path : $!"; + while (<$infile>) + { + my $line = $_; + if ($line =~ s/$pattern/$replacement/g) + { + print "Replaced line in $temp_path\n"; + } + print $outfile $line; + } + close $infile; + close $outfile; +} + +# +# Replaces line +# +sub replace_line +{ + # arguments + my ($pattern, $replacement, $path) = @_; + + # Backup + if (-e "$path.BACKUP") + { + chmod 0666, "$path.BACKUP"; + unlink "$path.BACKUP"; + } + chmod 0666, $path; + rename $path, "$path.BACKUP"; + + # update version information + my ($infile, $outfile); + open $infile, "<$path.BACKUP" or die "Can't open $path.BACKUP : $!"; + open $outfile, ">$path" or die "Can't open $path : $!"; + while (<$infile>) + { + my $line = $_; + if ($line =~ s/$pattern/$replacement/g) + { + print "Replaced line in $path\n"; + } + print $outfile $line; + } + close $infile; + close $outfile; +} + +my $pkgtime = strftime($PLATFORM.",%y,%m%d", localtime()); +my $mktime = strftime("%y%m%d", localtime()); + +# nokia_vpn_vpnpolins_armv5.pkg +replace_line_and_create_temp( + '^#{"Nokia VPN Policy Installer"},\(0xA0000131\),.*?,.*?,.*?, TYPE=SA, RU$', + "#{\"Nokia VPN Policy Installer\"},(0xA0000131),$pkgtime, TYPE=SA, RU", + 'nokia_vpn_vpnpolins_armv5.pkg'); + +# nokia_vpn_client_localised_armv5_urel.pkg +replace_line_and_create_temp( + '^\(0x101F5147\),.*?,.*?,.*?, TYPE=SA, RU$', + "(0x101F5147),$pkgtime, TYPE=SA, RU", + 'nokia_vpn_client_localised_armv5_urel.pkg'); + +# nokia_vpn_client_localised_armv5_udeb.pkg +replace_line_and_create_temp( + '^\(0x101F5147\),.*?,.*?,.*?, TYPE=SA, RU$', + "(0x101F5147),$pkgtime, TYPE=SA, RU", + 'nokia_vpn_client_localised_armv5_udeb.pkg'); + +# vpnclient_sis.mk +replace_line( + '^VERSION=.*?$', + "VERSION=$mktime", + 'vpnclient_sis.mk'); diff -r 000000000000 -r 33413c0669b9 vpnclient_sis/group/vpnclient_sis.mk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnclient_sis/group/vpnclient_sis.mk Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,92 @@ +# +# Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: Creates either localised or nonlocalised mVPN Client SIS files +# + +# To ensure that EPOCROOT always ends with a forward slash +TMPROOT:=$(subst \,/,$(EPOCROOT)) +EPOCROOT:=$(patsubst %/,%,$(TMPROOT))/ + +VERSION=091014 +RDDERDIR=../data/RDTest_02.der +RDKEYDIR=../data/RDTest_02.key +LOCALISATION_FILES=$(EPOCROOT)epoc32/data/Z/resource/vpnecomnotifier.r05 +S60PLATFORM=v42 + +do_nothing : + @rem do_nothing + +MAKMAKE : do_nothing + +BLD : + +# +# Localisation files must exist +# + @echo -- + if exist $(LOCALISATION_FILES) @echo Building localised version + if not exist $(LOCALISATION_FILES) @echo Localisation files are not available! Exiting.. + if not exist $(LOCALISATION_FILES) @echo -- + if not exist $(LOCALISATION_FILES) exit 1 + @echo -- + +# +# vpn policy installer +# + @echo Processing temp_nokia_vpn_vpnpolins_armv5.pkg + $(EPOCROOT)epoc32\tools\makesis -v temp_nokia_vpn_vpnpolins_armv5.pkg mVPN_vpnpolins_armv5.sis + @echo Signing created mVPN_vpnpolins_armv5.sis + $(EPOCROOT)epoc32\tools\signsis mVPN_vpnpolins_armv5.sis mVPN_vpnpolins_armv5.sis $(RDDERDIR) $(RDKEYDIR) + +# +# If localisation files exist create localised SIS files. +# +# UREL + @echo Processing temp_nokia_vpn_client_localised_armv5_urel.pkg + $(EPOCROOT)epoc32\tools\makesis -v temp_nokia_vpn_client_localised_armv5_urel.pkg mVPN_RnD_$(S60PLATFORM)_$(VERSION)_urel.sis + @echo Signing created mVPN_RnD_$(S60PLATFORM)_$(VERSION)_urel.sis + $(EPOCROOT)epoc32\tools\signsis mVPN_RnD_$(S60PLATFORM)_$(VERSION)_urel.sis mVPN_RnD_$(S60PLATFORM)_$(VERSION)_urel.sis $(RDDERDIR) $(RDKEYDIR) +# UDEB + @echo Processing temp_nokia_vpn_client_localised_armv5_udeb.pkg + $(EPOCROOT)epoc32\tools\makesis -v temp_nokia_vpn_client_localised_armv5_udeb.pkg mVPN_RnD_$(S60PLATFORM)_$(VERSION)_udeb.sis + @echo Signing created mVPN_RnD_$(S60PLATFORM)_$(VERSION)_udeb.sis + $(EPOCROOT)epoc32\tools\signsis mVPN_RnD_$(S60PLATFORM)_$(VERSION)_udeb.sis mVPN_RnD_$(S60PLATFORM)_$(VERSION)_udeb.sis $(RDDERDIR) $(RDKEYDIR) + + +# remove policy installer + @echo Remove unnecessary temporary sis files + if exist mVPN_vpnpolins_armv5.sis erase mVPN_vpnpolins_armv5.sis + if exist temp_* erase temp_* + +CLEAN : + if exist mVPN_RnD_$(S60PLATFORM)_$(VERSION)_urel.sis erase mVPN_RnD_$(S60PLATFORM)_$(VERSION)_urel.sis + if exist mVPN_RnD_$(S60PLATFORM)_$(VERSION)_udeb.sis erase mVPN_RnD_$(S60PLATFORM)_$(VERSION)_udeb.sis + if exist mVPN_vpnpolins_armv5.sis erase mVPN_vpnpolins_armv5.sis + if exist temp_* erase temp_* + if exist *.BACKUP erase *.BACKUP + + +LIB : do_nothing + +CLEANLIB : do_nothing + +RESOURCE : do_nothing + +FREEZE : do_nothing + +SAVESPACE : do_nothing + +RELEASABLES : do_nothing + +FINAL : do_nothing diff -r 000000000000 -r 33413c0669b9 vpnclient_sis/stub_sis/data/101f877b.txt Binary file vpnclient_sis/stub_sis/data/101f877b.txt has changed diff -r 000000000000 -r 33413c0669b9 vpnclient_sis/stub_sis/data/101f877b.txt.vpn Binary file vpnclient_sis/stub_sis/data/101f877b.txt.vpn has changed diff -r 000000000000 -r 33413c0669b9 vpnclient_sis/stub_sis/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnclient_sis/stub_sis/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2004-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file provides the information required for building the +* VPN Client sis files. +* +* +*/ + + + +PRJ_PLATFORMS +DEFAULT + +PRJ_EXPORTS +../data/101f877b.txt.vpn /epoc32/data/z/private/10202be9/101f877b.txt.vpn +../data/101f877b.txt /epoc32/WINSCW/C/private/10202be9/persists/101f877b.txt + +PRJ_MMPFILES + + gnumakefile vpnclient_stub_sis.mk + +// End of File diff -r 000000000000 -r 33413c0669b9 vpnclient_sis/stub_sis/group/stub_nokia_vpn_client_armv5.pkg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnclient_sis/stub_sis/group/stub_nokia_vpn_client_armv5.pkg Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,358 @@ +; +; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +; All rights reserved. +; This component and the accompanying materials are made available +; under the terms of "Eclipse Public License v1.0" +; which accompanies this distribution, and is available +; at the URL "http://www.eclipse.org/legal/epl-v10.html". +; +; Initial Contributors: +; Nokia Corporation - initial contribution. +; +; Contributors: +; +; Description: +; + +; ============================================================================ +; Name : stub_nokia_vpn_client_armv5.pkg +; Part of : VPN / VPN +; Description : Nokia VPN Client G1 S60 PACKAGE for Stub-SIS +; Version : %version: % +; +; Copyright © 2006 - 2008 Nokia. All rights reserved. +; This material, including documentation and any related computer +; programs, is protected by copyright controlled by Nokia. All +; rights are reserved. Copying, including reproducing, storing, +; adapting or translating, any or all of this material requires the +; prior written consent of Nokia. This material also contains +; confidential information which may not be disclosed to others +; without the prior written consent of Nokia. +; ============================================================================ +; Template version: 4.1 + +; LANGUAGES +; - None (English only by default) +&EN,FR,GE,SP,IT,SW,DA,NO,FI,AM,PO,TU,IC,RU,HU,DU,CS,SK,PL,SL,TC,HK,ZH,JA,TH,AR,TL,BG,HR,ET,FA,CF,EL,HE,IN,LV,LT,MS,BP,RO,SR,LS,UK,UR,VI,44,102,103 + +; INSTALLATION HEADER +; UID of acuagentcrypto +#{"Nokia VPN", + "Cl. VPN Nokia", + "Nokia VPN-Clnt.", + "Nokia VPN", + "Client Nokia VPN", + "Nokia VPN-klient", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN", + "Cli. VPN Nokia", + "Nokia VPN is.", + "Nokia VPN", + "Клиент Nokia VPN", + "Nokia VPN", + "Nokia VPN-cl.", + "Nokia VPN kl.", + "VPN Nokia", + "Klient Nokia VPN", + "Odj. NZO Nokia", + "諾基亞VPN用戶端", + "諾基亞VPN客戶端", + "诺基亚VPN客户端", + "Nokia VPN クライアント", + "Nokia VPN client", + "Nokia VPN", + "Nokia VPN client", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN klient", + "مشتري Nokia VPN", + "RPV Nokia", + "Πελάτης της Nokia VPN", + "לקוח Nokia VPN", + "Klien VPN Nokia", + "Nokia VPN", + "Nokia VPT kl.", + "Klien Nokia VPN", + "VPN Nokia", + "Client Nokia RVP", + "Nokia VPN klijent", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN client", + "Nokia VPN", + "Nokia VPN", + "Nokia VPN"}, +(0x101F5147),32,08,0124, TYPE=SA, RU + +; Product / platform version compatibility - S60 5.1 +[0x10283160],0,0,0,{ +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID"} + +; Product / platform version compatibility - S60 5.2 +[0x20022e6d],0,0,0,{ +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID", +"Series60ProductID"} + +; List of localised vendor names - one per language. +%{"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia", +"Nokia"} + +; The non-localised, globally unique vendor name (mandatory) +:"Nokia" + +; LIST OF FILES + +;/////////////////////////////////////////////// + +; ipsecpolparser; remove later +""-"z:\sys\bin\vpnipsecpolparser.dll" + +; VPN Connection Agent +""-"z:\sys\bin\vpnconnagt.agt" + +; VPN Policy Parser +""-"z:\sys\bin\ikepolparser.dll" + +; Symmetric crypto API wrapper +""-"z:\sys\bin\utlcrypto.dll" + +; Key Management Daemon +""-"z:\sys\bin\kmdserver.exe" + +; Key Management Daemon API +""-"z:\sys\bin\kmdapi.dll" + +; IKEUTILS library +""-"z:\sys\bin\ikeutils.dll" + +""-"z:\sys\bin\ikecert.dll" +""-"z:\sys\bin\ikev1lib.dll" +""-"z:\sys\bin\ikev2lib.dll" + +; IKE socket plugin +""-"z:\sys\bin\ikesocket.dll" + +; VPN DM +""-"z:\sys\bin\dmadengine.dll" +""-"z:\sys\bin\dmadipsecvpn.dll" +""-"z:\resource\plugins\dmadipsecvpn.rsc" +""-"z:\sys\bin\dmadpki.dll" +""-"z:\resource\plugins\dmadpki.rsc" + + +; VPN API (comes with platform) +""-"z:\sys\bin\vpnapi.dll" + +; VPN Management UI +""-"z:\sys\bin\vpnmanagementui.dll" + +""-"z:\resource\vpnmanagementuirsc.r*" + +; icon and GS plugin registration file +""-"z:\resource\apps\vpnmanagementui.mif" +""-"z:\resource\plugins\vpnmanagementui.rsc" + +; VPN help resources (not localized yet) +; Help resources should be already in ROM but content can be updated from SIS package +""-"z:\resource\help\vpn.h*" + +; PKI Services Server +""-"z:\sys\bin\pkiservice.exe" +; PKI Services API +""-"z:\sys\bin\pkiserviceapi.dll" + +; PKCS#10 Module +""-"z:\sys\bin\utlpkcs10.dll" +; PKCS#12 Module +""-"z:\sys\bin\utlpkcs12.dll" +; Base64 Module +""-"z:\sys\bin\utlbase64.dll" +; Socket Interaction Thread +""-"z:\sys\bin\eventmedsit.dll" +; Event Viewer +""-"z:\sys\bin\eventviewer.dll" +; +""-"z:\resource\vpnlogmessages.rsc" + +; Terminal control stubs (for downwards compatibility) +""-"z:\sys\bin\vpntcwrapper.dll" + +; VPN dialog manager +""-"z:\sys\bin\vpndialogmanager.dll" + +; VPN ECOM Notifier plug-in +""-"z:\sys\bin\vpnecomnotifier.dll" + +""-"z:\resource\plugins\vpnecomnotifier.rsc" + +""-"z:\resource\vpnecomnotifier.r*" + +; XML Parser +""-"z:\sys\bin\utlxml.dll" + +""-"z:\sys\bin\vpnpolicyrecognizer.dll" +""-"z:\resource\plugins\vpnpolicyrecognizer.rsc" + +""-"z:\sys\bin\vpnpolins.exe" +""-"z:\Private\10003a3f\import\apps\vpnpolins_reg.rsc" +; Embedded VPN Policy Installer sis file +@"..\..\ce_sis\sub_sisses\mVPN_vpnpolins_armv5.sis",(0xA0000131) + +; +; VPN Cleaner +; +""-"z:\sys\bin\vpncleaner.exe" +; +; VPN Manager +""-"z:\sys\bin\vpnmanager.exe" + +; Event Mediator +""-"z:\sys\bin\eventmed.exe" + +; Event Mediator API +""-"z:\sys\bin\eventmedapi.dll" + +; VPN Installer +""-"z:\sys\bin\vpnins.exe" diff -r 000000000000 -r 33413c0669b9 vpnclient_sis/stub_sis/group/stub_vpnpolins_armv5.pkg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnclient_sis/stub_sis/group/stub_vpnpolins_armv5.pkg Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,38 @@ +; +; Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +; All rights reserved. +; This component and the accompanying materials are made available +; under the terms of "Eclipse Public License v1.0" +; which accompanies this distribution, and is available +; at the URL "http://www.eclipse.org/legal/epl-v10.html". +; +; Initial Contributors: +; Nokia Corporation - initial contribution. +; +; Contributors: +; +; Description: +; +;// +;// Nokia VPN Client, VPNPolIns +;// +;//////////////////////////////////////////////////////////////// + +; LANGUAGES +; - None (English only by default) + +; INSTALLATION HEADER +#{"Nokia VPN Policy Installer Stub"},(0xA0000131),32,08,0124 + +; Product / platform version compatibility - S60 5.1 and 5.2 +[0x10283160],0,0,0,{"Series60ProductID"} +[0x20022e6d],0,0,0,{"Series60ProductID"} + +; List of localised vendor names - one per language. +; At least one must be provided (English [EN]). +%{"Nokia"} + +; Unique Vendor Name +:"Nokia" + +; No files! \ No newline at end of file diff -r 000000000000 -r 33413c0669b9 vpnclient_sis/stub_sis/group/update_versions.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnclient_sis/stub_sis/group/update_versions.pl Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,78 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# +# +# update_versions.pl +# +# Updates pkg-files' and vpnclient_sis.mk's version information with current date. +# Creates temporary pkg-files with updated version. +# + +use strict; +use POSIX qw(strftime); +use File::Copy; + + +my $PLATFORM = "41"; + +# +# Creates a temp file and replaces line +# +sub replace_line_and_create_temp +{ + # arguments + my ($pattern, $replacement, $path) = @_; + + # create temp file + my $temp_path = "temp_".$path; + if (-e $temp_path) + { + chmod 0666, $temp_path; + unlink $temp_path; + } + copy($path, $temp_path); + chmod 0666, $temp_path; + + # update version information + my ($infile, $outfile); + open $infile, "<".$path or die "Can't open $path : $!"; + open $outfile, ">".$temp_path or die "Can't open $temp_path : $!"; + while (<$infile>) + { + my $line = $_; + if ($line =~ s/$pattern/$replacement/g) + { + print "Replaced line in $temp_path\n"; + } + print $outfile $line; + } + close $infile; + close $outfile; +} + +my $pkgtime = strftime($PLATFORM.",%y,%m%d", localtime()); +my $mktime = strftime("%y%m%d", localtime()); + +# stub_nokia_vpn_vpnpolins_armv5.pkg +replace_line_and_create_temp( + '^#{"Nokia VPN Policy Installer Stub"},\(0xA0000131\),.*?,.*?,.*?', + "#{\"Nokia VPN Policy Installer Stub\"},(0xA0000131),$pkgtime", + 'stub_vpnpolins_armv5.pkg'); + +# stub_nokia_vpn_client_localised_armv5.pkg +replace_line_and_create_temp( + '^\(0x101F5147\),.*?,.*?,.*?$', + "(0x101F5147),$pkgtime", + 'stub_nokia_vpn_client_armv5.pkg'); diff -r 000000000000 -r 33413c0669b9 vpnclient_sis/stub_sis/group/vpnclient_stub_sis.mk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnclient_sis/stub_sis/group/vpnclient_stub_sis.mk Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,56 @@ +# +# Copyright (c) 2006 - 2008 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# This file provides the information required for building the +# VPN Client sis files. +# + +do_nothing : + @rem do_nothing + +MAKMAKE : do_nothing + +BLD : + @echo Processing stub_vpnpolins_armv5.pkg + makesis -v -s stub_vpnpolins_armv5.pkg ipsecvpn_vpnpolins.SIS + + @echo Processing stub_nokia_vpn_client_armv5.pkg + makesis -v -s stub_nokia_vpn_client_armv5.pkg ipsecvpn.SIS + + @echo Export stub sis files to $(EPOCROOT)epoc32\data\z\system\install + copy ipsecvpn_vpnpolins.SIS $(EPOCROOT)epoc32\data\z\system\install + copy ipsecvpn.SIS $(EPOCROOT)epoc32\data\z\system\install + +CLEAN : + if exist ipsecvpn_vpnpolins.SIS erase ipsecvpn_vpnpolins.SIS + if exist $(EPOCROOT)epoc32/data/z/system/install/ipsecvpn_vpnpolins.SIS erase $(EPOCROOT)epoc32/data/z/system/install/ipsecvpn_vpnpolins.SIS + if exist $(EPOCROOT)epoc32/data/z/system/install/ipsecvpn.SIS erase $(EPOCROOT)epoc32/data/z/system/install/ipsecvpn.SIS + if exist ipsecvpn.SIS erase ipsecvpn.SIS + if exist *BACKUP erase *BACKUP + +LIB : do_nothing + +CLEANLIB : do_nothing + +RESOURCE : do_nothing + +FREEZE : do_nothing + +SAVESPACE : do_nothing + +RELEASABLES : + if exist ipsecvpn.SIS @echo ipsecvpn.SIS + if exist ipsecvpn_vpnpolins.SIS @echo ipsecvpn_vpnpolins.SIS + +FINAL : do_nothing diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/BWINS/dmadengineU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/BWINS/dmadengineU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,70 @@ +EXPORTS + ??1CDmAdCallBack@@UAE@XZ @ 1 NONAME ; CDmAdCallBack::~CDmAdCallBack(void) + ??1CDmAdEngine@@UAE@XZ @ 2 NONAME ; CDmAdEngine::~CDmAdEngine(void) + ??1CDmAdRtNode@@UAE@XZ @ 3 NONAME ; CDmAdRtNode::~CDmAdRtNode(void) + ?AddChildObjectL@TDmAdUtil@@SAAAVMSmlDmDDFObject@@AAV2@ABVTDesC8@@@Z @ 4 NONAME ; class MSmlDmDDFObject & TDmAdUtil::AddChildObjectL(class MSmlDmDDFObject &, class TDesC8 const &) + ?AddLeafObjectL@CDmAdEngine@@QAEXABVTDesC16@@0ABVTDesC8@@0H@Z @ 5 NONAME ; void CDmAdEngine::AddLeafObjectL(class TDesC16 const &, class TDesC16 const &, class TDesC8 const &, class TDesC16 const &, int) + ?AddNodeObjectL@CDmAdEngine@@QAEXABVTDesC16@@0H@Z @ 6 NONAME ; void CDmAdEngine::AddNodeObjectL(class TDesC16 const &, class TDesC16 const &, int) + ?AddNodeObjectL@CDmAdEngine@@QAEXABVTDesC8@@0H@Z @ 7 NONAME ; void CDmAdEngine::AddNodeObjectL(class TDesC8 const &, class TDesC8 const &, int) + ?BuildLocallyCreatedRtNodeUriSegLC@TDmAdUtil@@SAPAVHBufC8@@AAH@Z @ 8 NONAME ; class HBufC8 * TDmAdUtil::BuildLocallyCreatedRtNodeUriSegLC(int &) + ?BuildRtNodeChildUriListL@TDmAdUtil@@SAXPAVMDmAdCallBack@@PAVMDmAdStoreApi@@ABVTDesC8@@2ABV?$CArrayFix@UTSmlDmMappingInfo@@@@AAVCBufBase@@@Z @ 9 NONAME ; void TDmAdUtil::BuildRtNodeChildUriListL(class MDmAdCallBack *, class MDmAdStoreApi *, class TDesC8 const &, class TDesC8 const &, class CArrayFix const &, class CBufBase &) + ?BuildUriL@TDmAdUtil@@SAPAVHBufC8@@ABVTDesC8@@0@Z @ 10 NONAME ; class HBufC8 * TDmAdUtil::BuildUriL(class TDesC8 const &, class TDesC8 const &) + ?BuildUriLC@TDmAdUtil@@SAPAVHBufC8@@ABVTDesC8@@0@Z @ 11 NONAME ; class HBufC8 * TDmAdUtil::BuildUriLC(class TDesC8 const &, class TDesC8 const &) + ?ChildURIListL@CDmAdEngine@@QAEXABVTDesC16@@0ABV?$CArrayFix@UTSmlDmMappingInfo@@@@HH@Z @ 12 NONAME ; void CDmAdEngine::ChildURIListL(class TDesC16 const &, class TDesC16 const &, class CArrayFix const &, int, int) + ?ChildURIListL@CDmAdEngine@@QAEXABVTDesC8@@0ABV?$CArrayFix@UTSmlDmMappingInfo@@@@HH@Z @ 13 NONAME ; void CDmAdEngine::ChildURIListL(class TDesC8 const &, class TDesC8 const &, class CArrayFix const &, int, int) + ?CommitAtomicL@CDmAdEngine@@QAEXXZ @ 14 NONAME ; void CDmAdEngine::CommitAtomicL(void) + ?CompareUris@TDmAdUtil@@SAHABVTDesC8@@0@Z @ 15 NONAME ; int TDmAdUtil::CompareUris(class TDesC8 const &, class TDesC8 const &) + ?CompleteOutstandingCmdsL@CDmAdEngine@@QAEXXZ @ 16 NONAME ; void CDmAdEngine::CompleteOutstandingCmdsL(void) + ?CopyCommandL@CDmAdEngine@@QAEXABVTDesC8@@0000H@Z @ 17 NONAME ; void CDmAdEngine::CopyCommandL(class TDesC8 const &, class TDesC8 const &, class TDesC8 const &, class TDesC8 const &, class TDesC8 const &, int) + ?DeleteObjectL@CDmAdEngine@@QAEXABVTDesC16@@0H@Z @ 18 NONAME ; void CDmAdEngine::DeleteObjectL(class TDesC16 const &, class TDesC16 const &, int) + ?DeleteObjectL@CDmAdEngine@@QAEXABVTDesC8@@0H@Z @ 19 NONAME ; void CDmAdEngine::DeleteObjectL(class TDesC8 const &, class TDesC8 const &, int) + ?DesToInt@TDmAdUtil@@SAHABVTDesC16@@@Z @ 20 NONAME ; int TDmAdUtil::DesToInt(class TDesC16 const &) + ?DesToInt@TDmAdUtil@@SAHABVTDesC8@@@Z @ 21 NONAME ; int TDmAdUtil::DesToInt(class TDesC8 const &) + ?DesToUint@TDmAdUtil@@SAIABVTDesC16@@@Z @ 22 NONAME ; unsigned int TDmAdUtil::DesToUint(class TDesC16 const &) + ?DesToUint@TDmAdUtil@@SAIABVTDesC8@@@Z @ 23 NONAME ; unsigned int TDmAdUtil::DesToUint(class TDesC8 const &) + ?EndMessageL@CDmAdEngine@@QAEXXZ @ 24 NONAME ; void CDmAdEngine::EndMessageL(void) + ?ExecuteCommandL@CDmAdEngine@@QAEXABVTDesC8@@000H@Z @ 25 NONAME ; void CDmAdEngine::ExecuteCommandL(class TDesC8 const &, class TDesC8 const &, class TDesC8 const &, class TDesC8 const &, int) + ?ExecuteCommandL@CDmAdEngine@@QAEXABVTDesC8@@0AAPAVRWriteStream@@0H@Z @ 26 NONAME ; void CDmAdEngine::ExecuteCommandL(class TDesC8 const &, class TDesC8 const &, class RWriteStream * &, class TDesC8 const &, int) + ?FetchLeafObjectL@CDmAdEngine@@QAEXABVTDesC16@@00HH@Z @ 27 NONAME ; void CDmAdEngine::FetchLeafObjectL(class TDesC16 const &, class TDesC16 const &, class TDesC16 const &, int, int) + ?FetchLeafObjectL@CDmAdEngine@@QAEXABVTDesC8@@00HH@Z @ 28 NONAME ; void CDmAdEngine::FetchLeafObjectL(class TDesC8 const &, class TDesC8 const &, class TDesC8 const &, int, int) + ?FetchLeafObjectSizeL@CDmAdEngine@@QAEXABVTDesC8@@00HH@Z @ 29 NONAME ; void CDmAdEngine::FetchLeafObjectSizeL(class TDesC8 const &, class TDesC8 const &, class TDesC8 const &, int, int) + ?FetchLinkL@CDmAdCallBack@@UAEXABVTDesC8@@AAVCBufBase@@AAW4TError@MSmlDmAdapter@@@Z @ 30 NONAME ; void CDmAdCallBack::FetchLinkL(class TDesC8 const &, class CBufBase &, enum MSmlDmAdapter::TError &) + ?FillNodeInfoL@TDmAdUtil@@SAXAAVMSmlDmDDFObject@@VTSmlDmAccessTypes@@W4TOccurence@2@W4TScope@2@W4TDFFormat@2@ABVTDesC8@@H5@Z @ 31 NONAME ; void TDmAdUtil::FillNodeInfoL(class MSmlDmDDFObject &, class TSmlDmAccessTypes, enum MSmlDmDDFObject::TOccurence, enum MSmlDmDDFObject::TScope, enum MSmlDmDDFObject::TDFFormat, class TDesC8 const &, int, class TDesC8 const &) + ?FindChildUriL@CDmAdCallBack@@UAEPAVHBufC8@@ABVTDesC8@@0@Z @ 32 NONAME ; class HBufC8 * CDmAdCallBack::FindChildUriL(class TDesC8 const &, class TDesC8 const &) + ?FirstUriSeg@TDmAdUtil@@SA?AVTPtrC8@@ABVTDesC8@@@Z @ 33 NONAME ; class TPtrC8 TDmAdUtil::FirstUriSeg(class TDesC8 const &) + ?GetLuidAllocL@CDmAdCallBack@@UAEPAVHBufC8@@ABVTDesC8@@@Z @ 34 NONAME ; class HBufC8 * CDmAdCallBack::GetLuidAllocL(class TDesC8 const &) + ?IntToDes8LC@TDmAdUtil@@SAPAVHBufC8@@H@Z @ 35 NONAME ; class HBufC8 * TDmAdUtil::IntToDes8LC(int) + ?IntToDes8LC@TDmAdUtil@@SAPAVHBufC8@@I@Z @ 36 NONAME ; class HBufC8 * TDmAdUtil::IntToDes8LC(unsigned int) + ?IntToDes8LC@TDmAdUtil@@SAPAVHBufC8@@J@Z @ 37 NONAME ; class HBufC8 * TDmAdUtil::IntToDes8LC(long) + ?IntToDes8LC@TDmAdUtil@@SAPAVHBufC8@@K@Z @ 38 NONAME ; class HBufC8 * TDmAdUtil::IntToDes8LC(unsigned long) + ?IntToDesLC@TDmAdUtil@@SAPAVHBufC16@@H@Z @ 39 NONAME ; class HBufC16 * TDmAdUtil::IntToDesLC(int) + ?IntToDesLC@TDmAdUtil@@SAPAVHBufC16@@I@Z @ 40 NONAME ; class HBufC16 * TDmAdUtil::IntToDesLC(unsigned int) + ?IntToDesLC@TDmAdUtil@@SAPAVHBufC16@@J@Z @ 41 NONAME ; class HBufC16 * TDmAdUtil::IntToDesLC(long) + ?IntToDesLC@TDmAdUtil@@SAPAVHBufC16@@K@Z @ 42 NONAME ; class HBufC16 * TDmAdUtil::IntToDesLC(unsigned long) + ?LastUriSeg@TDmAdUtil@@SA?AVTPtrC8@@ABVTDesC8@@@Z @ 43 NONAME ; class TPtrC8 TDmAdUtil::LastUriSeg(class TDesC8 const &) + ?Luid@CDmAdRtNode@@QBE?AVTPtrC8@@XZ @ 44 NONAME ; class TPtrC8 CDmAdRtNode::Luid(void) const + ?LuidTo16L@TDmAdUtil@@SAPAVHBufC16@@ABVTDesC8@@@Z @ 45 NONAME ; class HBufC16 * TDmAdUtil::LuidTo16L(class TDesC8 const &) + ?LuidTo8L@TDmAdUtil@@SAPAVHBufC8@@ABVTDesC16@@@Z @ 46 NONAME ; class HBufC8 * TDmAdUtil::LuidTo8L(class TDesC16 const &) + ?MapStatusCode@TDmAdUtil@@SA?AW4TError@MSmlDmAdapter@@H@Z @ 47 NONAME ; enum MSmlDmAdapter::TError TDmAdUtil::MapStatusCode(int) + ?NewL@CDmAdCallBack@@SAPAV1@PAVMSmlDmCallback@@ABVTDesC8@@@Z @ 48 NONAME ; class CDmAdCallBack * CDmAdCallBack::NewL(class MSmlDmCallback *, class TDesC8 const &) + ?NewL@CDmAdEngine@@SAPAV1@PAVMDmAdCallBack@@PAVMDmAdStoreApi@@PAVMDmAdDdfApi@@PAVMDmAdRtNodeDataApi@@@Z @ 49 NONAME ; class CDmAdEngine * CDmAdEngine::NewL(class MDmAdCallBack *, class MDmAdStoreApi *, class MDmAdDdfApi *, class MDmAdRtNodeDataApi *) + ?NewL@CDmAdRtNode@@SAPAV1@ABVTDesC8@@0PAVMDmAdCallBack@@PAVMDmAdRtNodeDataApi@@@Z @ 50 NONAME ; class CDmAdRtNode * CDmAdRtNode::NewL(class TDesC8 const &, class TDesC8 const &, class MDmAdCallBack *, class MDmAdRtNodeDataApi *) + ?NewLC@CDmAdCallBack@@SAPAV1@PAVMSmlDmCallback@@ABVTDesC8@@@Z @ 51 NONAME ; class CDmAdCallBack * CDmAdCallBack::NewLC(class MSmlDmCallback *, class TDesC8 const &) + ?NewLC@CDmAdEngine@@SAPAV1@PAVMDmAdCallBack@@PAVMDmAdStoreApi@@PAVMDmAdDdfApi@@PAVMDmAdRtNodeDataApi@@@Z @ 52 NONAME ; class CDmAdEngine * CDmAdEngine::NewLC(class MDmAdCallBack *, class MDmAdStoreApi *, class MDmAdDdfApi *, class MDmAdRtNodeDataApi *) + ?NumOfURISegs@TDmAdUtil@@SAHABVTDesC8@@@Z @ 53 NONAME ; int TDmAdUtil::NumOfURISegs(class TDesC8 const &) + ?ParseUriLC@TDmAdUtil@@SAXABVTDesC8@@AAPAV?$CArrayFix@VTPtrC8@@@@@Z @ 54 NONAME ; void TDmAdUtil::ParseUriLC(class TDesC8 const &, class CArrayFix * &) + ?RemoveDotSlash@TDmAdUtil@@SA?AVTPtrC8@@ABVTDesC8@@@Z @ 55 NONAME ; class TPtrC8 TDmAdUtil::RemoveDotSlash(class TDesC8 const &) + ?RemoveLastUriSeg@TDmAdUtil@@SA?AVTPtrC8@@ABVTDesC8@@@Z @ 56 NONAME ; class TPtrC8 TDmAdUtil::RemoveLastUriSeg(class TDesC8 const &) + ?RollbackAtomicL@CDmAdEngine@@QAEXXZ @ 57 NONAME ; void CDmAdEngine::RollbackAtomicL(void) + ?SetLuidL@CDmAdRtNode@@QAEXABVTDesC8@@@Z @ 58 NONAME ; void CDmAdRtNode::SetLuidL(class TDesC8 const &) + ?SetMappingL@CDmAdCallBack@@UAEXABVTDesC8@@0@Z @ 59 NONAME ; void CDmAdCallBack::SetMappingL(class TDesC8 const &, class TDesC8 const &) + ?SetResultsL@CDmAdCallBack@@UAEXHAAVCBufBase@@ABVTDesC8@@@Z @ 60 NONAME ; void CDmAdCallBack::SetResultsL(int, class CBufBase &, class TDesC8 const &) + ?SetStatusL@CDmAdCallBack@@UAEXHH@Z @ 61 NONAME ; void CDmAdCallBack::SetStatusL(int, int) + ?StartAtomicL@CDmAdEngine@@QAEXXZ @ 62 NONAME ; void CDmAdEngine::StartAtomicL(void) + ?StreamCommittedL@CDmAdEngine@@QAEXXZ @ 63 NONAME ; void CDmAdEngine::StreamCommittedL(void) + ?StreamingSupport@CDmAdEngine@@QAEHAAH@Z @ 64 NONAME ; int CDmAdEngine::StreamingSupport(int &) + ?UpdateLeafObjectL@CDmAdEngine@@QAEXABVTDesC16@@0ABVTDesC8@@0H@Z @ 65 NONAME ; void CDmAdEngine::UpdateLeafObjectL(class TDesC16 const &, class TDesC16 const &, class TDesC8 const &, class TDesC16 const &, int) + ?UpdateLeafObjectL@CDmAdEngine@@QAEXABVTDesC8@@000H@Z @ 66 NONAME ; void CDmAdEngine::UpdateLeafObjectL(class TDesC8 const &, class TDesC8 const &, class TDesC8 const &, class TDesC8 const &, int) + ?UpdateLeafObjectL@CDmAdEngine@@QAEXABVTDesC8@@0AAPAVRWriteStream@@0H@Z @ 67 NONAME ; void CDmAdEngine::UpdateLeafObjectL(class TDesC8 const &, class TDesC8 const &, class RWriteStream * &, class TDesC8 const &, int) + ?Uri@CDmAdRtNode@@QBE?AVTPtrC8@@XZ @ 68 NONAME ; class TPtrC8 CDmAdRtNode::Uri(void) const + diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/EABI/dmadengineU.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/EABI/dmadengineU.def Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,90 @@ +EXPORTS + _ZN11CDmAdEngine11EndMessageLEv @ 1 NONAME + _ZN11CDmAdEngine12CopyCommandLERK6TDesC8S2_S2_S2_S2_i @ 2 NONAME + _ZN11CDmAdEngine12StartAtomicLEv @ 3 NONAME + _ZN11CDmAdEngine13ChildURIListLERK6TDesC8S2_RK9CArrayFixI17TSmlDmMappingInfoEii @ 4 NONAME + _ZN11CDmAdEngine13ChildURIListLERK7TDesC16S2_RK9CArrayFixI17TSmlDmMappingInfoEii @ 5 NONAME + _ZN11CDmAdEngine13CommitAtomicLEv @ 6 NONAME + _ZN11CDmAdEngine13DeleteObjectLERK6TDesC8S2_i @ 7 NONAME + _ZN11CDmAdEngine13DeleteObjectLERK7TDesC16S2_i @ 8 NONAME + _ZN11CDmAdEngine14AddLeafObjectLERK7TDesC16S2_RK6TDesC8S2_i @ 9 NONAME + _ZN11CDmAdEngine14AddNodeObjectLERK6TDesC8S2_i @ 10 NONAME + _ZN11CDmAdEngine14AddNodeObjectLERK7TDesC16S2_i @ 11 NONAME + _ZN11CDmAdEngine15ExecuteCommandLERK6TDesC8S2_RP12RWriteStreamS2_i @ 12 NONAME + _ZN11CDmAdEngine15ExecuteCommandLERK6TDesC8S2_S2_S2_i @ 13 NONAME + _ZN11CDmAdEngine15RollbackAtomicLEv @ 14 NONAME + _ZN11CDmAdEngine16FetchLeafObjectLERK6TDesC8S2_S2_ii @ 15 NONAME + _ZN11CDmAdEngine16FetchLeafObjectLERK7TDesC16S2_S2_ii @ 16 NONAME + _ZN11CDmAdEngine16StreamCommittedLEv @ 17 NONAME + _ZN11CDmAdEngine16StreamingSupportERi @ 18 NONAME + _ZN11CDmAdEngine17UpdateLeafObjectLERK6TDesC8S2_RP12RWriteStreamS2_i @ 19 NONAME + _ZN11CDmAdEngine17UpdateLeafObjectLERK6TDesC8S2_S2_S2_i @ 20 NONAME + _ZN11CDmAdEngine17UpdateLeafObjectLERK7TDesC16S2_RK6TDesC8S2_i @ 21 NONAME + _ZN11CDmAdEngine20FetchLeafObjectSizeLERK6TDesC8S2_S2_ii @ 22 NONAME + _ZN11CDmAdEngine24CompleteOutstandingCmdsLEv @ 23 NONAME + _ZN11CDmAdEngine4NewLEP13MDmAdCallBackP13MDmAdStoreApiP11MDmAdDdfApiP18MDmAdRtNodeDataApi @ 24 NONAME + _ZN11CDmAdEngine5NewLCEP13MDmAdCallBackP13MDmAdStoreApiP11MDmAdDdfApiP18MDmAdRtNodeDataApi @ 25 NONAME + _ZN11CDmAdEngineD0Ev @ 26 NONAME + _ZN11CDmAdEngineD1Ev @ 27 NONAME + _ZN11CDmAdEngineD2Ev @ 28 NONAME + _ZN11CDmAdRtNode4NewLERK6TDesC8S2_P13MDmAdCallBackP18MDmAdRtNodeDataApi @ 29 NONAME + _ZN11CDmAdRtNode8SetLuidLERK6TDesC8 @ 30 NONAME + _ZN11CDmAdRtNodeD0Ev @ 31 NONAME + _ZN11CDmAdRtNodeD1Ev @ 32 NONAME + _ZN11CDmAdRtNodeD2Ev @ 33 NONAME + _ZN13CDmAdCallBack10FetchLinkLERK6TDesC8R8CBufBaseRN13MSmlDmAdapter6TErrorE @ 34 NONAME + _ZN13CDmAdCallBack10SetStatusLEii @ 35 NONAME + _ZN13CDmAdCallBack11SetMappingLERK6TDesC8S2_ @ 36 NONAME + _ZN13CDmAdCallBack11SetResultsLEiR8CBufBaseRK6TDesC8 @ 37 NONAME + _ZN13CDmAdCallBack13FindChildUriLERK6TDesC8S2_ @ 38 NONAME + _ZN13CDmAdCallBack13GetLuidAllocLERK6TDesC8 @ 39 NONAME + _ZN13CDmAdCallBack4NewLEP14MSmlDmCallbackRK6TDesC8 @ 40 NONAME + _ZN13CDmAdCallBack5NewLCEP14MSmlDmCallbackRK6TDesC8 @ 41 NONAME + _ZN13CDmAdCallBackD0Ev @ 42 NONAME + _ZN13CDmAdCallBackD1Ev @ 43 NONAME + _ZN13CDmAdCallBackD2Ev @ 44 NONAME + _ZN9TDmAdUtil10BuildUriLCERK6TDesC8S2_ @ 45 NONAME + _ZN9TDmAdUtil10IntToDesLCEi @ 46 NONAME + _ZN9TDmAdUtil10IntToDesLCEj @ 47 NONAME + _ZN9TDmAdUtil10IntToDesLCEl @ 48 NONAME + _ZN9TDmAdUtil10IntToDesLCEm @ 49 NONAME + _ZN9TDmAdUtil10LastUriSegERK6TDesC8 @ 50 NONAME + _ZN9TDmAdUtil10ParseUriLCERK6TDesC8RP9CArrayFixI6TPtrC8E @ 51 NONAME + _ZN9TDmAdUtil11CompareUrisERK6TDesC8S2_ @ 52 NONAME + _ZN9TDmAdUtil11FirstUriSegERK6TDesC8 @ 53 NONAME + _ZN9TDmAdUtil11IntToDes8LCEi @ 54 NONAME + _ZN9TDmAdUtil11IntToDes8LCEj @ 55 NONAME + _ZN9TDmAdUtil11IntToDes8LCEl @ 56 NONAME + _ZN9TDmAdUtil11IntToDes8LCEm @ 57 NONAME + _ZN9TDmAdUtil12NumOfURISegsERK6TDesC8 @ 58 NONAME + _ZN9TDmAdUtil13FillNodeInfoLER15MSmlDmDDFObject17TSmlDmAccessTypesNS0_10TOccurenceENS0_6TScopeENS0_9TDFFormatERK6TDesC8iS8_ @ 59 NONAME + _ZN9TDmAdUtil13MapStatusCodeEi @ 60 NONAME + _ZN9TDmAdUtil14RemoveDotSlashERK6TDesC8 @ 61 NONAME + _ZN9TDmAdUtil15AddChildObjectLER15MSmlDmDDFObjectRK6TDesC8 @ 62 NONAME + _ZN9TDmAdUtil16RemoveLastUriSegERK6TDesC8 @ 63 NONAME + _ZN9TDmAdUtil24BuildRtNodeChildUriListLEP13MDmAdCallBackP13MDmAdStoreApiRK6TDesC8S6_RK9CArrayFixI17TSmlDmMappingInfoER8CBufBase @ 64 NONAME + _ZN9TDmAdUtil33BuildLocallyCreatedRtNodeUriSegLCERi @ 65 NONAME + _ZN9TDmAdUtil8DesToIntERK6TDesC8 @ 66 NONAME + _ZN9TDmAdUtil8DesToIntERK7TDesC16 @ 67 NONAME + _ZN9TDmAdUtil8LuidTo8LERK7TDesC16 @ 68 NONAME + _ZN9TDmAdUtil9BuildUriLERK6TDesC8S2_ @ 69 NONAME + _ZN9TDmAdUtil9DesToUintERK6TDesC8 @ 70 NONAME + _ZN9TDmAdUtil9DesToUintERK7TDesC16 @ 71 NONAME + _ZN9TDmAdUtil9LuidTo16LERK6TDesC8 @ 72 NONAME + _ZNK11CDmAdRtNode3UriEv @ 73 NONAME + _ZNK11CDmAdRtNode4LuidEv @ 74 NONAME + _ZTI11CDmAdEngine @ 75 NONAME ; ## + _ZTI11CDmAdRtNode @ 76 NONAME ; ## + _ZTI12CDmAdCommand @ 77 NONAME ; ## + _ZTI13CDmAdCallBack @ 78 NONAME ; ## + _ZTV11CDmAdEngine @ 79 NONAME ; ## + _ZTV11CDmAdRtNode @ 80 NONAME ; ## + _ZTV12CDmAdCommand @ 81 NONAME ; ## + _ZTV13CDmAdCallBack @ 82 NONAME ; ## + _ZThn4_N13CDmAdCallBack10FetchLinkLERK6TDesC8R8CBufBaseRN13MSmlDmAdapter6TErrorE @ 83 NONAME ; ## + _ZThn4_N13CDmAdCallBack10SetStatusLEii @ 84 NONAME ; ## + _ZThn4_N13CDmAdCallBack11SetMappingLERK6TDesC8S2_ @ 85 NONAME ; ## + _ZThn4_N13CDmAdCallBack11SetResultsLEiR8CBufBaseRK6TDesC8 @ 86 NONAME ; ## + _ZThn4_N13CDmAdCallBack13FindChildUriLERK6TDesC8S2_ @ 87 NONAME ; ## + _ZThn4_N13CDmAdCallBack13GetLuidAllocLERK6TDesC8 @ 88 NONAME ; ## + diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/bmarm/DMADENGINEU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/bmarm/DMADENGINEU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,76 @@ +EXPORTS + "_._13CDmAdLuidElem" @ 1 NONAME R3UNUSED ; CDmAdLuidElem::~CDmAdLuidElem(void) + AddLeafObjectL__11CDmAdEngineRC7TDesC16T1RC6TDesC8T1i @ 2 NONAME ; CDmAdEngine::AddLeafObjectL(TDesC16 const &, TDesC16 const &, TDesC8 const &, TDesC16 const &, int) + AddNodeObjectL__11CDmAdEngineRC6TDesC8T1i @ 3 NONAME ; CDmAdEngine::AddNodeObjectL(TDesC8 const &, TDesC8 const &, int) + AddNodeObjectL__11CDmAdEngineRC7TDesC16T1i @ 4 NONAME ; CDmAdEngine::AddNodeObjectL(TDesC16 const &, TDesC16 const &, int) + BuildLocallyCreatedRtNodeUriSegLC__9TDmAdUtilRi @ 5 NONAME R3UNUSED ; TDmAdUtil::BuildLocallyCreatedRtNodeUriSegLC(int &) + BuildRtNodeChildUriListL__9TDmAdUtilP13MDmAdCallBackP13MDmAdStoreApiRC6TDesC8T3RCt9CArrayFix1Z18TNSmlDmMappingInfoR8CBufBase @ 6 NONAME ; TDmAdUtil::BuildRtNodeChildUriListL(MDmAdCallBack *, MDmAdStoreApi *, TDesC8 const &, TDesC8 const &, CArrayFix const &, CBufBase &) + BuildUriLC__9TDmAdUtilRC6TDesC8T1 @ 7 NONAME R3UNUSED ; TDmAdUtil::BuildUriLC(TDesC8 const &, TDesC8 const &) + BuildUriL__9TDmAdUtilRC6TDesC8T1 @ 8 NONAME R3UNUSED ; TDmAdUtil::BuildUriL(TDesC8 const &, TDesC8 const &) + ChildURIListL__11CDmAdEngineRC6TDesC8T1RCt9CArrayFix1Z18TNSmlDmMappingInfoii @ 9 NONAME ; CDmAdEngine::ChildURIListL(TDesC8 const &, TDesC8 const &, CArrayFix const &, int, int) + ChildURIListL__11CDmAdEngineRC7TDesC16T1RCt9CArrayFix1Z18TNSmlDmMappingInfoii @ 10 NONAME ; CDmAdEngine::ChildURIListL(TDesC16 const &, TDesC16 const &, CArrayFix const &, int, int) + CleanupOperationDeleteCArrayPtr__13CDmAdLuidElemPv @ 11 NONAME R3UNUSED ; CDmAdLuidElem::CleanupOperationDeleteCArrayPtr(void *) + CommitAtomicL__11CDmAdEngine @ 12 NONAME R3UNUSED ; CDmAdEngine::CommitAtomicL(void) + CompareUris__9TDmAdUtilRC6TDesC8T1 @ 13 NONAME R3UNUSED ; TDmAdUtil::CompareUris(TDesC8 const &, TDesC8 const &) + CompleteOutstandingCmdsL__11CDmAdEngine @ 14 NONAME R3UNUSED ; CDmAdEngine::CompleteOutstandingCmdsL(void) + CopyCommandL__11CDmAdEngineRC6TDesC8N41i @ 15 NONAME ; CDmAdEngine::CopyCommandL(TDesC8 const &, TDesC8 const &, TDesC8 const &, TDesC8 const &, TDesC8 const &, int) + DeleteObjectL__11CDmAdEngineRC6TDesC8T1i @ 16 NONAME ; CDmAdEngine::DeleteObjectL(TDesC8 const &, TDesC8 const &, int) + DeleteObjectL__11CDmAdEngineRC7TDesC16T1i @ 17 NONAME ; CDmAdEngine::DeleteObjectL(TDesC16 const &, TDesC16 const &, int) + DesToInt__9TDmAdUtilRC6TDesC8 @ 18 NONAME R3UNUSED ; TDmAdUtil::DesToInt(TDesC8 const &) + DesToInt__9TDmAdUtilRC7TDesC16 @ 19 NONAME R3UNUSED ; TDmAdUtil::DesToInt(TDesC16 const &) + DesToUint__9TDmAdUtilRC6TDesC8 @ 20 NONAME R3UNUSED ; TDmAdUtil::DesToUint(TDesC8 const &) + DesToUint__9TDmAdUtilRC7TDesC16 @ 21 NONAME R3UNUSED ; TDmAdUtil::DesToUint(TDesC16 const &) + EndMessageL__11CDmAdEngine @ 22 NONAME R3UNUSED ; CDmAdEngine::EndMessageL(void) + ExecuteCommandL__11CDmAdEngineRC6TDesC8N31i @ 23 NONAME ; CDmAdEngine::ExecuteCommandL(TDesC8 const &, TDesC8 const &, TDesC8 const &, TDesC8 const &, int) + ExecuteCommandL__11CDmAdEngineRC6TDesC8T1RP12RWriteStreamT1i @ 24 NONAME ; CDmAdEngine::ExecuteCommandL(TDesC8 const &, TDesC8 const &, RWriteStream *&, TDesC8 const &, int) + FetchLeafObjectL__11CDmAdEngineRC6TDesC8N21ii @ 25 NONAME ; CDmAdEngine::FetchLeafObjectL(TDesC8 const &, TDesC8 const &, TDesC8 const &, int, int) + FetchLeafObjectL__11CDmAdEngineRC7TDesC16N21ii @ 26 NONAME ; CDmAdEngine::FetchLeafObjectL(TDesC16 const &, TDesC16 const &, TDesC16 const &, int, int) + FetchLeafObjectSizeL__11CDmAdEngineRC6TDesC8N21ii @ 27 NONAME ; CDmAdEngine::FetchLeafObjectSizeL(TDesC8 const &, TDesC8 const &, TDesC8 const &, int, int) + FetchLinkL__13CDmAdCallBackRC6TDesC8R8CBufBaseRQ214CNSmlDmAdapter6TError @ 28 NONAME ; CDmAdCallBack::FetchLinkL(TDesC8 const &, CBufBase &, CNSmlDmAdapter::TError &) + FillNodeInfoL__9TDmAdUtilR16MNSmlDmDDFObjectG18TNSmlDmAccessTypesQ216MNSmlDmDDFObject10TOccurenceQ216MNSmlDmDDFObject6TScopeQ216MNSmlDmDDFObject9TDFFormatRC6TDesC8iT6 @ 29 NONAME ; TDmAdUtil::FillNodeInfoL(MNSmlDmDDFObject &, TNSmlDmAccessTypes, MNSmlDmDDFObject::TOccurence, MNSmlDmDDFObject::TScope, MNSmlDmDDFObject::TDFFormat, TDesC8 const &, int, TDesC8 const &) + FindChildUriL__13CDmAdCallBackRC6TDesC8T1 @ 30 NONAME R3UNUSED ; CDmAdCallBack::FindChildUriL(TDesC8 const &, TDesC8 const &) + FindLargestLocallyCreatedL__9TDmAdUtilRCt9CArrayFix1Z18TNSmlDmMappingInfo @ 31 NONAME R3UNUSED ; TDmAdUtil::FindLargestLocallyCreatedL(CArrayFix const &) + FirstUriSeg__9TDmAdUtilRC6TDesC8 @ 32 NONAME R3UNUSED ; TDmAdUtil::FirstUriSeg(TDesC8 const &) + GetLuidAllocL__13CDmAdCallBackRC6TDesC8 @ 33 NONAME R3UNUSED ; CDmAdCallBack::GetLuidAllocL(TDesC8 const &) + IntToDes8LC__9TDmAdUtilUi @ 34 NONAME R3UNUSED ; TDmAdUtil::IntToDes8LC(unsigned int) + IntToDes8LC__9TDmAdUtili @ 35 NONAME R3UNUSED ; TDmAdUtil::IntToDes8LC(int) + IntToDesLC__9TDmAdUtilUi @ 36 NONAME R3UNUSED ; TDmAdUtil::IntToDesLC(unsigned int) + IntToDesLC__9TDmAdUtili @ 37 NONAME R3UNUSED ; TDmAdUtil::IntToDesLC(int) + LastUriSeg__9TDmAdUtilRC6TDesC8 @ 38 NONAME R3UNUSED ; TDmAdUtil::LastUriSeg(TDesC8 const &) + LuidTo16L__9TDmAdUtilRC6TDesC8 @ 39 NONAME R3UNUSED ; TDmAdUtil::LuidTo16L(TDesC8 const &) + LuidTo8L__9TDmAdUtilRC7TDesC16 @ 40 NONAME R3UNUSED ; TDmAdUtil::LuidTo8L(TDesC16 const &) + Luid__C11CDmAdRtNode @ 41 NONAME R3UNUSED ; CDmAdRtNode::Luid(void) const + Luid__C13CDmAdLuidElem @ 42 NONAME R3UNUSED ; CDmAdLuidElem::Luid(void) const + MapStatusCode__9TDmAdUtili @ 43 NONAME R3UNUSED ; TDmAdUtil::MapStatusCode(int) + NewLC__11CDmAdEngineP13MDmAdCallBackP13MDmAdStoreApiP11MDmAdDdfApiP18MDmAdRtNodeDataApiRC7TDesC16 @ 44 NONAME ; CDmAdEngine::NewLC(MDmAdCallBack *, MDmAdStoreApi *, MDmAdDdfApi *, MDmAdRtNodeDataApi *, TDesC16 const &) + NewLC__13CDmAdCallBackP15MNSmlDmCallbackRC6TDesC8 @ 45 NONAME R3UNUSED ; CDmAdCallBack::NewLC(MNSmlDmCallback *, TDesC8 const &) + NewLC__13CDmAdLuidElemRC6TDesC8 @ 46 NONAME R3UNUSED ; CDmAdLuidElem::NewLC(TDesC8 const &) + NewL__11CDmAdEngineP13MDmAdCallBackP13MDmAdStoreApiP11MDmAdDdfApiP18MDmAdRtNodeDataApiRC7TDesC16 @ 47 NONAME ; CDmAdEngine::NewL(MDmAdCallBack *, MDmAdStoreApi *, MDmAdDdfApi *, MDmAdRtNodeDataApi *, TDesC16 const &) + NewL__11CDmAdRtNodeRC6TDesC8T1P13MDmAdCallBackP18MDmAdRtNodeDataApi @ 48 NONAME ; CDmAdRtNode::NewL(TDesC8 const &, TDesC8 const &, MDmAdCallBack *, MDmAdRtNodeDataApi *) + NewL__13CDmAdCallBackP15MNSmlDmCallbackRC6TDesC8 @ 49 NONAME R3UNUSED ; CDmAdCallBack::NewL(MNSmlDmCallback *, TDesC8 const &) + NewL__13CDmAdLuidElemRC6TDesC8 @ 50 NONAME R3UNUSED ; CDmAdLuidElem::NewL(TDesC8 const &) + NumOfURISegs__9TDmAdUtilRC6TDesC8 @ 51 NONAME R3UNUSED ; TDmAdUtil::NumOfURISegs(TDesC8 const &) + ParseUriLC__9TDmAdUtilRC6TDesC8RPt9CArrayFix1Z6TPtrC8 @ 52 NONAME R3UNUSED ; TDmAdUtil::ParseUriLC(TDesC8 const &, CArrayFix *&) + RemoveDotSlash__9TDmAdUtilRC6TDesC8 @ 53 NONAME R3UNUSED ; TDmAdUtil::RemoveDotSlash(TDesC8 const &) + RemoveLastUriSeg__9TDmAdUtilRC6TDesC8 @ 54 NONAME R3UNUSED ; TDmAdUtil::RemoveLastUriSeg(TDesC8 const &) + RollbackAtomicL__11CDmAdEngine @ 55 NONAME R3UNUSED ; CDmAdEngine::RollbackAtomicL(void) + SetLuidL__11CDmAdRtNodeRC6TDesC8 @ 56 NONAME R3UNUSED ; CDmAdRtNode::SetLuidL(TDesC8 const &) + SetMappingL__13CDmAdCallBackRC6TDesC8T1 @ 57 NONAME R3UNUSED ; CDmAdCallBack::SetMappingL(TDesC8 const &, TDesC8 const &) + SetResultsL__13CDmAdCallBackiR8CBufBaseRC6TDesC8 @ 58 NONAME ; CDmAdCallBack::SetResultsL(int, CBufBase &, TDesC8 const &) + SetStatusL__13CDmAdCallBackii @ 59 NONAME R3UNUSED ; CDmAdCallBack::SetStatusL(int, int) + StartAtomicL__11CDmAdEngine @ 60 NONAME R3UNUSED ; CDmAdEngine::StartAtomicL(void) + StreamCommittedL__11CDmAdEngine @ 61 NONAME R3UNUSED ; CDmAdEngine::StreamCommittedL(void) + StreamingSupport__11CDmAdEngineRi @ 62 NONAME R3UNUSED ; CDmAdEngine::StreamingSupport(int &) + UpdateLeafObjectL__11CDmAdEngineRC6TDesC8N31i @ 63 NONAME ; CDmAdEngine::UpdateLeafObjectL(TDesC8 const &, TDesC8 const &, TDesC8 const &, TDesC8 const &, int) + UpdateLeafObjectL__11CDmAdEngineRC6TDesC8T1RP12RWriteStreamT1i @ 64 NONAME ; CDmAdEngine::UpdateLeafObjectL(TDesC8 const &, TDesC8 const &, RWriteStream *&, TDesC8 const &, int) + UpdateLeafObjectL__11CDmAdEngineRC7TDesC16T1RC6TDesC8T1i @ 65 NONAME ; CDmAdEngine::UpdateLeafObjectL(TDesC16 const &, TDesC16 const &, TDesC8 const &, TDesC16 const &, int) + Uri__C11CDmAdRtNode @ 66 NONAME R3UNUSED ; CDmAdRtNode::Uri(void) const + "_._11CDmAdEngine" @ 67 NONAME R3UNUSED ; CDmAdEngine::~CDmAdEngine(void) + "_._11CDmAdRtNode" @ 68 NONAME R3UNUSED ; CDmAdRtNode::~CDmAdRtNode(void) + "_._13CDmAdCallBack" @ 69 NONAME R3UNUSED ; CDmAdCallBack::~CDmAdCallBack(void) + AddChildObjectL__9TDmAdUtilR16MNSmlDmDDFObjectRC6TDesC8 @ 70 NONAME R3UNUSED ; TDmAdUtil::AddChildObjectL(MNSmlDmDDFObject &, TDesC8 const &) + IntToDes8LC__9TDmAdUtilUl @ 71 NONAME R3UNUSED ; TDmAdUtil::IntToDes8LC(unsigned long) + IntToDes8LC__9TDmAdUtill @ 72 NONAME R3UNUSED ; TDmAdUtil::IntToDes8LC(long) + IntToDesLC__9TDmAdUtilUl @ 73 NONAME R3UNUSED ; TDmAdUtil::IntToDesLC(unsigned long) + IntToDesLC__9TDmAdUtill @ 74 NONAME R3UNUSED ; TDmAdUtil::IntToDesLC(long) + diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file provides the information required for building the module. +* +*/ + + + +#include + +PRJ_MMPFILES +dmadengine.mmp diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/group/dmadengine.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/group/dmadengine.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project dmadengine +* +*/ + + + +#include + +TARGET dmadengine.dll +TARGETTYPE DLL +UID 0x1000008d 0x20000247 + +CAPABILITY CAP_ECOM_PLUGIN +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE dmadcallback.cpp +SOURCE dmadcommand.cpp +SOURCE dmadengine.cpp +SOURCE dmadenginenewapi.cpp +SOURCE dmadrtnode.cpp +SOURCE dmadutil.cpp + + +USERINCLUDE ../inc + +MW_LAYER_SYSTEMINCLUDE +SYSTEMINCLUDE /epoc32/include/ecom + +LIBRARY euser.lib +LIBRARY charconv.lib +LIBRARY sysutil.lib +LIBRARY ecom.lib + +DEBUGLIBRARY flogger.lib + +MACRO DMAD_ENGINE_EXPORT \ No newline at end of file diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/inc/DmAdRtNode.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/inc/DmAdRtNode.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdRtNode. +* +*/ + + + +#ifndef __DMADRTNODE_H__ +#define __DMADRTNODE_H__ + +#include + +#include "dmadengineexportdef.h" +#include "dmadcallback.h" +#include "dmadcommand.h" +#include "dmadrtnodedataapi.h" + +//------------------------------------------------------------------------------------------------ +// CDmAdRtNode +//------------------------------------------------------------------------------------------------ +class CDmAdRtNode : public CBase + { +public: + DMAD_IMPORT_C static CDmAdRtNode* NewL(const TDesC8& aUri, const TDesC8& aLuid, MDmAdCallBack* aCallBack, MDmAdRtNodeDataApi* aRtNodeDataApi); + DMAD_IMPORT_C ~CDmAdRtNode(); + DMAD_IMPORT_C TPtrC8 Uri(void) const; + DMAD_IMPORT_C TPtrC8 Luid(void) const; + DMAD_IMPORT_C void SetLuidL(const TDesC8& aLuid); + static void CleanupOperationDeleteCArrayPtr(TAny* aPtr); + void AppendCommandL(CDmAdCommand* aCommand); + void AddLeafObjectL(const TDesC8& aUri, const TDesC8& aObject, TInt aStatusRef); + void UpdateLeafObjectL(const TDesC8& aUri, const TDesC8& aObject, TInt aStatusRef); + TBool IsSomeChild(const TDesC8& aSomeParentUri) const; + TBool AreUriTypesSame(const TDesC8& aUri); + + inline CArrayPtr* Commands(void) const; + inline TBool IsSomeLeafAddedToRtNode(void) const; + inline TBool IsJustFetched(void) const; + inline CDmAdRtNodeData* Data(void) const; + inline void SetSomeLeafAddedToRtNode(TBool aSomeLeafAddedToRtNode); + +private: + CDmAdRtNode(MDmAdRtNodeDataApi* aRtNodeDataApi); + void ConstructL(const TDesC8& aUri, const TDesC8& aLuid, MDmAdCallBack* aCallBack); + +private: + MDmAdRtNodeDataApi* iRtNodeDataApi; + + CArrayPtr* iCommands; + HBufC8* iUri; + HBufC8* iLuid; + TBool iSomeLeafAddedToRtNode; + TBool iJustFetched; + CDmAdRtNodeData* iData; + }; + +#include "dmadrtnode.inl" + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/inc/dmadcallback.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/inc/dmadcallback.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Call back interface +* +*/ + + + +#ifndef __DMADCALLBACK_H__ +#define __DMADCALLBACK_H__ + +#include + +//------------------------------------------------------------------------------------------------ +// MDmAdCallBack +//------------------------------------------------------------------------------------------------ +class MDmAdCallBack + { + public: + virtual void SetResultsL(TInt aResultsRef, CBufBase& aObject, const TDesC8& aType) = 0; + virtual void SetStatusL(TInt aStatusRef, TInt aError) = 0; + virtual void SetMappingL(const TDesC8& aUri, const TDesC8& aLuid) = 0; + virtual void FetchLinkL(const TDesC8& aUri, CBufBase& aData, MSmlDmAdapter::TError& aStatus) = 0; + virtual HBufC8* GetLuidAllocL(const TDesC8& aUri) = 0; + virtual HBufC8* FindChildUriL(const TDesC8& aParentUri, const TDesC8& aChildLuid) = 0; + }; +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/inc/dmadcallbackc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/inc/dmadcallbackc.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Call back implementation +* +*/ + + + +#ifndef __DMADCALLBACKC_H__ +#define __DMADCALLBACKC_H__ + +#include "dmadengineexportdef.h" +#include "dmadcallback.h" + +//------------------------------------------------------------------------------------------------ +// CDmAdCallBack +//------------------------------------------------------------------------------------------------ +class CDmAdCallBack : public CBase, public MDmAdCallBack + { +public: + DMAD_IMPORT_C static CDmAdCallBack* NewL(MSmlDmCallback* aCallBack, const TDesC8& aSomeOwnUri); + DMAD_IMPORT_C static CDmAdCallBack* NewLC(MSmlDmCallback* aCallBack, const TDesC8& aSomeOwnUri); + DMAD_IMPORT_C ~CDmAdCallBack(); + + DMAD_IMPORT_C void SetMappingL(const TDesC8& aURI, const TDesC8& aLuid); + DMAD_IMPORT_C void SetStatusL(TInt aStatusRef, TInt aError); + DMAD_IMPORT_C void SetResultsL(TInt aResultsRef, CBufBase& aObject, const TDesC8& aType); + DMAD_IMPORT_C void FetchLinkL(const TDesC8& aUri, CBufBase& aData, MSmlDmAdapter::TError& aStatus); + DMAD_IMPORT_C HBufC8* GetLuidAllocL(const TDesC8& aUri); + DMAD_IMPORT_C HBufC8* FindChildUriL(const TDesC8& aParentUri, const TDesC8& aChildLuid); + +private: + void ConstructL(const TDesC8& aSomeOwnUri); + CDmAdCallBack(MSmlDmCallback* aCallBack); +private: + MSmlDmCallback* iCallBack; + HBufC8* iSomeOwnUri; + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/inc/dmadcommand.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/inc/dmadcommand.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdCommand. +* +*/ + + +#ifndef __DMADCOMMAND_H__ +#define __DMADCOMMAND_H__ + +#include + +//------------------------------------------------------------------------------------------------ +// CDmAdCommand +//------------------------------------------------------------------------------------------------ +class CDmAdCommand : public CBase + { +public: + static CDmAdCommand* NewL(const TDesC8& aUri, const TInt aStatusRef, TBool aLeaf); + static CDmAdCommand* NewLC(const TDesC8& aUri, const TInt aStatusRef, TBool aLeaf); + ~CDmAdCommand(); + static void CleanupOperationDeleteCArrayPtr(TAny* aPtr); + + inline TInt StatusRef(void) const; + inline TInt Status(void) const; + inline TBool IsLeaf(void) const; + +private: + void ConstructL(const TDesC8& aUri); + CDmAdCommand(const TInt aStatusRef, TBool aLeaf); + +private: + CDmAdCommand(); + void ConstructL(void); + +private: + TInt iStatusRef; + TInt iStatus; + TBool iLeaf; + }; + +#include "dmadcommand.inl" + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/inc/dmadcommand.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/inc/dmadcommand.inl Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Inlined command methods +* +*/ + + + +#ifndef __DMADCOMMAND_INL__ +#define __DMADCOMMAND_INL__ + +inline TInt CDmAdCommand::StatusRef(void) const + { + return iStatusRef; + } + +inline TInt CDmAdCommand::Status(void) const + { + return iStatus; + } + +inline TBool CDmAdCommand::IsLeaf(void) const + { + return iLeaf; + } + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/inc/dmadddfapi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/inc/dmadddfapi.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of MDmAdDdfApi. +* +*/ + + + +#ifndef __DMADDDFAPI_H__ +#define __DMADDDFAPI_H__ + +#include + +//------------------------------------------------------------------------------------------------ +// MDmAdDdfApi +//------------------------------------------------------------------------------------------------ +class MDmAdDdfApi + { + public: + virtual void NotRtNodeAddNodeObjectL(const TDesC8& aUri, const TDesC8& aParentLuid, TInt aStatusRef) = 0; + virtual void NotRtNodeUpdateLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aObject, const TDesC8& aType, TInt aStatusRef) = 0; + virtual TInt NotRtNodeFetchLeafObjectLC(const TDesC8& aUri, const TDesC8& /*aLuid*/, const TDesC8& /*aType*/, CBufBase*& aObject) = 0; + virtual void NotRtNodeDeleteObjectL(const TDesC8& aUri, const TDesC8& aLuid, TInt aStatusRef) = 0; + + virtual TBool IsNodeRtNodeL(const TDesC8& aUri) = 0; + virtual TBool IsLeafUnderRtNodeL(const TDesC8& aUri) = 0; + virtual TPtrC8 RtNodeUriForLeafL(const TDesC8& aLeafUri) = 0; + virtual TBool IsTopLevelRtNode(const TDesC8& aUri) = 0; + virtual HBufC8* ParentRtNodeUriForRtNodeLC(const TDesC8& aUri) = 0; + virtual void BuildChildUriListLC(const TDesC8& aUri, const TDesC8& aParentLuid, const CArrayFix& aPreviousUriSegmentList, CBufBase*& aCurrentList) = 0; + }; +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/inc/dmadengine.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/inc/dmadengine.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,136 @@ +/* +* Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Engine +* +*/ + + + +#ifndef __DMADENGINE_H__ +#define __DMADENGINE_H__ + +#include +#include "dmadengineexportdef.h" +#include "dmadcallback.h" +#include "dmadstoreapi.h" +#include "dmadddfapi.h" +#include "dmadrtnodedataapi.h" +#include "DmAdRtNode.h" + +//------------------------------------------------------------------------------------------------ +// CDmAdEngine +//------------------------------------------------------------------------------------------------ +class CDmAdEngine : public CBase + { +public: + DMAD_IMPORT_C static CDmAdEngine* NewL(MDmAdCallBack* aDmAdCallBack, + MDmAdStoreApi* aStoreApi, + MDmAdDdfApi* aDdfApi, + MDmAdRtNodeDataApi* aRtNodeDataApi); + + DMAD_IMPORT_C static CDmAdEngine* NewLC(MDmAdCallBack* aDmAdCallBack, + MDmAdStoreApi* aStoreApi, + MDmAdDdfApi* aDdfApi, + MDmAdRtNodeDataApi* aRtNodeDataApi); + DMAD_IMPORT_C ~CDmAdEngine(); + + DMAD_IMPORT_C void ChildURIListL(const TDesC8& aUri, const TDesC8& aLuid, const CArrayFix& aPreviousURISegmentList, TInt aResultsRef, TInt aStatusRef); + DMAD_IMPORT_C void AddNodeObjectL(const TDesC8& aUri, const TDesC8& aParentLuid, const TInt aStatusRef); + DMAD_IMPORT_C void UpdateLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aObject, const TDesC8& aType, TInt aStatusRef); + DMAD_IMPORT_C void FetchLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aType, TInt aResultsRef, TInt aStatusRef); + DMAD_IMPORT_C void DeleteObjectL(const TDesC8& aUri, const TDesC8& aLuid, TInt aStatusRef); + DMAD_IMPORT_C void CompleteOutstandingCmdsL(); + + DMAD_IMPORT_C void ChildURIListL(const TDesC& aUri, const TDesC& aLuid, const CArrayFix& aPreviousURISegmentList, const TInt aResultsRef, const TInt aStatusRef); + DMAD_IMPORT_C void AddNodeObjectL(const TDesC& aUri, const TDesC& aParentLuid, const TInt aStatusRef); + DMAD_IMPORT_C void AddLeafObjectL(const TDesC& aUri, const TDesC& aParentLuid, const TDesC8& aObject, const TDesC& aType, const TInt aStatusRef); + DMAD_IMPORT_C void UpdateLeafObjectL(const TDesC& aUri, const TDesC& aLuid, const TDesC8& aObject, const TDesC& aType, const TInt aStatusRef); + DMAD_IMPORT_C void FetchLeafObjectL(const TDesC& aUri, const TDesC& aLuid, const TDesC& aType, const TInt aResultsRef, const TInt aStatusRef); + DMAD_IMPORT_C void DeleteObjectL(const TDesC& aUri, const TDesC& aLuid, const TInt aStatusRef); + DMAD_IMPORT_C void EndMessageL(); + + DMAD_IMPORT_C void UpdateLeafObjectL(const TDesC8& aUri, + const TDesC8& aLuid, + RWriteStream*& aStream, + const TDesC8& aType, + TInt aStatusRef); + DMAD_IMPORT_C void FetchLeafObjectSizeL(const TDesC8& aUri, + const TDesC8& aLuid, + const TDesC8& aType, + TInt aResultsRef, + TInt aStatusRef); + DMAD_IMPORT_C void ExecuteCommandL(const TDesC8& aUri, + const TDesC8& aLuid, + const TDesC8& aArgument, + const TDesC8& aType, + TInt aStatusRef); + DMAD_IMPORT_C void ExecuteCommandL(const TDesC8& aUri, + const TDesC8& aLuid, + RWriteStream*& aStream, + const TDesC8& aType, + TInt aStatusRef); + DMAD_IMPORT_C void CopyCommandL(const TDesC8& aTargetUri, + const TDesC8& aTargetLuid, + const TDesC8& aSourceUri, + const TDesC8& aSourceLuid, + const TDesC8& aType, + TInt aStatusRef); + DMAD_IMPORT_C void StartAtomicL(); + DMAD_IMPORT_C void CommitAtomicL(); + DMAD_IMPORT_C void RollbackAtomicL(); + DMAD_IMPORT_C TBool StreamingSupport(TInt& aItemSize); + DMAD_IMPORT_C void StreamCommittedL(); + +private: + void ConstructL(); + CDmAdEngine(MDmAdCallBack* aDmAdCallBack, + MDmAdStoreApi* aStoreApi, + MDmAdDdfApi* aDdfApi, + MDmAdRtNodeDataApi* aRtNodeDataApi); + + void DoChildUriListL(const TDesC8& aUri, const TDesC8& aParentLuid, const CArrayFix& aPreviousUriSegmentList, TInt aResultsRef, TInt aStatusRef); + void DoAddNodeObjectL(const TDesC8& aUri, const TDesC8& aParentLuid, TInt aStatusRef); + void DoUpdateLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aObject, const TDesC8& aType, TInt aStatusRef); + void DoFetchLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aType, TInt aResultsRef, TInt aStatusRef); + TInt DoFetchLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aType, CBufBase*& aObject); + void DoDeleteObjectL(const TDesC8& aUri, const TDesC8& aLuid, TInt aStatusRef); + void DoCompleteOutstandingCmdsL(); + + + CDmAdRtNode* FindRtNodeInBuffer(const TDesC8& aUri); + CDmAdRtNode* FindRtNodeInBufferByLuid(const TDesC8& aLuid, const TDesC8& aUri); + CDmAdRtNode* RestoreRtNodeInBufferIfNotDoneL(const TDesC8& aUri, const TDesC8& aLuid); + CDmAdRtNode* FetchRtNodeInBufferL(const TDesC8& aUri, const TDesC8& aLuid); + void CompleteCommandsL(CDmAdRtNode& aRtNode, TInt aStatus); + void CompleteCommandsL(CArrayPtr& aRtNodes, TInt aStatus); + void BuildTopLevelRtNodesListLC(CArrayPtr* aRtNodes, + CArrayPtr*& aTopLevelRtNodes); + void BuildChildRtNodesListLC(CArrayPtr* aRtNodes, + const TDesC8& aSomeParentUri, + CArrayPtr*& aChildRtNodes); + + void SaveRtNodesL(void); + TBool FindRtNodeInStoreL(const TDesC8& aLuid, const TDesC8& aUri); + HBufC8* ParentRtNodeLuidForRtNodeLC(const TDesC8& aUri); + +private: + MDmAdCallBack* iCallBack; + MDmAdStoreApi* iStoreApi; + MDmAdDdfApi* iDdfApi; + MDmAdRtNodeDataApi* iRtNodeDataApi; + + CArrayPtr* iRtNodes; + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/inc/dmadengineexportdef.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/inc/dmadengineexportdef.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Device Management Adapter Engine export definitions. +* +*/ + + + +#ifndef __DMADENGINEEXPORTDEF_H__ +#define __DMADENGINEEXPORTDEF_H__ + +#ifdef DMAD_ENGINE_EXPORT + #define DMAD_EXPORT_C EXPORT_C + #define DMAD_IMPORT_C IMPORT_C +#else + #define DMAD_EXPORT_C + #define DMAD_IMPORT_C +#endif + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/inc/dmadrtnode.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/inc/dmadrtnode.inl Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Inlined node methods +* +*/ + + + +#ifndef __DMADRTNODE_INL__ +#define __DMADRTNODE_INL__ + +inline CArrayPtr* CDmAdRtNode::Commands(void) const + { + return iCommands; + } + +inline TBool CDmAdRtNode::IsSomeLeafAddedToRtNode(void) const + { + return iSomeLeafAddedToRtNode; + } + +inline TBool CDmAdRtNode::IsJustFetched(void) const + { + return iJustFetched; + } + +inline CDmAdRtNodeData* CDmAdRtNode::Data(void) const + { + return iData; + } + +inline void CDmAdRtNode::SetSomeLeafAddedToRtNode(TBool aSomeLeafAddedToRtNode) + { + iSomeLeafAddedToRtNode = aSomeLeafAddedToRtNode; + } + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/inc/dmadrtnodedataapi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/inc/dmadrtnodedataapi.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of MDmAdRtNodeDataApi. +* +*/ + + + +#ifndef __DMADRTNODEDATAAPI_H__ +#define __DMADRTNODEDATAAPI_H__ + +#include + +class MDmAdCallBack; +class CDmAdRtNodeData; + +//------------------------------------------------------------------------------------------------ +// MDmAdRtNodeDataApi +//------------------------------------------------------------------------------------------------ +class MDmAdRtNodeDataApi + { + public: + virtual CDmAdRtNodeData* CreateDmAdRtNodeDataL(const TDesC8& aUri, MDmAdCallBack* aCallBack) = 0; + virtual void DeleteDmAdRtNodeData(CDmAdRtNodeData* aDmAdRtNodeData) = 0; + + virtual void UpdateLeafDataL(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri, const TDesC8& aObject) = 0; + virtual void FetchLeafObjectLC(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri, const TDesC8& aLuid, CBufBase*& aObject) = 0; + virtual void SetDefaultSettingsL(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri) = 0; + virtual TBool AreUriTypesSame(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri) = 0; + }; +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/inc/dmadstoreapi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/inc/dmadstoreapi.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of MDmAdStoreApi. +* +*/ + + + +#ifndef __DMADSTOREAPI_H__ +#define __DMADSTOREAPI_H__ + +#include "DmAdRtNode.h" + +//------------------------------------------------------------------------------------------------ +// MDmAdStoreApi +//------------------------------------------------------------------------------------------------ +class MDmAdStoreApi + { + public: + virtual TBool FindRtNodeL(const TDesC8& aLuid, const TDesC8& aUri) = 0; + virtual void LuidListL(const TDesC8& aUri, const TDesC8& aLuid, RPointerArray& aLuidList) = 0; + virtual void FetchRtNodeL(CDmAdRtNode& aRtNode) = 0; + virtual void SaveTopLevelRtNodeL(CDmAdRtNode& aRtNode, CArrayPtr& aChildRtNodes) = 0; + virtual void SaveChildLevelRtNodeL(CDmAdRtNode& aRtNode) = 0; + virtual void DeleteRtNodeL(const TDesC8& aLuid, const TDesC8& aUri) = 0; + }; +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/inc/dmadutil.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/inc/dmadutil.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of TDmAdUtil. +* +*/ + + + +#ifndef __DMADUTIL_H__ +#define __DMADUTIL_H__ + +#include +#include "dmadengineexportdef.h" +#include "dmadcallback.h" +#include "dmadstoreapi.h" + +_LIT8(KDmAdUriDotSlash, "./"); +_LIT8(KDmAdSeparator, "/"); +_LIT8(KDmAdMimeTypeTextPlain, "text/plain"); +_LIT8(KDmAdLocallyCreatedRtNodeUriSegPrefix, "cli"); + +//------------------------------------------------------------------------------------------------ +// TDmAdUtil +//------------------------------------------------------------------------------------------------ +class TDmAdUtil + { +public: + DMAD_IMPORT_C static TInt DesToInt(const TDesC& aDes); + DMAD_IMPORT_C static TInt DesToInt(const TDesC8& aDes); + DMAD_IMPORT_C static HBufC* IntToDesLC(const TInt aInt); + DMAD_IMPORT_C static HBufC8* IntToDes8LC(const TInt aInt); + DMAD_IMPORT_C static HBufC* IntToDesLC(const TInt32 aInt32); + DMAD_IMPORT_C static HBufC8* IntToDes8LC(const TInt32 aInt32); + DMAD_IMPORT_C static TUint DesToUint(const TDesC& aDes); + DMAD_IMPORT_C static TUint DesToUint(const TDesC8& aDes); + DMAD_IMPORT_C static HBufC* IntToDesLC(const TUint aUint); + DMAD_IMPORT_C static HBufC8* IntToDes8LC(const TUint aUint); + DMAD_IMPORT_C static HBufC* IntToDesLC(const TUint32 aUint32); + DMAD_IMPORT_C static HBufC8* IntToDes8LC(const TUint32 aUint32); + DMAD_IMPORT_C static TPtrC8 LastUriSeg(const TDesC8& aUri); + DMAD_IMPORT_C static TPtrC8 FirstUriSeg(const TDesC8& aUri); + DMAD_IMPORT_C static TPtrC8 RemoveLastUriSeg(const TDesC8& aUri); + DMAD_IMPORT_C static TInt NumOfURISegs(const TDesC8& aUri); + DMAD_IMPORT_C static TPtrC8 RemoveDotSlash(const TDesC8& aUri); + DMAD_IMPORT_C static TInt CompareUris(const TDesC8& aUri1, const TDesC8& aUri2); + DMAD_IMPORT_C static HBufC8* BuildUriLC(const TDesC8& aUriPath, const TDesC8& aUriSeg); + DMAD_IMPORT_C static HBufC8* BuildUriL(const TDesC8& aUriPath, const TDesC8& aUriSeg); + DMAD_IMPORT_C static MSmlDmAdapter::TError MapStatusCode(TInt aStatus); + DMAD_IMPORT_C static void ParseUriLC(const TDesC8& aUri, CArrayFix*& aUriSegList); + DMAD_IMPORT_C static HBufC8* LuidTo8L(const TDesC& aLuid16); + DMAD_IMPORT_C static HBufC* LuidTo16L(const TDesC8& aLuid8); + DMAD_IMPORT_C static void FillNodeInfoL(MSmlDmDDFObject& aNode, + TSmlDmAccessTypes aAccTypes, + MSmlDmDDFObject::TOccurence aOccurrence, + MSmlDmDDFObject::TScope aScope, + MSmlDmDDFObject::TDFFormat aFormat, + const TDesC8& aDescription, + TBool aObjectGroup, + const TDesC8& aMimeType=KDmAdMimeTypeTextPlain); + DMAD_IMPORT_C static MSmlDmDDFObject& AddChildObjectL(MSmlDmDDFObject& aNode, const TDesC8& aNodeName); + DMAD_IMPORT_C static HBufC8* BuildLocallyCreatedRtNodeUriSegLC(TInt& aLargest); + DMAD_IMPORT_C static void BuildRtNodeChildUriListL(MDmAdCallBack* aDmAdCallBack, + MDmAdStoreApi* aStoreApi, + const TDesC8& aUri, + const TDesC8& aParentLuid, + const CArrayFix& aPreviousUriSegmentList, + CBufBase& aCurrentList); + + +private: + static TInt FindLargestLocallyCreated(const CArrayFix& aPreviousUriSegmentList); + + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/inc/vpnlogger.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/inc/vpnlogger.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,108 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Logging code fot the dmadpki +* +*/ + + + + + +#ifndef VPNLOGGER_H +#define VPNLOGGER_H + +#if defined(_DEBUG) + +#include +#include + + +NONSHARABLE_CLASS(TTraceItem) + { +public: + inline TTraceItem(const TDesC& aTraceName); + inline ~TTraceItem(); + + inline static void TraceCleanupOperation(TAny* aItem); +private: + + HBufC* iTraceName; + TBool iMethodHasLeft; + }; + + +NONSHARABLE_CLASS(CVpnDebugLogger) : public CBase + { +public: + + inline static void InitializeDebugLoggerL(const TDesC& aFolder, const TDesC& aFileName); + inline static void FinalizeDebugLogger(); + inline static void LogWrite(const TDesC& aText); + inline static void LogWrite(const TDesC8& aText); + + inline static void LogWriteF(TRefByValue aFmt, ...); + inline static void LogWriteF(TRefByValue aFmt, ...); + + + inline static void HexWrite(const TDesC8& aData); + + +private: + inline void ConstructL(const TDesC& aFolder, const TDesC& aFileName); + inline ~CVpnDebugLogger(); + + inline static void TimeStamp(TDes& aBuffer); + inline static CVpnDebugLogger* VpnDebugLogger(); + + inline void WriteLogRaw(const TDesC& aLogMessage); + + + RFileLogger iFileLogger; + TUint iCallDepth; + + TBuf<512> iDebugString; + friend class TTraceItem; + + TUint8 iReferenceCount; + }; + +#define INITIALIZE_DEBUG_LOG_L(a, b) CVpnDebugLogger::InitializeDebugLoggerL((a), (b)) +#define FINALIZE_DEBUG_LOG CVpnDebugLogger::FinalizeDebugLogger(); + +/** + * Trace can't be used inside LC methods. + */ +#define TRACE(a) TTraceItem __trace(TPtrC((const TText *)L ## a)) +#define DEBUG_LOG(a) CVpnDebugLogger::LogWrite(a) +#define DEBUG_LOG1(a, b) CVpnDebugLogger::LogWriteF((a), (b)) +#define DEBUG_LOG2(a, b, c) CVpnDebugLogger::LogWriteF((a), (b), (c)) + +#define DEBUG_LOG_HEX(a) CVpnDebugLogger::HexWrite((a)) + +#include "vpnlogger.inl" + +#else + +#define INITIALIZE_DEBUG_LOG_L(a, b) +#define FINALIZE_DEBUG_LOG +#define TRACE(a) +#define DEBUG_LOG(a) +#define DEBUG_LOG1(a, b) +#define DEBUG_LOG2(a, b, c) + +#define DEBUG_LOG_HEX(a) + + +#endif //!defined(_DEBUG) +#endif //VPNLOGGER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/inc/vpnlogger.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/inc/vpnlogger.inl Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,359 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Logging code fot the dmadpki +* +*/ + + + + +#if defined(_DEBUG) + + +_LIT(KTraceOutOfMemory, "TRACE out of memory"); + +_LIT(KInMark, ">"); +_LIT(KOutMark, "<"); +_LIT(KDepthMark, "-"); +_LIT(KSeparator, " "); +_LIT(KLeaveFrom, "LEAVE FROM: "); + + + +void TTraceItem::TraceCleanupOperation(TAny* aItem) + { + + TTraceItem* traceCleanupItem = static_cast(aItem); + CVpnDebugLogger* logger = CVpnDebugLogger::VpnDebugLogger(); + logger->iCallDepth--; + + logger->iDebugString.Zero(); + + CVpnDebugLogger::TimeStamp(logger->iDebugString); + logger->iDebugString.Append(KLeaveFrom); + logger->iDebugString.Append(*(traceCleanupItem->iTraceName)); + logger->WriteLogRaw(logger->iDebugString); + + delete traceCleanupItem->iTraceName; + + traceCleanupItem->iMethodHasLeft = ETrue; + } + + +TTraceItem::TTraceItem(const TDesC& aTraceName) + { + iMethodHasLeft = EFalse; + + CVpnDebugLogger* logger = CVpnDebugLogger::VpnDebugLogger(); + + iTraceName = aTraceName.Alloc(); + if (iTraceName != NULL) + { + if (logger != NULL) + { + logger->iCallDepth++; + + logger->iDebugString.Zero(); + CVpnDebugLogger::TimeStamp(logger->iDebugString); + + for (TInt i = 0; i < logger->iCallDepth; ++i) + { + logger->iDebugString.Append(KDepthMark); + } + + logger->iDebugString.Append(KInMark); + logger->iDebugString.Append(KSeparator); + logger->iDebugString.Append(*iTraceName); + logger->WriteLogRaw(logger->iDebugString); + } + CleanupStack::PushL(TCleanupItem(TTraceItem::TraceCleanupOperation, this)); + } + else + { + if (logger != NULL) + { + logger->WriteLogRaw(KTraceOutOfMemory); + } + } + } + + +TTraceItem::~TTraceItem() + { + CVpnDebugLogger* logger = CVpnDebugLogger::VpnDebugLogger(); + + + if (!iMethodHasLeft) + { + if (iTraceName != NULL) + { + if (logger != NULL) + { + logger->iDebugString.Zero(); + CVpnDebugLogger::TimeStamp(logger->iDebugString); + logger->iDebugString.Append(KOutMark); + for (TInt i = 0; i < logger->iCallDepth; ++i) + { + logger->iDebugString.Append(KDepthMark); + } + + logger->iDebugString.Append(KSeparator); + logger->iDebugString.Append(*iTraceName); + logger->WriteLogRaw(logger->iDebugString); + + logger->iCallDepth--; + } + delete iTraceName; + CleanupStack::Pop(this); + + } + else + { + if (logger != NULL) + { + logger->WriteLogRaw(KTraceOutOfMemory); + } + } + } + } + + + +void CVpnDebugLogger::InitializeDebugLoggerL(const TDesC& aFolder, const TDesC& aFileName) + { + + CVpnDebugLogger* self = static_cast(Dll::Tls()); + if (self == NULL) + { + self = new (ELeave) CVpnDebugLogger; + CleanupStack::PushL(self); + self->ConstructL(aFolder, aFileName); + User::LeaveIfError(Dll::SetTls(self)); + CleanupStack::Pop(self); + } + self->iReferenceCount++; + } + + +void CVpnDebugLogger::ConstructL(const TDesC& aFolder, const TDesC& aFileName) + { + User::LeaveIfError(iFileLogger.Connect()); + iFileLogger.SetDateAndTime(EFalse, EFalse); + iFileLogger.CreateLog(aFolder, aFileName, EFileLoggingModeAppend); + } + + +CVpnDebugLogger::~CVpnDebugLogger() + { + if ( iFileLogger.Handle() != 0 ) + { + iFileLogger.Write(_L("Logger delete")); + iFileLogger.CloseLog(); + } + + iFileLogger.Close(); + } + + +void CVpnDebugLogger::FinalizeDebugLogger() + { + CVpnDebugLogger* self = static_cast(Dll::Tls()); + __ASSERT_ALWAYS(self != NULL, User::Invariant()); + + self->iReferenceCount--; + + if (self->iReferenceCount == 0) + { + Dll::SetTls(NULL); + delete self; + } + } + + +CVpnDebugLogger* CVpnDebugLogger::VpnDebugLogger() + { + return static_cast(Dll::Tls()); + } + + +void CVpnDebugLogger::WriteLogRaw(const TDesC& aLogMessage) + { + iFileLogger.Write(aLogMessage); + } + + +void CVpnDebugLogger::LogWrite(const TDesC& aText) + { + CVpnDebugLogger* logger = VpnDebugLogger(); + logger->iDebugString.Zero(); + CVpnDebugLogger::TimeStamp(logger->iDebugString); + + if (logger->iCallDepth > 0) + { + for (TUint i = 0; i < logger->iCallDepth; ++i) + { + logger->iDebugString.Append(_L(" ")); + } + logger->iDebugString.Append(_L(" ")); + } + + logger->iDebugString.Append(aText); + logger->WriteLogRaw(logger->iDebugString); + } + + +void CVpnDebugLogger::LogWrite(const TDesC8& aText) + { + CVpnDebugLogger* logger = VpnDebugLogger(); + logger->iDebugString.Zero(); + CVpnDebugLogger::TimeStamp(logger->iDebugString); + + if (logger->iCallDepth > 0) + { + for (TUint i = 0; i < logger->iCallDepth; ++i) + { + logger->iDebugString.Append(_L(" ")); + } + logger->iDebugString.Append(_L(" ")); + } + + TInt stringLength = logger->iDebugString.Length(); + TUint spaceLeft = logger->iDebugString.MaxLength() - stringLength; + + TUint16* ptr = const_cast(logger->iDebugString.Ptr() + stringLength); + TPtr buffer(ptr, spaceLeft); + buffer.Copy(aText); + + logger->iDebugString.SetLength(stringLength + buffer.Length()); + logger->WriteLogRaw(logger->iDebugString); + } + + +void CVpnDebugLogger::LogWriteF(TRefByValue aFmt, ...) + { + VA_LIST list; + VA_START(list,aFmt); + + + CVpnDebugLogger* logger = VpnDebugLogger(); + logger->iDebugString.Zero(); + CVpnDebugLogger::TimeStamp(logger->iDebugString); + + if (logger->iCallDepth > 0) + { + for (TUint i = 0; i < logger->iCallDepth; ++i) + { + logger->iDebugString.Append(_L(" ")); + } + logger->iDebugString.Append(_L(" ")); + } + + + const TDesC& format = aFmt; + + logger->iDebugString.AppendFormatList(format, list); + logger->WriteLogRaw(logger->iDebugString); + } + + + +void CVpnDebugLogger::LogWriteF(TRefByValue aFmt, ...) + { + TBuf8<512> buf; + + VA_LIST list; + VA_START(list,aFmt); + + const TDesC8& format = aFmt; + buf.FormatList(format, list); + + LogWrite(buf); + } + + +void CVpnDebugLogger::HexWrite(const TDesC8& aData) + { + const TUint KRowLength = 16; //16 bytes in one row + + TBuf<128> row; + + TUint rowCount = aData.Length() / KRowLength; + if (aData.Length() % KRowLength != 0) + { + rowCount++; + } + + for (TInt i = 0; i < rowCount; ++i) + { + _LIT(KRowStartFormat, "%04x: "); + TPtrC8 rowData(aData.Mid(KRowLength*i)); + + row.Zero(); + row.Format(KRowStartFormat, i*KRowLength); + TInt j; + for (j = 0; j < KRowLength; ++j) + { + if ( j < rowData.Length()) + { + _LIT(KDataByteFormat, "%02x "); + TUint8 byte = rowData[j]; + row.AppendFormat(KDataByteFormat, byte); + } + else + { + row.Append(_L(" ")); + } + } + + for (j = 0; j < KRowLength && j < rowData.Length(); ++j) + { + TUint8 byte = rowData[j]; + if (byte >= ' ' && byte <= '~') + { + row.Append(byte); + } + else + { + row.Append(_L(".")); + } + } + + + LogWrite(row); + } + } + + +void CVpnDebugLogger::TimeStamp(TDes& aBuffer) + { + TTime time; + time.HomeTime(); + TDateTime dateTime = time.DateTime(); + + + _LIT(KFormatTxt,"%02d/%02d/%d %02d:%02d:%02d.%03d "); + aBuffer.Format(KFormatTxt, + dateTime.Day()+1, + TInt(dateTime.Month()+1), + dateTime.Year(), + + dateTime.Hour(), dateTime.Minute(), dateTime.Second(), + dateTime.MicroSecond() + ); + + + } + + +#endif //defined(_DEBUG) diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/rom/dmadengine.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/rom/dmadengine.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Image description file for project dmadengine +* +*/ + + +#ifndef __DMADENGINE_IBY__ +#define __DMADENGINE_IBY__ + +#ifdef SYMBIAN_EXCLUDE_IPSEC + +REM dmadentine not included in this rom + +#else + +file=ABI_DIR\BUILD_DIR\dmadengine.dll SHARED_LIB_DIR\dmadengine.dll + +#endif // SYMBIAN_EXCLUDE_IPSEC + +#endif // __DMADENGINE_IBY__ diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/src/dmadcallback.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/src/dmadcallback.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,216 @@ +/* +* Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Call back implementation +* +*/ + + +#include + +#include "dmadcallbackc.h" +#include "dmadutil.h" +#include "vpnlogger.h" + +#if defined(_DEBUG) +_LIT(KDmAdLogFolder,"vpn"); +_LIT(KDmAdLogFile,"dmadengine.log"); +#endif + + +DMAD_EXPORT_C CDmAdCallBack* CDmAdCallBack::NewL(MSmlDmCallback* aCallBack, const TDesC8& aSomeOwnUri) + { + + //Is first method called from the dmadengine + //This why the logging is initiated here. + INITIALIZE_DEBUG_LOG_L(KDmAdLogFolder, KDmAdLogFile); + DEBUG_LOG1(_L8("LOGGING INITIALIZED for %S"), &aSomeOwnUri); + + CDmAdCallBack* self = NewLC(aCallBack, aSomeOwnUri); + CleanupStack::Pop(); // self + return self; + } + +DMAD_EXPORT_C CDmAdCallBack* CDmAdCallBack::NewLC(MSmlDmCallback* aCallBack, const TDesC8& aSomeOwnUri) + { + CDmAdCallBack* self = new (ELeave) CDmAdCallBack(aCallBack); + CleanupStack::PushL(self); + self->ConstructL(aSomeOwnUri); + return self; + } + +void CDmAdCallBack::ConstructL(const TDesC8& aSomeOwnUri) + { + TRACE("CDmAdCallBack::ConstructL"); + iSomeOwnUri = aSomeOwnUri.AllocL(); + } + +CDmAdCallBack::CDmAdCallBack(MSmlDmCallback* aCallBack) : iCallBack(aCallBack) + { + } + +DMAD_EXPORT_C CDmAdCallBack::~CDmAdCallBack() + { + + DEBUG_LOG1(_L8("FINALIZING LOGGING %S"), iSomeOwnUri); + FINALIZE_DEBUG_LOG; + + delete iSomeOwnUri; + } + +DMAD_EXPORT_C void CDmAdCallBack::SetResultsL(TInt aResultsRef, CBufBase& aObject, const TDesC8& aType) + { + TRACE("CDmAdCallBack::SetResultsL"); + + DEBUG_LOG1(_L("rref = %d"), aResultsRef); + DEBUG_LOG1(_L("lth = %d"), aObject.Ptr(0).Length()); + + DEBUG_LOG_HEX(aObject.Ptr(0)); + + iCallBack->SetResultsL(aResultsRef, aObject, aType); + } + +DMAD_EXPORT_C void CDmAdCallBack::SetStatusL(TInt aStatusRef, TInt aError) + { + TRACE("CDmAdCallBack::SetStatusL"); + + DEBUG_LOG1(_L("rref = %d"), aStatusRef); + DEBUG_LOG1(_L("status = %d"), aError); + + iCallBack->SetStatusL(aStatusRef, TDmAdUtil::MapStatusCode(aError)); + } + +DMAD_EXPORT_C void CDmAdCallBack::SetMappingL(const TDesC8& aUri, const TDesC8& aLuid) + { + TRACE("CDmAdCallBack::SetMappingL"); + + DEBUG_LOG1(_L8("aUri %S"), &aUri); + DEBUG_LOG(_L8("aLuid:")); + DEBUG_LOG_HEX(aLuid); + + iCallBack->SetMappingL(aUri, aLuid); + } + +DMAD_EXPORT_C void CDmAdCallBack::FetchLinkL(const TDesC8& aUri, CBufBase& aData, MSmlDmAdapter::TError& aStatus) + { + TRACE("CDmAdCallBack::FetchLinkL"); + + aData.Reset(); + iCallBack->FetchLinkL(aUri, aData, aStatus); + + DEBUG_LOG1(_L("FetchLinkL status %d"), aStatus); + DEBUG_LOG1(_L("Data Length %d"), aData.Ptr(0).Length()); + DEBUG_LOG1(_L8("aUri = %S"), &aUri); + DEBUG_LOG_HEX(aData.Ptr(0)); + + //Some adapters are a bit sloppy and returns a malformed URI, which + //ends with / character. This causes problems in our code. + //So if the last character is /, we strip it off. + + TUint dataSize = aData.Size(); + if (dataSize > 0) + { + TUint lastPosition = dataSize - 1; + TUint8 lastCharacter; + aData.Read(lastPosition, &lastCharacter, 1); + + if (lastCharacter == '/') + { + DEBUG_LOG(_L("WARNING: last character is /. Stripping it off...")); + aData.ResizeL(lastPosition); + } + + } +} + +DMAD_EXPORT_C HBufC8* CDmAdCallBack::GetLuidAllocL(const TDesC8& aUri) + { + TRACE("CDmAdCallBack::GetLuidAllocL"); + + HBufC8* luid = iCallBack->GetLuidAllocL(aUri); + + DEBUG_LOG1(_L8("aUri %S"), &aUri); + DEBUG_LOG(_L("luid:")); + DEBUG_LOG_HEX(*luid); + +#if 1 // restore adapter index (fixes agent) + + HBufC8* tempLuid = iCallBack->GetLuidAllocL(*iSomeOwnUri); + DEBUG_LOG1(_L8("iCallBack->GetLuidAllocL(%S) called"), iSomeOwnUri); + delete tempLuid; +#endif + + return luid; + } + +DMAD_EXPORT_C HBufC8* CDmAdCallBack::FindChildUriL(const TDesC8& aParentUri, const TDesC8& aChildLuid) + { + TRACE("CDmAdCallBack::FindChildUriL"); + + DEBUG_LOG1(_L8("aParentUri = %S"), &aParentUri); + DEBUG_LOG(_L8("aChildLuid:")); + DEBUG_LOG_HEX(aChildLuid); + + CBufBase* childUriList = CBufFlat::NewL(16); + CleanupStack::PushL(childUriList); + MSmlDmAdapter::TError status; + FetchLinkL(aParentUri, *childUriList, status); + if (status == MSmlDmAdapter::ENotFound) + { + DEBUG_LOG(_L("Node not found")); + CleanupStack::PopAndDestroy(); // childUriList + return 0; + } + else if (status != MSmlDmAdapter::EOk) + { + DEBUG_LOG1(_L("Operation failed with %d"), status); + User::Leave(KErrGeneral); + } + + CArrayFix* uriSegList; + TDmAdUtil::ParseUriLC(childUriList->Ptr(0), uriSegList); + + TBool found = EFalse; + HBufC8* uri = 0; + for (TInt i=0; iCount(); ++i) + { + uri = TDmAdUtil::BuildUriLC(aParentUri, uriSegList->At(i)); + HBufC8* luid = GetLuidAllocL(*uri); + if (luid->Compare(aChildLuid) == 0) + { + found = ETrue; + delete luid; + break; + } + CleanupStack::PopAndDestroy(); // uri + delete luid; + } + + if (found) + { + CleanupStack::Pop(); // uri + } + + CleanupStack::PopAndDestroy(2); //uriSegList, childUriList + + if (found) + { + DEBUG_LOG1(_L8("Found uri %S"), uri); + return uri; + } + else + { + DEBUG_LOG(_L("Uri not found")); + return 0; + } + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/src/dmadcommand.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/src/dmadcommand.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CDmAdCommand. +* +*/ + + +#include "dmadcommand.h" +#include "vpnlogger.h" + + +CDmAdCommand* CDmAdCommand::NewL(const TDesC8& aUri, const TInt aStatusRef, TBool aLeaf) + { + TRACE("CDmAdCommand::NewL"); + + CDmAdCommand *self = NewLC(aUri, aStatusRef, aLeaf); + CleanupStack::Pop(); // self + return self; + } + +CDmAdCommand* CDmAdCommand::NewLC(const TDesC8& aUri, const TInt aStatusRef, TBool aLeaf) + { + CDmAdCommand *self = new (ELeave) CDmAdCommand(aStatusRef, aLeaf); + CleanupStack::PushL(self); + self->ConstructL(aUri); + return self; + } + +void CDmAdCommand::ConstructL(const TDesC8& /*aUri*/) + { + TRACE("CDmAdCommand::ConstructL"); + } + +CDmAdCommand::CDmAdCommand(const TInt aStatusRef, TBool aLeaf) : + iStatusRef(aStatusRef), iStatus(KErrNone), iLeaf(aLeaf) + { + TRACE("CDmAdCommand::CDmAdCommand"); + } + +CDmAdCommand::~CDmAdCommand() + { + TRACE("CDmAdCommand::~CDmAdCommand"); + } + +void CDmAdCommand::CleanupOperationDeleteCArrayPtr(TAny* aPtr) + { + if (aPtr == NULL) + { + return; + } + CArrayPtr* array = REINTERPRET_CAST(CArrayPtr*,aPtr); + array->ResetAndDestroy(); + delete array; + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/src/dmadengine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/src/dmadengine.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,579 @@ +/* +* Copyright (c) 2000 - 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Device Management Adapter Engine. +* +*/ + + +#include +#include + +#include "dmadengine.h" +#include "dmadcommand.h" +#include "dmadutil.h" +#include "vpnlogger.h" + +//=================================================================================================== + + + +//=================================================================================================== + +DMAD_EXPORT_C CDmAdEngine* CDmAdEngine::NewL(MDmAdCallBack* aDmAdCallBack, + MDmAdStoreApi* aStoreApi, + MDmAdDdfApi* aDdfApi, + MDmAdRtNodeDataApi* aRtNodeDataApi) + { + TRACE("CDmAdEngine::NewL"); + + CDmAdEngine* self = NewLC(aDmAdCallBack, aStoreApi, aDdfApi, aRtNodeDataApi); + CleanupStack::Pop(); + return self; + } + +DMAD_EXPORT_C CDmAdEngine* CDmAdEngine::NewLC(MDmAdCallBack* aDmAdCallBack, + MDmAdStoreApi* aStoreApi, + MDmAdDdfApi* aDdfApi, + MDmAdRtNodeDataApi* aRtNodeDataApi) + { + CDmAdEngine* self = new (ELeave) CDmAdEngine(aDmAdCallBack, aStoreApi, aDdfApi, aRtNodeDataApi); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +void CDmAdEngine::ConstructL() + { + TRACE("CDmAdEngine::ConstructL"); + iRtNodes = new (ELeave) CArrayPtrFlat(4); + } + +CDmAdEngine::CDmAdEngine(MDmAdCallBack* aDmAdCallBack, + MDmAdStoreApi* aStoreApi, + MDmAdDdfApi* aDdfApi, + MDmAdRtNodeDataApi* aRtNodeDataApi) : + iCallBack(aDmAdCallBack), iStoreApi(aStoreApi), iDdfApi(aDdfApi), iRtNodeDataApi(aRtNodeDataApi) + { + TRACE("CDmAdEngine::CDmAdEngine"); + } + +DMAD_EXPORT_C CDmAdEngine::~CDmAdEngine() + { + TRACE("CDmAdEngine::~CDmAdEngine"); + CDmAdRtNode::CleanupOperationDeleteCArrayPtr(iRtNodes); + } + +//=================================================================================================== + +DMAD_EXPORT_C void CDmAdEngine::ChildURIListL(const TDesC8& aUri, const TDesC8& aParentLuid, + const CArrayFix& aPreviousUriSegmentList, + TInt aResultsRef, TInt aStatusRef) + { + TRACE("CDmAdEngine::ChildURIListL"); + + DEBUG_LOG1(_L8("aUri %S"), &aUri); + DEBUG_LOG1(_L8("aParentLuid %S"), &aParentLuid); + DEBUG_LOG2(_L("aResultsRef = %d, aStatusRef = %d"), aResultsRef, aStatusRef); + + + TPtrC8 uri(TDmAdUtil::RemoveDotSlash(aUri)); + TRAPD(err, DoChildUriListL(uri, aParentLuid, aPreviousUriSegmentList, aResultsRef, aStatusRef)); + if (err != KErrNone) + { + iCallBack->SetStatusL(aStatusRef, err); + } + } + +DMAD_EXPORT_C void CDmAdEngine::AddNodeObjectL(const TDesC8& aUri, const TDesC8& aParentLuid, + TInt aStatusRef) + { + TRACE("CDmAdEngine::AddNodeObjectL"); + + DEBUG_LOG1(_L8("aUri %S"), &aUri); + DEBUG_LOG1(_L8("aParentLuid %S"), &aParentLuid); + DEBUG_LOG1(_L("aStatusRef = %d"), aStatusRef); + + TPtrC8 uri(TDmAdUtil::RemoveDotSlash(aUri)); + TRAPD(err, DoAddNodeObjectL(uri, aParentLuid, aStatusRef)); + if (err != KErrNone) + { + iCallBack->SetStatusL(aStatusRef, err); + } + } + +DMAD_EXPORT_C void CDmAdEngine::UpdateLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, + const TDesC8& aObject, const TDesC8& aType, + TInt aStatusRef) + { + TRACE("CDmAdEngine::UpdateLeafObjectL"); + + DEBUG_LOG1(_L8("aUri %S"), &aUri); + DEBUG_LOG1(_L8("aLuid %S"), &aLuid); + DEBUG_LOG1(_L8("aType %S"), &aType); + DEBUG_LOG1(_L("aStatusRef = %d"), aStatusRef); + + + DEBUG_LOG(_L("Object:")); + DEBUG_LOG_HEX(aObject); + + TPtrC8 uri(TDmAdUtil::RemoveDotSlash(aUri)); + TRAPD(err, DoUpdateLeafObjectL(uri, aLuid, aObject, aType, aStatusRef)); + if (err != KErrNone) + { + iCallBack->SetStatusL(aStatusRef, err); + } + } + +DMAD_EXPORT_C void CDmAdEngine::FetchLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, + const TDesC8& aType, TInt aResultsRef, TInt aStatusRef) + { + TRACE("CDmAdEngine::FetchLeafObjectL"); + + DEBUG_LOG1(_L8("aUri %S"), &aUri); + DEBUG_LOG1(_L8("aLuid %S"), &aLuid); + DEBUG_LOG1(_L8("aType %S"), &aType); + DEBUG_LOG2(_L("aResultsRef = %d, aStatusRef = %d"), aResultsRef, aStatusRef); + + TPtrC8 uri(TDmAdUtil::RemoveDotSlash(aUri)); + TRAPD(err, DoFetchLeafObjectL(uri, aLuid, aType, aResultsRef, aStatusRef)); + if (err != KErrNone) + { + iCallBack->SetStatusL(aStatusRef, err); + } + } + +DMAD_EXPORT_C void CDmAdEngine::DeleteObjectL(const TDesC8& aUri, const TDesC8& aLuid, TInt aStatusRef) + { + TRACE("CDmAdEngine::DeleteObjectL"); + DEBUG_LOG1(_L8("aUri %S"), &aUri); + DEBUG_LOG1(_L8("aLuid %S"), &aLuid); + DEBUG_LOG1(_L("aStatusRef = %d"), aStatusRef); + + TPtrC8 uri(TDmAdUtil::RemoveDotSlash(aUri)); + TRAPD(err, DoDeleteObjectL(uri, aLuid, aStatusRef)); + if (err != KErrNone) + { + iCallBack->SetStatusL(aStatusRef, err); + } + } + +DMAD_EXPORT_C void CDmAdEngine::CompleteOutstandingCmdsL() + { + TRACE("CDmAdEngine::CompleteOutstandingCmdsL"); + + TRAPD(err, DoCompleteOutstandingCmdsL()); + if (err != KErrNone) + { + iRtNodes->ResetAndDestroy(); + } + } + +//=================================================================================================== + +void CDmAdEngine::DoChildUriListL(const TDesC8& aUri, const TDesC8& aParentLuid, const CArrayFix& aPreviousUriSegmentList, TInt aResultsRef, TInt aStatusRef) + { + TRACE("CDmAdEngine::DoChildUriListL"); + + CBufBase* currentList; + iDdfApi->BuildChildUriListLC(aUri, aParentLuid, aPreviousUriSegmentList, currentList); + iCallBack->SetResultsL(aResultsRef, *currentList, KNullDesC8); + iCallBack->SetStatusL(aStatusRef, KErrNone); + CleanupStack::PopAndDestroy(); //currentList + } + + +void CDmAdEngine::DoAddNodeObjectL(const TDesC8& aUri, const TDesC8& aParentLuid, TInt aStatusRef) + { + TRACE("CDmAdEngine::DoAddNodeObjectL"); + + if (!iDdfApi->IsNodeRtNodeL(aUri)) + { + iDdfApi->NotRtNodeAddNodeObjectL(aUri, aParentLuid, aStatusRef); + return; + } + + if (FindRtNodeInStoreL(aParentLuid, aUri)) + { + iCallBack->SetStatusL(aStatusRef, KErrAlreadyExists); + return; + } + + CDmAdRtNode* rtNode = FindRtNodeInBuffer(aUri); + if (rtNode != NULL) + { + iCallBack->SetStatusL(aStatusRef, KErrAlreadyExists); + return; + } + + if (SysUtil::FFSSpaceBelowCriticalLevelL(0, 0)) + { + iCallBack->SetStatusL(aStatusRef, KErrDiskFull); + return; + } + + rtNode = CDmAdRtNode::NewL(aUri, aParentLuid, iCallBack, iRtNodeDataApi); + CleanupStack::PushL(rtNode); + + iRtNodeDataApi->SetDefaultSettingsL(rtNode->Data(), aUri); + rtNode->SetSomeLeafAddedToRtNode(ETrue); + + CDmAdCommand* command = CDmAdCommand::NewLC(aUri, aStatusRef, EFalse); + rtNode->AppendCommandL(command); + CleanupStack::Pop(); //command + + iRtNodes->AppendL(rtNode); + CleanupStack::Pop(); // rtNode + + } + +void CDmAdEngine::DoUpdateLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aObject, const TDesC8& aType, TInt aStatusRef) + { + TRACE("CDmAdEngine::DoUpdateLeafObjectL"); + + CDmAdRtNode* rtNode = NULL; + + if (!iDdfApi->IsLeafUnderRtNodeL(aUri)) + { + iDdfApi->NotRtNodeUpdateLeafObjectL(aUri, aLuid, aObject, aType, aStatusRef); + return; + } + + TPtrC8 rtNodeUri(iDdfApi->RtNodeUriForLeafL(aUri)); + if (!FindRtNodeInStoreL(aLuid, rtNodeUri)) + { + rtNode = FindRtNodeInBuffer(rtNodeUri); + if (rtNode == NULL) + { + iCallBack->SetStatusL(aStatusRef, KErrNotFound); + return; + } + rtNode->AddLeafObjectL(aUri, aObject, aStatusRef); + return; + } + + rtNode = RestoreRtNodeInBufferIfNotDoneL(rtNodeUri, aLuid); + rtNode->UpdateLeafObjectL(aUri, aObject, aStatusRef); + } + + +void CDmAdEngine::DoFetchLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aType, TInt aResultsRef, TInt aStatusRef) + { + TRACE("CDmAdEngine::DoFetchLeafObjectL"); + + CBufBase* object = 0; + TInt status = DoFetchLeafObjectL(aUri, aLuid, aType, object); + CleanupStack::PushL(object); + if (status == KErrNone) + { + iCallBack->SetResultsL(aResultsRef, *object, aType); + } + iCallBack->SetStatusL(aStatusRef, status); + CleanupStack::PopAndDestroy(); //object + } + +TInt CDmAdEngine::DoFetchLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aType, CBufBase*& aObject) + { + TRACE("CDmAdEngine::DoFetchLeafObjectL"); + + TInt status = KErrNone; + aObject = 0; + if (!iDdfApi->IsLeafUnderRtNodeL(aUri)) + { + status = iDdfApi->NotRtNodeFetchLeafObjectLC(aUri, aLuid, aType, aObject); + CleanupStack::Pop(); //aObject + return status; + } + + if (aLuid.Length() == 0) + { + aObject = CBufFlat::NewL(32); + status = KErrNotFound; + return status; + } + + TPtrC8 rtNodeUri(TDmAdUtil::RemoveLastUriSeg(aUri)); + CDmAdRtNode* rtNode = RestoreRtNodeInBufferIfNotDoneL(rtNodeUri, aLuid); + iRtNodeDataApi->FetchLeafObjectLC(rtNode->Data(), aUri, aLuid, aObject); + CleanupStack::Pop(); //object + return status; + } + + +void CDmAdEngine::DoDeleteObjectL(const TDesC8& aUri, const TDesC8& aLuid, TInt aStatusRef) + { + TRACE("CDmAdEngine::DoDeleteObjectL"); + + if (aLuid.Length() == 0) + { + if (iDdfApi->IsNodeRtNodeL(aUri)) + { + iCallBack->SetStatusL(aStatusRef, KErrNotFound); + return; + } + iDdfApi->NotRtNodeDeleteObjectL(aUri, aLuid, aStatusRef); + return; + } + + /* + if (IsLeaf(aUri)) + { + DMADERR(DmAdErr::Printf(_L("*** CDmAdEngine::DoDeleteObjectL: %d (line=%d)\n"), KDmAdErr1, __LINE__)); + User::Leave(KErrGeneral); + } + */ + + if (!iDdfApi->IsTopLevelRtNode(aUri)) + { + HBufC8* parentRtNodeLuid = ParentRtNodeLuidForRtNodeLC(aUri); + if (parentRtNodeLuid->Compare(aLuid) == 0) + { + DEBUG_LOG(_L("Not found 1")); + User::Leave(KErrNotFound); + } + DEBUG_LOG(_L("Not found 2")); + User::Leave(KErrNotFound); + CleanupStack::PopAndDestroy(); //parentRtNodeLuid + } + + iStoreApi->DeleteRtNodeL(aLuid, aUri); + iCallBack->SetStatusL(aStatusRef, KErrNone); + } + + +void CDmAdEngine::DoCompleteOutstandingCmdsL() + { + TRACE("CDmAdEngine::DoCompleteOutstandingCmdsL"); + + SaveRtNodesL(); + } + +//=================================================================================================== + +CDmAdRtNode* CDmAdEngine::FindRtNodeInBuffer(const TDesC8& aUri) + { + TRACE("CDmAdEngine::FindRtNodeInBuffer"); + + CDmAdRtNode* rtNode = NULL; + TInt countRtNodes = iRtNodes->Count(); + for (TInt i=0; i < countRtNodes; i++) + { + if (iRtNodes->At(i)->Uri().Compare(aUri) == 0) + { + rtNode = iRtNodes->At(i); + break; + } + } + return rtNode; + } + +CDmAdRtNode* CDmAdEngine::FindRtNodeInBufferByLuid(const TDesC8& aLuid, const TDesC8& aUri) + { + TRACE("CDmAdEngine::FindRtNodeInBufferByLuid"); + + CDmAdRtNode* rtNode = NULL; + TInt countRtNodes = iRtNodes->Count(); + for (TInt i=0; i < countRtNodes; i++) + { + if (iRtNodes->At(i)->Luid().Compare(aLuid) == 0 && + iRtNodes->At(i)->AreUriTypesSame(aUri)) + { + rtNode = iRtNodes->At(i); + break; + } + } + return rtNode; + } + +CDmAdRtNode* CDmAdEngine::RestoreRtNodeInBufferIfNotDoneL(const TDesC8& aUri, const TDesC8& aLuid) + { + TRACE("CDmAdEngine::RestoreRtNodeInBufferIfNotDoneL"); + + CDmAdRtNode* rtNode = FindRtNodeInBufferByLuid(aLuid, aUri); + if (rtNode == NULL) + { + rtNode = FetchRtNodeInBufferL(aUri, aLuid); + } + return rtNode; + } + +CDmAdRtNode* CDmAdEngine::FetchRtNodeInBufferL(const TDesC8& aUri, const TDesC8& aLuid) + { + TRACE("CDmAdEngine::FetchRtNodeInBufferL"); + + CDmAdRtNode* rtNode = CDmAdRtNode::NewL(aUri, aLuid, iCallBack, iRtNodeDataApi); + CleanupStack::PushL(rtNode); + + iStoreApi->FetchRtNodeL(*rtNode); + + iRtNodes->AppendL(rtNode); + CleanupStack::Pop(); //rtNode + return rtNode; + } + +void CDmAdEngine::CompleteCommandsL(CDmAdRtNode& aRtNode, TInt aStatus) + { + TRACE("CDmAdEngine::CompleteCommandsL"); + + TInt countCommands = aRtNode.Commands()->Count(); + for (TInt cmd=0; cmd < countCommands; cmd++) + { + CDmAdCommand* command = aRtNode.Commands()->At(cmd); + if (command->Status() == KErrNone) + { + if (!command->IsLeaf()) + { + if (aStatus == MSmlDmAdapter::EOk) + { + iCallBack->SetMappingL(aRtNode.Uri(), aRtNode.Luid()); + } + } + iCallBack->SetStatusL(command->StatusRef(), aStatus); + } + else + { + iCallBack->SetStatusL(command->StatusRef(), command->Status()); + } + } + } + +void CDmAdEngine::CompleteCommandsL(CArrayPtr& aRtNodes, TInt aStatus) + { + TRACE("CDmAdEngine::CompleteCommandsL"); + + for (TInt i=0; i < aRtNodes.Count(); i++) + { + CDmAdRtNode* rtNode = aRtNodes.At(i); + CompleteCommandsL(*rtNode, aStatus); + } + } + +void CDmAdEngine::BuildTopLevelRtNodesListLC(CArrayPtr* aRtNodes, + CArrayPtr*& aTopLevelRtNodes) + { + CArrayPtr* rtNodesList; + rtNodesList = new (ELeave) CArrayPtrFlat(4); + CleanupStack::PushL(TCleanupItem(CDmAdRtNode::CleanupOperationDeleteCArrayPtr, + rtNodesList)); + + for (TInt i=0; i < aRtNodes->Count(); i++) + { + CDmAdRtNode* rtNode = aRtNodes->At(i); + if (iDdfApi->IsTopLevelRtNode(rtNode->Uri())) + { + rtNodesList->AppendL(rtNode); + aRtNodes->Delete(i); + i--; + } + } + + aTopLevelRtNodes = rtNodesList; + } + +void CDmAdEngine::BuildChildRtNodesListLC(CArrayPtr* aRtNodes, + const TDesC8& aSomeParentUri, + CArrayPtr*& aChildRtNodes) + { + CArrayPtr* rtNodesList; + rtNodesList = new (ELeave) CArrayPtrFlat(4); + CleanupStack::PushL(TCleanupItem(CDmAdRtNode::CleanupOperationDeleteCArrayPtr, + rtNodesList)); + + for (TInt i=0; i < aRtNodes->Count(); i++) + { + CDmAdRtNode* rtNode = aRtNodes->At(i); + if (rtNode->IsSomeChild(aSomeParentUri)) + { + rtNodesList->AppendL(rtNode); + aRtNodes->Delete(i); + i--; + } + } + + aChildRtNodes = rtNodesList; + } + +void CDmAdEngine::SaveRtNodesL(void) + { + TRACE("CDmAdEngine::SaveRtNodesL"); + + CArrayPtr* topLevelRtNodes; + BuildTopLevelRtNodesListLC(iRtNodes, topLevelRtNodes); + + TInt countRtNodes; + countRtNodes = topLevelRtNodes->Count(); + TInt i; + for (i=0; i < countRtNodes; i++) + { + CDmAdRtNode* rtNode = topLevelRtNodes->At(i); + CArrayPtr* childRtNodes; + BuildChildRtNodesListLC(iRtNodes, rtNode->Uri(), childRtNodes); + + TRAPD(err, iStoreApi->SaveTopLevelRtNodeL(*rtNode, *childRtNodes)); + CompleteCommandsL(*rtNode, err); + CompleteCommandsL(*childRtNodes, err); + + CleanupStack::PopAndDestroy(); //childRtNodes + } + CleanupStack::PopAndDestroy(); //topLevelRtNodes + + //child rtNodes without top level RtNode + countRtNodes = iRtNodes->Count(); + for (i=0; i < countRtNodes; i++) + { + CDmAdRtNode* rtNode = iRtNodes->At(i); + TInt err = KErrNone; + if (!rtNode->IsJustFetched()) + { + TRAP(err, iStoreApi->SaveChildLevelRtNodeL(*rtNode)); + } + CompleteCommandsL(*rtNode, err); + } + iRtNodes->ResetAndDestroy(); + } + +TBool CDmAdEngine::FindRtNodeInStoreL(const TDesC8& aLuid, const TDesC8& aUri) + { + TRACE("CDmAdEngine::FindRtNodeInStoreL"); + + TBool ret = EFalse; + + if (iDdfApi->IsTopLevelRtNode(aUri)) + { + ret = iStoreApi->FindRtNodeL(aLuid, aUri); + } + else + { + HBufC8* parentRtNodeLuid = ParentRtNodeLuidForRtNodeLC(aUri); + if (parentRtNodeLuid->Compare(aLuid) == 0) + { + ret = EFalse; + } + else + { + ret = iStoreApi->FindRtNodeL(aLuid, aUri); + } + CleanupStack::PopAndDestroy(); //parentRtNodeLuid + } + + return ret; + } + +HBufC8* CDmAdEngine::ParentRtNodeLuidForRtNodeLC(const TDesC8& aUri) + { + HBufC8* parentRtNodeUri = iDdfApi->ParentRtNodeUriForRtNodeLC(aUri); + HBufC8* parentRtNodeLuid = iCallBack->GetLuidAllocL(*parentRtNodeUri); + CleanupStack::PopAndDestroy(); // parentRtNodeUri + CleanupStack::PushL(parentRtNodeLuid); + return parentRtNodeLuid; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/src/dmadenginenewapi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/src/dmadenginenewapi.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,259 @@ +/* +* Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Device Management Adapter Engine. +* +*/ + + +#include + +#include "dmadengine.h" +#include "dmadutil.h" +#include "vpnlogger.h" + + +DMAD_EXPORT_C void CDmAdEngine::ChildURIListL(const TDesC& /*aUri*/, + const TDesC& /*aParentLuid*/, + const CArrayFix& /*aPreviousUriSegmentList*/, + const TInt /*aResultsRef*/, + const TInt /*aStatusRef*/) + { + TRACE("CDmAdEngine::ChildURIListL"); + DEBUG_LOG(_L("Empty method")); + } + +DMAD_EXPORT_C void CDmAdEngine::AddNodeObjectL(const TDesC& /*aUri*/, + const TDesC& /*aParentLuid*/, + const TInt /*aStatusRef*/) + { + TRACE("CDmAdEngine::AddNodeObjectL"); + DEBUG_LOG(_L("Empty method")); + } + +DMAD_EXPORT_C void CDmAdEngine::AddLeafObjectL(const TDesC& /*aUri*/, + const TDesC& /*aParentLuid*/, + const TDesC8& /*aObject*/, + const TDesC& /*aType*/, + const TInt /*aStatusRef*/) + { + TRACE("CDmAdEngine::AddLeafObjectL"); + DEBUG_LOG(_L("Empty method")); + } + +DMAD_EXPORT_C void CDmAdEngine::UpdateLeafObjectL(const TDesC& /*aUri*/, + const TDesC& /*aLuid*/, + const TDesC8& /*aObject*/, + const TDesC& /*aType*/, + const TInt /*aStatusRef*/) + { + TRACE("CDmAdEngine::UpdateLeafObjectL"); + DEBUG_LOG(_L("Empty method")); + } + +DMAD_EXPORT_C void CDmAdEngine::FetchLeafObjectL(const TDesC& /*aUri*/, + const TDesC& /*aLuid*/, + const TDesC& /*aType*/, + const TInt /*aResultsRef*/, + const TInt /*aStatusRef*/) + { + TRACE("CDmAdEngine::FetchLeafObjectL"); + DEBUG_LOG(_L("Empty method")); + } + +DMAD_EXPORT_C void CDmAdEngine::DeleteObjectL(const TDesC& /*aUri*/, + const TDesC& /*aLuid*/, + const TInt /*aStatusRef*/) + { + TRACE("CDmAdEngine::DeleteObjectL"); + DEBUG_LOG(_L("Empty method")); + } + +DMAD_EXPORT_C void CDmAdEngine::EndMessageL() + { + TRACE("CDmAdEngine::EndMessageL"); + DEBUG_LOG(_L("Empty method")); + } + +//=================================================================================================== + +DMAD_EXPORT_C void CDmAdEngine::UpdateLeafObjectL(const TDesC8& /*aUri*/, + const TDesC8& /*aLuid*/, + RWriteStream*& /*aStream*/, + const TDesC8& /*aType*/, + TInt aStatusRef) + { + TRACE("CDmAdEngine::UpdateLeafObjectL"); + DEBUG_LOG(_L("Unsupported stream method called")); + + iCallBack->SetStatusL(aStatusRef, KErrGeneral); + } + +DMAD_EXPORT_C void CDmAdEngine::FetchLeafObjectSizeL(const TDesC8& aUri, + const TDesC8& aLuid, + const TDesC8& aType, + TInt aResultsRef, + TInt aStatusRef) + { + TRACE("CDmAdEngine::FetchLeafObjectSizeL"); + + DEBUG_LOG1(_L8("aUri %S"), &aUri); + DEBUG_LOG1(_L8("aLuid %S"), &aLuid); + DEBUG_LOG1(_L8("aType %S"), &aType); + DEBUG_LOG2(_L("aResultsRef = %d, aStatusRef = %d"), aResultsRef, aStatusRef); + + TPtrC8 uri(TDmAdUtil::RemoveDotSlash(aUri)); + TInt status = KErrNone; + CBufBase* object = 0; + TRAPD(err, status = DoFetchLeafObjectL(uri, aLuid, aType, object)); + if (err != KErrNone) + { + iCallBack->SetStatusL(aStatusRef, err); + return; + } + if (status != KErrNone) + { + delete object; + iCallBack->SetStatusL(aStatusRef, status); + return; + } + + CleanupStack::PushL(object); + TInt objSizeInBytes = object->Size(); + HBufC8* sizeBuf = TDmAdUtil::IntToDes8LC(objSizeInBytes); + object->Reset(); + object->InsertL(0, *sizeBuf); + + iCallBack->SetResultsL(aResultsRef, *object, aType); + iCallBack->SetStatusL(aStatusRef, status); + CleanupStack::PopAndDestroy(2); //sizeBuf, object + } + +DMAD_EXPORT_C void CDmAdEngine::ExecuteCommandL(const TDesC8& aUri, + const TDesC8& aLuid, + const TDesC8& aArgument, + const TDesC8& aType, + TInt aStatusRef) + { + TRACE("CDmAdEngine::ExecuteCommandL"); + + DEBUG_LOG1(_L8("aUri %S"), &aUri); + DEBUG_LOG1(_L8("aLuid %S"), &aLuid); + + DEBUG_LOG(_L("Argument:")); + DEBUG_LOG_HEX(aArgument); + + DEBUG_LOG1(_L8("aType %S"), &aType); + DEBUG_LOG1(_L("aStatusRef = %d"), aStatusRef); + + if (!iDdfApi->IsLeafUnderRtNodeL(aUri)) + { + iDdfApi->NotRtNodeUpdateLeafObjectL(aUri, aLuid, aArgument, aType, aStatusRef); + } + else + { + iCallBack->SetStatusL(aStatusRef, KErrNotFound); + } + } + +DMAD_EXPORT_C void CDmAdEngine::ExecuteCommandL(const TDesC8& /*aUri*/, + const TDesC8& /*aLuid*/, + RWriteStream*& /*aStream*/, + const TDesC8& /*aType*/, + TInt aStatusRef) + { + TRACE("CDmAdEngine::ExecuteCommandL"); + DEBUG_LOG(_L("Unsupported stream method called")); + + iCallBack->SetStatusL(aStatusRef, KErrGeneral); + } + +DMAD_EXPORT_C void CDmAdEngine::CopyCommandL(const TDesC8& aTargetUri, + const TDesC8& aTargetLuid, + const TDesC8& aSourceUri, + const TDesC8& aSourceLuid, + const TDesC8& aType, + TInt aStatusRef) + { + TRACE("CDmAdEngine::CopyCommandL"); + + DEBUG_LOG1(_L8("aTargetUri = %S"), &aTargetUri); + DEBUG_LOG1(_L8("aTargetLuid = %S"), &aTargetLuid); + DEBUG_LOG1(_L8("aSourceUri = %S"), &aSourceUri); + DEBUG_LOG1(_L8("aSourceLuid = %S"), &aSourceLuid); + DEBUG_LOG1(_L8("aType = %S"), &aType); + DEBUG_LOG1(_L("aStatusRef = %d"), aStatusRef); + + + TInt err = KErrNone; + TPtrC8 sourceUri(TDmAdUtil::RemoveDotSlash(aSourceUri)); + TInt status = KErrNone; + CBufBase* object = 0; + TRAP(err, status = DoFetchLeafObjectL(sourceUri, aSourceLuid, aType, object)); + if (err != KErrNone) + { + iCallBack->SetStatusL(aStatusRef, err); + return; + } + if (status != KErrNone) + { + delete object; + iCallBack->SetStatusL(aStatusRef, status); + return; + } + + CleanupStack::PushL(object); + + DEBUG_LOG(_L("object:")); + DEBUG_LOG_HEX(object->Ptr(0)); + + TPtrC8 targetUri(TDmAdUtil::RemoveDotSlash(aTargetUri)); + TRAP(err, DoUpdateLeafObjectL(targetUri, aTargetLuid, object->Ptr(0), aType, aStatusRef)); + if (err != KErrNone) + { + iCallBack->SetStatusL(aStatusRef, err); + } + + CleanupStack::PopAndDestroy(); // object + } + +DMAD_EXPORT_C void CDmAdEngine::StartAtomicL() + { + TRACE("CDmAdEngine::StartAtomicL"); + DEBUG_LOG(_L("Empty method")); + } + +DMAD_EXPORT_C void CDmAdEngine::CommitAtomicL() + { + TRACE("CDmAdEngine::CommitAtomicL"); + DEBUG_LOG(_L("Empty method")); + } + +DMAD_EXPORT_C void CDmAdEngine::RollbackAtomicL() + { + TRACE("CDmAdEngine::RollbackAtomicL"); + DEBUG_LOG(_L("Empty method")); + } + +DMAD_EXPORT_C TBool CDmAdEngine::StreamingSupport(TInt& /*aItemSize*/) + { + TRACE("CDmAdEngine::StreamingSupport"); + return EFalse; + } + +DMAD_EXPORT_C void CDmAdEngine::StreamCommittedL() + { + TRACE("CDmAdEngine::StreamCommittedL"); + DEBUG_LOG(_L("Empty method")); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/src/dmadrtnode.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/src/dmadrtnode.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,169 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CDmAdRtNode. +* +*/ + + +#include "DmAdRtNode.h" +#include "dmadcallback.h" +#include "dmadcommand.h" +#include "dmadutil.h" +#include "vpnlogger.h" + +DMAD_EXPORT_C CDmAdRtNode* CDmAdRtNode::NewL(const TDesC8& aUri, const TDesC8& aLuid, MDmAdCallBack* aCallBack, MDmAdRtNodeDataApi* aRtNodeDataApi) + { + TRACE("CDmAdRtNode::NewL"); + + CDmAdRtNode *self = new (ELeave) CDmAdRtNode(aRtNodeDataApi); + CleanupStack::PushL(self); + self->ConstructL(aUri, aLuid, aCallBack); + CleanupStack::Pop(); // self + return self; + } + +void CDmAdRtNode::ConstructL(const TDesC8& aUri, const TDesC8& aLuid, MDmAdCallBack* aCallBack) + { + TRACE("CDmAdRtNode::ConstructL"); + + DEBUG_LOG1(_L8("aUri: %S"), &aUri); + DEBUG_LOG(_L("aLuid:")); + DEBUG_LOG_HEX(aLuid); + + iCommands = new (ELeave) CArrayPtrFlat(4); + iUri = aUri.AllocL(); + iLuid = aLuid.AllocL(); + iData = iRtNodeDataApi->CreateDmAdRtNodeDataL(aUri, aCallBack); + } + +CDmAdRtNode::CDmAdRtNode(MDmAdRtNodeDataApi* aRtNodeDataApi) + : iRtNodeDataApi(aRtNodeDataApi), iSomeLeafAddedToRtNode(EFalse), iJustFetched(ETrue) + { + TRACE("CDmAdRtNode::CDmAdRtNode"); + } + +DMAD_EXPORT_C CDmAdRtNode::~CDmAdRtNode() + { + TRACE("CDmAdRtNode::~CDmAdRtNode"); + + CDmAdCommand::CleanupOperationDeleteCArrayPtr(iCommands); + delete iUri; + delete iLuid; + iRtNodeDataApi->DeleteDmAdRtNodeData(iData); + } + +DMAD_EXPORT_C TPtrC8 CDmAdRtNode::Uri(void) const + { + TRACE("CDmAdRtNode::Uri"); + + __ASSERT_ALWAYS(iUri != NULL, User::Invariant()); + + TPtrC8 ret(*iUri); + return ret; + } + +DMAD_EXPORT_C TPtrC8 CDmAdRtNode::Luid(void) const + { + TRACE("CDmAdRtNode::Luid"); + + __ASSERT_ALWAYS(iLuid != NULL, User::Invariant()); + + TPtrC8 ret(*iLuid); + return ret; + } + +DMAD_EXPORT_C void CDmAdRtNode::SetLuidL(const TDesC8& aLuid) + { + TRACE("CDmAdRtNode::SetLuidL"); + + DEBUG_LOG1(_L8("Node uri: %S"), iUri); + DEBUG_LOG(_L("aLuid:")); + DEBUG_LOG_HEX(aLuid); + + __ASSERT_ALWAYS(aLuid.Length() > 0, User::Invariant()); + + + delete iLuid; + iLuid = NULL; + + iLuid = aLuid.AllocL(); + } + + +void CDmAdRtNode::CleanupOperationDeleteCArrayPtr(TAny* aPtr) + { + __ASSERT_ALWAYS(aPtr != NULL, User::Invariant()); + + CArrayPtr* array = REINTERPRET_CAST(CArrayPtr*,aPtr); + array->ResetAndDestroy(); + delete array; + } + + +void CDmAdRtNode::AppendCommandL(CDmAdCommand* aCommand) + { + TRACE("CDmAdRtNode::AppendCommandL"); + + iCommands->AppendL(aCommand); + iJustFetched = EFalse; + } + +void CDmAdRtNode::AddLeafObjectL(const TDesC8& aUri, const TDesC8& aObject, TInt aStatusRef) + { + TRACE("CDmAdRtNode::AddLeafObjectL"); + + CDmAdCommand* command = CDmAdCommand::NewLC(aUri, aStatusRef, ETrue); + + iRtNodeDataApi->UpdateLeafDataL(iData, aUri, aObject); + iSomeLeafAddedToRtNode = ETrue; + + AppendCommandL(command); + CleanupStack::Pop(); //command + } + +void CDmAdRtNode::UpdateLeafObjectL(const TDesC8& aUri, const TDesC8& aObject, TInt aStatusRef) + { + TRACE("CDmAdRtNode::UpdateLeafObjectL"); + + CDmAdCommand* command = CDmAdCommand::NewLC(aUri, aStatusRef, ETrue); + + iRtNodeDataApi->UpdateLeafDataL(iData, aUri, aObject); + + AppendCommandL(command); + CleanupStack::Pop(); //command + } + +TBool CDmAdRtNode::IsSomeChild(const TDesC8& aSomeParentUri) const + { + TRACE("CDmAdRtNode::IsSomeChild"); + + TPtrC8 someParentUri(TDmAdUtil::RemoveDotSlash(aSomeParentUri)); + TPtrC8 uri(TDmAdUtil::RemoveDotSlash(*iUri)); + if (uri.Find(someParentUri) == 0) + { + return ETrue; + } + else + { + return EFalse; + } + } + +TBool CDmAdRtNode::AreUriTypesSame(const TDesC8& aUri) + { + TRACE("CDmAdRtNode::AreUriTypesSameL"); + + return iRtNodeDataApi->AreUriTypesSame(iData, aUri); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadengine/src/dmadutil.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadengine/src/dmadutil.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,502 @@ +/* +* Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of TDmAdUtil. +* +*/ + + + +#include +#include "dmadutil.h" +#include "vpnlogger.h" + +//----------------------------------------------------------------------- + +DMAD_EXPORT_C TInt TDmAdUtil::DesToInt(const TDesC& aDes) + { + if (aDes.Length() == 0) + { + return 0; + } + TLex16 lex(aDes); + TInt value = 0; + if (lex.Val(value) != KErrNone) + { + ; + } + return value; + } + +DMAD_EXPORT_C TInt TDmAdUtil::DesToInt(const TDesC8& aDes) + { + if (aDes.Length() == 0) + { + return 0; + } + TLex8 lex(aDes); + TInt value = 0; + if (lex.Val(value) != KErrNone) + { + ; + } + return value; + } + +DMAD_EXPORT_C HBufC* TDmAdUtil::IntToDesLC(const TInt aInt) + { + HBufC* buf = HBufC::NewLC(10); //10 = max length of 32bit integer + TPtr ptrBuf = buf->Des(); + ptrBuf.Num(aInt); + return buf; + } + +DMAD_EXPORT_C HBufC8* TDmAdUtil::IntToDes8LC(const TInt aInt) + { + HBufC8* buf = HBufC8::NewLC(10); //10 = max length of 32bit integer + TPtr8 ptrBuf = buf->Des(); + ptrBuf.Num(aInt); + return buf; + } + +DMAD_EXPORT_C HBufC* TDmAdUtil::IntToDesLC(const TInt32 aInt32) + { + return IntToDesLC((TInt)aInt32); + } + +DMAD_EXPORT_C HBufC8* TDmAdUtil::IntToDes8LC(const TInt32 aInt32) + { + return IntToDes8LC((TInt)aInt32); + } + +//----------------------------------------------------------------------- + +DMAD_EXPORT_C TUint TDmAdUtil::DesToUint(const TDesC& aDes) + { + if (aDes.Length() == 0) + { + return 0; + } + TLex16 lex(aDes); + TUint value = 0; + if (lex.Val(value) != KErrNone) + { + ; + } + return value; + } + +DMAD_EXPORT_C TUint TDmAdUtil::DesToUint(const TDesC8& aDes) + { + if (aDes.Length() == 0) + { + return 0; + } + TLex8 lex(aDes); + TUint value = 0; + if (lex.Val(value) != KErrNone) + { + ; + } + return value; + } + +DMAD_EXPORT_C HBufC* TDmAdUtil::IntToDesLC(const TUint aUint) + { + HBufC* buf = HBufC::NewLC(10); //10 = max length of 32bit integer + TPtr ptrBuf = buf->Des(); + ptrBuf.Num(aUint); + return buf; + } + +DMAD_EXPORT_C HBufC8* TDmAdUtil::IntToDes8LC(const TUint aUint) + { + HBufC8* buf = HBufC8::NewLC(10); //10 = max length of 32bit integer + TPtr8 ptrBuf = buf->Des(); + ptrBuf.Num(aUint); + return buf; + } + +DMAD_EXPORT_C HBufC* TDmAdUtil::IntToDesLC(const TUint32 aUint32) + { + return IntToDesLC((TUint)aUint32); + } + +DMAD_EXPORT_C HBufC8* TDmAdUtil::IntToDes8LC(const TUint32 aUint32) + { + return IntToDes8LC((TUint)aUint32); + } + +//----------------------------------------------------------------------- + +DMAD_EXPORT_C TPtrC8 TDmAdUtil::LastUriSeg(const TDesC8& aUri) + { + TInt i; + for (i=aUri.Length()-1; i>=0; i--) + { + if (aUri[i] == '/') + { + break; + } + } + if (i==0) + { + return aUri; + } + else + { + return aUri.Mid(i+1); + } + } + +DMAD_EXPORT_C TPtrC8 TDmAdUtil::FirstUriSeg(const TDesC8& aUri) + { + TInt i; + TBool found = EFalse; + for (i=0; i=0; i--) + { + if (aUri[i] == '/') + { + break; + } + } + return aUri.Left(i); + } + +DMAD_EXPORT_C TInt TDmAdUtil::NumOfURISegs(const TDesC8& aUri) + { + TPtrC8 uri(TDmAdUtil::RemoveDotSlash(aUri)); + TInt numOfURISegs = 1; + for (TInt i=0; iDes(); + uriDesc.Copy(aUriPath); + uriDesc.Append(KDmAdSeparator); + uriDesc.Append(aUriSeg); + return uri; + } + +DMAD_EXPORT_C MSmlDmAdapter::TError TDmAdUtil::MapStatusCode(TInt aStatus) + { + TRACE("TDmAdUtil::MapStatusCode"); + + + MSmlDmAdapter::TError dmStatus; + if (aStatus == KErrNone) + { + dmStatus = MSmlDmAdapter::EOk; + } + else if (aStatus == KErrNotFound) + { + dmStatus = MSmlDmAdapter::ENotFound; + } + else if (aStatus == KErrCorrupt) + { + dmStatus = MSmlDmAdapter::EInvalidObject; + } + else if (aStatus == KErrAlreadyExists) + { + dmStatus = MSmlDmAdapter::EAlreadyExists; + } + else if (aStatus == KErrTooBig) + { + dmStatus = MSmlDmAdapter::ETooLargeObject; + } + else if (aStatus == KErrDiskFull) + { + dmStatus = MSmlDmAdapter::EDiskFull; + } + /* + ERollbackFailed, + EObjectInUse, + ENoMemory, + ECommitOK, + ERollbackOK, + ECommitFailed + */ + else + { + dmStatus = MSmlDmAdapter::EError; + } + return dmStatus; + } + +DMAD_EXPORT_C void TDmAdUtil::ParseUriLC(const TDesC8& aUri, CArrayFix*& aUriSegList) + { + TPtrC8 uri(TDmAdUtil::RemoveDotSlash(aUri)); + + CArrayFix* uriSegList; + uriSegList = new (ELeave) CArrayFixFlat(8); + CleanupStack::PushL(uriSegList); + + TPtrC8 seg; + TPtrC8 curr(uri); + + while (curr.Length() > 0) + { + TInt offset = curr.Locate('/'); + if (offset == KErrNotFound) + { + seg.Set(curr); + curr.Set(KNullDesC8); + } + else + { + seg.Set(curr.Left(offset)); + TInt rightLth = curr.Length() - offset - 1; + if (rightLth <= 0) + { + DEBUG_LOG(_L("TDmAdUtil::ParseUriLC: corrupted uri")); + DEBUG_LOG1(_L8("URI: %S"), &aUri); + + User::Leave(KErrGeneral); + } + curr.Set(curr.Right(rightLth)); + } + uriSegList->AppendL(seg); + } + + aUriSegList = uriSegList; + } + +DMAD_EXPORT_C HBufC8* TDmAdUtil::LuidTo8L(const TDesC& aLuid16) + { + HBufC8* luid8 = HBufC8::NewL(aLuid16.Length()); + luid8->Des().Copy(aLuid16); + return luid8; + } + +DMAD_EXPORT_C HBufC* TDmAdUtil::LuidTo16L(const TDesC8& aLuid8) + { + HBufC* luid16 = HBufC::NewL(aLuid8.Length()); + luid16->Des().Copy(aLuid8); + return luid16; + } + +//----------------------------------------------------------------------- + +DMAD_EXPORT_C void TDmAdUtil::FillNodeInfoL(MSmlDmDDFObject& aNode, + TSmlDmAccessTypes aAccTypes, + MSmlDmDDFObject::TOccurence aOccurrence, + MSmlDmDDFObject::TScope aScope, + MSmlDmDDFObject::TDFFormat aFormat, + const TDesC8& aDescription, + TBool aObjectGroup, + const TDesC8& aMimeType) +{ + aNode.SetAccessTypesL(aAccTypes); + aNode.SetOccurenceL(aOccurrence); + aNode.SetScopeL(aScope); + aNode.SetDFFormatL(aFormat); + + if (aMimeType.Length() > 0) + { + aNode.AddDFTypeMimeTypeL(aMimeType); + } + + aNode.SetDescriptionL(aDescription); + + (void)aObjectGroup; + } + +DMAD_EXPORT_C MSmlDmDDFObject& TDmAdUtil::AddChildObjectL(MSmlDmDDFObject& aNode, const TDesC8& aNodeName) + { + if (aNodeName.Length() == 0) + { + MSmlDmDDFObject& object = aNode.AddChildObjectGroupL(); + return object; + } + else + { + MSmlDmDDFObject& object = aNode.AddChildObjectL(aNodeName); + return object; + } + } + +DMAD_EXPORT_C HBufC8* TDmAdUtil::BuildLocallyCreatedRtNodeUriSegLC(TInt& aLargest) + { + ++aLargest; + HBufC8* number = TDmAdUtil::IntToDes8LC(aLargest); + HBufC8* uri = HBufC8::NewL(KDmAdLocallyCreatedRtNodeUriSegPrefix().Length() + number->Length()); + uri->Des().Copy(KDmAdLocallyCreatedRtNodeUriSegPrefix); + uri->Des().Append(*number); + CleanupStack::PopAndDestroy(); // number + CleanupStack::PushL(uri); + return uri; + } + +TInt TDmAdUtil::FindLargestLocallyCreated(const CArrayFix& aPreviousUriSegmentList) + { + TRACE("TDmAdUtil::FindLargestLocallyCreated"); + TInt largest = 0; + for (TInt i=0; i < aPreviousUriSegmentList.Count(); i++) + { + const TSmlDmMappingInfo& mappingInfo = aPreviousUriSegmentList.At(i); + if (mappingInfo.iURISeg.Find(KDmAdLocallyCreatedRtNodeUriSegPrefix) == 0) + { + TPtrC8 numberPart(mappingInfo.iURISeg.Mid(KDmAdLocallyCreatedRtNodeUriSegPrefix().Length())); + TInt number = TDmAdUtil::DesToInt(numberPart); + if (number > largest) + { + largest = number; + } + } + } + return largest; + } + + +void PointerArrayCleanup(TAny* item) + { + RPointerArray* a = static_cast*>(item); + a->ResetAndDestroy(); + a->Close(); + } + + +#define DMAD_DUMP_PREVIOUS_URI_SEGMENT_LIST + +DMAD_EXPORT_C void TDmAdUtil::BuildRtNodeChildUriListL(MDmAdCallBack* aDmAdCallBack, + MDmAdStoreApi* aStoreApi, + const TDesC8& aUri, + const TDesC8& aParentLuid, + const CArrayFix& aPreviousUriSegmentList, + CBufBase& aCurrentList) + { +#ifdef DMAD_DUMP_PREVIOUS_URI_SEGMENT_LIST + DEBUG_LOG(_L("BuildRtNodeChildUriListL:")); + { + for (TInt i=0; i < aPreviousUriSegmentList.Count(); i++) + { + const TSmlDmMappingInfo& mappingInfo = aPreviousUriSegmentList.At(i); + + DEBUG_LOG1(_L("entry %d:"), i); + DEBUG_LOG1(_L8("Uri: %S"), &(mappingInfo.iURISeg)); + DEBUG_LOG_HEX(mappingInfo.iURISegLUID); + + } + } +#endif + + RPointerArray luidList; + CleanupStack::PushL(TCleanupItem(PointerArrayCleanup, &luidList)); + + aStoreApi->LuidListL(aUri, aParentLuid, luidList); + + + // Finds largest number used in cli named nodes. + TInt largest = FindLargestLocallyCreated(aPreviousUriSegmentList); + DEBUG_LOG1(_L("largest is cli%d"), largest); + + TInt countLuidList = luidList.Count(); + for (TInt j=0; j < countLuidList; j++) + { + const HBufC8* luidElem = luidList[j]; + + HBufC8* uriSeg = 0; + + //Tries to find the luid from the aPreviousUriSegmentList + for (TInt i=0; i < aPreviousUriSegmentList.Count(); i++) + { + const TSmlDmMappingInfo& mappingInfo = aPreviousUriSegmentList.At(i); + + if (mappingInfo.iURISegLUID.Compare(*luidElem) == 0) + { + uriSeg = mappingInfo.iURISeg.AllocLC(); + break; + } + } + + if (uriSeg == 0) + { + //Uri was not found from the aPreviousUriSegmentList + uriSeg = BuildLocallyCreatedRtNodeUriSegLC(largest); + + DEBUG_LOG2(_L8("uriSeg %S, largest %d"), uriSeg, largest); + + HBufC8* wholeUri = TDmAdUtil::BuildUriLC(aUri, *uriSeg); + aDmAdCallBack->SetMappingL(*wholeUri, *luidElem); + CleanupStack::PopAndDestroy(); //wholeUri + } + + //If this is not the first element, inserts slash at the beginning + //of the result list. + if (j > 0) + { + aCurrentList.InsertL(aCurrentList.Size(), KDmAdSeparator); + } + aCurrentList.InsertL(aCurrentList.Size(), *uriSeg); + + CleanupStack::PopAndDestroy(); // uriSeg + } + + CleanupStack::PopAndDestroy(); //luidList + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/BWINS/DMADTESTU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/BWINS/DMADTESTU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?StartTest@TDmAdStartTest@@SAXXZ @ 1 NONAME ; public: static void __cdecl TDmAdStartTest::StartTest(void) + diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/data/1020699c.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/data/1020699c.rss Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Resource definitions for dmadipsecvpn. +* +*/ + +CHARACTER_SET UTF8 + +/* +* ============================================================================ +* Name : 1020699C.rss +* ============================================================================ +*/ + +#include + +#define KSmlDMInterfaceUid 0x102018B4 +#include "dmadadapterimplconst.h" + +RESOURCE REGISTRY_INFO theRegistryInfo + { + dll_uid = KDmAdDllUid; //The DLL's 3rd UID. + interfaces = + { + INTERFACE_INFO + { + interface_uid = KSmlDMInterfaceUid; // DM interface UID + implementations = + { + IMPLEMENTATION_INFO + { + implementation_uid = KDmAdImplUid; + version_no = 1; + display_name = ""; + default_data = ""; + opaque_data = ""; + } + }; + } + }; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file provides the information required for building the module. +* +*/ + + + +#include + +PRJ_MMPFILES +dmadipsecvpn.mmp + +PRJ_TESTMMPFILES diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/group/dmadipsecvpn.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/group/dmadipsecvpn.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project dmadipsecvpn +* +*/ + + + +#include + +TARGET dmadipsecvpn.dll +TARGETTYPE PLUGIN +UID 0x10009D8D 0x1020699C + +CAPABILITY CAP_ECOM_PLUGIN +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE dmadadapter.cpp +SOURCE dmadddf.cpp +SOURCE DmAdRtNodeData.cpp +SOURCE dmadrtnodedataapi.cpp +SOURCE DmAdStore.cpp +SOURCE dmadstorevpnapcmm.cpp +SOURCE dmadeventlog.cpp +SOURCE eventlogger.cpp + +START RESOURCE ../data/1020699c.rss +TARGET dmadipsecvpn.rsc +END + +USERINCLUDE ../inc +USERINCLUDE ../../dmadengine/inc +USERINCLUDE ../../eventviewer/inc +USERINCLUDE ../../../vpnapiimpl/inc +USERINCLUDE ../../eventmediatorapi/inc +USERINCLUDE ../../vpncommon/inc +USERINCLUDE ../../vpnmanager/inc + +MW_LAYER_SYSTEMINCLUDE +SYSTEMINCLUDE /epoc32/include/ecom + +LIBRARY euser.lib +LIBRARY ecom.lib +LIBRARY charconv.lib +LIBRARY dmadengine.lib +LIBRARY eventmedapi.lib +LIBRARY vpnapi.lib +LIBRARY eventviewer.lib +LIBRARY efsrv.lib +LIBRARY bafl.lib +LIBRARY cmmanager.lib + +DEBUGLIBRARY flogger.lib + +MACRO DMAD_ENGINE_EXPORT diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/inc/DmAdRtNodeData.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/inc/DmAdRtNodeData.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,150 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdRtNodeData. +* +*/ + + + +#ifndef __DMADRTNODEDATA_H__ +#define __DMADRTNODEDATA_H__ + + +#include + +#include "dmadcallback.h" +#include "dmadstorevpnap.h" +#include "vpnapi.h" + +class CX509Certificate; + +typedef enum + { + EDmAdUriTypeVpnAp, + EDmAdUriTypePolicy, + } TDmAdUriType; + +//------------------------------------------------------------------------------------------------ +// CDmAdVpnApData +//------------------------------------------------------------------------------------------------ +class CDmAdVpnApData : public CBase + { +public: + static CDmAdVpnApData* NewL(MDmAdCallBack* aCallBack); + ~CDmAdVpnApData(); + + + void SetNameL(const TDesC8& aName); + HBufC8* NameLC(void); + + void SetPolicyRefIdL(const TDesC& aPolicyRefId); + HBufC* PolicyRefIdLC(void); + + void SetConRefL(const TDesC8& aConRef); + HBufC8* ConRefLC(void); + + HBufC8* ThisRefLC(const TDesC8& aLuid); + HBufC8* PolicyRefUriLC(void); + + void RestoreL(const TVpnApParms& aVpnApParms); + void ToStoreL(TVpnApParms& aVpnApParms); + +private: + CDmAdVpnApData(MDmAdCallBack* aCallBack); + +private: + MDmAdCallBack* iCallBack; + + HBufC* iName; + HBufC* iPolicyRefId; + HBufC8* iConRef; + }; + +//------------------------------------------------------------------------------------------------ +// CDmAdPolicyData +//------------------------------------------------------------------------------------------------ +class CDmAdPolicyData : public CBase + { +public: + static CDmAdPolicyData* NewL(void); + ~CDmAdPolicyData(); + + void SetNameL(const TDesC8& aName); + HBufC8* NameLC(void); + void SetIdL(const TDesC8& aId); + HBufC8* IdLC(void); + void SetVersionL(const TDesC8& aVersion); + HBufC8* VersionLC(void); + void SetDescriptionL(const TDesC8& aDescription); + HBufC8* DescriptionLC(void); + void SetIssuerL(const TDesC8& aIssuer); + HBufC8* IssuerLC(void); + void SetContactL(const TDesC8& aContact); + HBufC8* ContactLC(void); + void SetContentL(const TDesC8& aContent); + TPtrC8 Content(void); + void DetailsRestoreL(const TVpnPolicyDetails& aDetails); + void DetailsToStoreL(TVpnPolicyDetails& aDetails); + void ContentRestoreL(const TDesC8& aContent); + TPtrC8 ContentToStore(void); + +private: + CDmAdPolicyData(); + +private: + HBufC* iName; + HBufC* iId; + HBufC* iVersion; + HBufC* iDescription; + HBufC* iIssuer; + HBufC* iContact; + HBufC8* iContent; + }; + +//------------------------------------------------------------------------------------------------ +// CDmAdRtNodeData +//------------------------------------------------------------------------------------------------ +class CDmAdRtNodeData : public CBase + { +public: + static CDmAdRtNodeData* NewL(const TDesC8& aUri, MDmAdCallBack* aCallBack); + ~CDmAdRtNodeData(); + TDmAdUriType UriType(void) const; + static TDmAdUriType UriTypeL(const TDesC8& aUri); + void UpdateLeafDataL(const TDesC8& aUri, const TDesC8& aObject); + void FetchLeafObjectLC(const TDesC8& aUri, const TDesC8& aLuid, CBufBase*& aObject); + + inline CDmAdVpnApData* VpnApData(void) const; + inline CDmAdPolicyData* PolicyData(void) const; + +private: + void ConstructL(const TDesC8& aUri, MDmAdCallBack* aCallBack); + CDmAdRtNodeData(); + void UpdateLeafDataVpnApL(const TDesC8& aUri, const TDesC8& aObject); + void UpdateLeafDataPolicyL(const TDesC8& aUri, const TDesC8& aObject); + void FetchLeafObjectVpnApLC(const TDesC8& aUri, const TDesC8& aLuid, CBufBase*& aObject); + void FetchLeafObjectPolicyLC(const TDesC8& aUri, const TDesC8& aLuid, CBufBase*& aObject); + +private: + TDmAdUriType iUriType; + union + { + CDmAdVpnApData* iVpnAp; + CDmAdPolicyData* iPolicy; + } u; + }; + +#include "DmAdRtNodeData.inl" + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/inc/DmAdRtNodeData.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/inc/DmAdRtNodeData.inl Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Inlined node data methods. +* +*/ + + + +#ifndef __DMADRTNODEDATA_INL__ +#define __DMADRTNODEDATA_INL__ + +inline CDmAdVpnApData* CDmAdRtNodeData::VpnApData(void) const + { + return u.iVpnAp; + } + +inline CDmAdPolicyData* CDmAdRtNodeData::PolicyData(void) const + { + return u.iPolicy; + } + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/inc/DmAdStore.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/inc/DmAdStore.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdStore. +* +*/ + + + +#ifndef __DMADSTORE_H__ +#define __DMADSTORE_H__ + +#include + +#include "dmadstoreapi.h" +#include "DmAdRtNode.h" + +#include "dmadstorevpnap.h" +#include "vpnapi.h" + +#include "eventlogger.h" + +//------------------------------------------------------------------------------------------------ +// CDmAdStore +//------------------------------------------------------------------------------------------------ +class CDmAdStore : public CBase, public MDmAdStoreApi + { +public: + static CDmAdStore* NewL(void); + ~CDmAdStore(); + TBool FindRtNodeL(const TDesC8& aLuid, const TDesC8& aUri); + void LuidListL(const TDesC8& aUri, const TDesC8& aLuid, RPointerArray& aLuidList); + void FetchRtNodeL(CDmAdRtNode& aRtNode); + void SaveTopLevelRtNodeL(CDmAdRtNode& aRtNode, CArrayPtr& aChildRtNodes); + void SaveChildLevelRtNodeL(CDmAdRtNode& aRtNode); + void DeleteRtNodeL(const TDesC8& aLuid, const TDesC8& aUri); + +private: + void ConstructL(void); + CDmAdStore(); + + TBool VpnApFindRtNodeL(const TDesC8& aLuid, const TDesC8& aUri); + void VpnApLuidListL(RPointerArray& aLuidList); + void VpnApFetchRtNodeL(CDmAdRtNode& aRtNode); + void VpnApSaveTopLevelRtNodeL(CDmAdRtNode& aRtNode, CArrayPtr& aChildRtNodes); + void VpnApDeleteRtNodeL(const TDesC8& aLuid); + + TPtrC8 PolicyRefToLuid(const TDesC& aPolicyRef); + TPtrC LuidToPolicyRef(const TDesC8& aLuid); + TBool PolicyFindRtNodeL(const TDesC8& aLuid, const TDesC8& aUri); + void PolicyLuidListL(RPointerArray& aLuidList); + void PolicyFetchRtNodeL(CDmAdRtNode& aRtNode); + void PolicySaveTopLevelRtNodeL(CDmAdRtNode& aRtNode, CArrayPtr& aChildRtNodes); + void PolicyDeleteRtNodeL(const TDesC8& aLuid); + +private: + CVpnAp* iVpnAp; + RVpnServ iVpnApi; + + DEFINE_EVENT_LOGGER + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/inc/dmadadapter.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/inc/dmadadapter.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,94 @@ +/* +* Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: VPN OMA DM Adapter +* +*/ + + + +#ifndef __DMADADAPTER_H__ +#define __DMADADAPTER_H__ + +#include + +#include "dmadcallbackc.h" +#include "DmAdStore.h" +#include "dmadddf.h" +#include "dmadrtnodedataapic.h" +#include "dmadengine.h" + +//------------------------------------------------------------------------------------------------ +// CDmAdAdapter +//------------------------------------------------------------------------------------------------ +class CDmAdAdapter : public CSmlDmAdapter + { +public: + static CDmAdAdapter* NewL(MSmlDmCallback* aDmCallback); + static CDmAdAdapter* NewLC(MSmlDmCallback* aDmCallback); + ~CDmAdAdapter(); + + void DDFVersionL(CBufBase& aVersion); + void DDFStructureL(MSmlDmDDFObject& aDDF); + + void ChildURIListL(const TDesC8& aUri, const TDesC8& aLuid, const CArrayFix& aPreviousURISegmentList, TInt aResultsRef, TInt aStatusRef); + void AddNodeObjectL(const TDesC8& aUri, const TDesC8& aParentLuid, const TInt aStatusRef); + void UpdateLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aObject, const TDesC8& aType, TInt aStatusRef); + void FetchLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aType, TInt aResultsRef, TInt aStatusRef); + void DeleteObjectL(const TDesC8& aUri, const TDesC8& aLuid, TInt aStatusRef); + void CompleteOutstandingCmdsL(); + void UpdateLeafObjectL(const TDesC8& aUri, + const TDesC8& aLuid, + RWriteStream*& aStream, + const TDesC8& aType, + TInt aStatusRef); + void FetchLeafObjectSizeL(const TDesC8& aUri, + const TDesC8& aLuid, + const TDesC8& aType, + TInt aResultsRef, + TInt aStatusRef); + void ExecuteCommandL(const TDesC8& aUri, + const TDesC8& aLuid, + const TDesC8& aArgument, + const TDesC8& aType, + TInt aStatusRef); + void ExecuteCommandL(const TDesC8& aUri, + const TDesC8& aLuid, + RWriteStream*& aStream, + const TDesC8& aType, + TInt aStatusRef); + void CopyCommandL(const TDesC8& aTargetUri, + const TDesC8& aTargetLuid, + const TDesC8& aSourceUri, + const TDesC8& aSourceLuid, + const TDesC8& aType, + TInt aStatusRef); + void StartAtomicL(); + void CommitAtomicL(); + void RollbackAtomicL(); + TBool StreamingSupport(TInt& aItemSize); + void StreamCommittedL(); + +private: + CDmAdAdapter(MSmlDmCallback* aDmCallback); + void ConstructL(MSmlDmCallback* aDmCallback); + +private: + CDmAdCallBack* iCallBack; + CDmAdStore* iStore; + CDmAdDdf* iDdf; + CDmAdRtNodeDataApi* iRtNodeDataApi; + CDmAdEngine* iEngine; + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/inc/dmadadapterimplconst.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/inc/dmadadapterimplconst.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: VPN OMA DM Adapter constants. +* +*/ + + + +#ifndef __DMADADAPTERIMPLCONST_H__ +#define __DMADADAPTERIMPLCONST_H__ + +#define KDmAdDllUid 0x1020699C +#define KDmAdImplUid 0x1020699D + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/inc/dmadddf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/inc/dmadddf.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,167 @@ +/* +* Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdDdf. +* +*/ + + + +#ifndef __DMADDDF_H__ +#define __DMADDDF_H__ + +#include +#include "dmadddfapi.h" +#include "dmadcallback.h" +#include "DmAdStore.h" +#include "version.h" + +//------------------------------------------------------------------------------------------------ +// DDF version +//------------------------------------------------------------------------------------------------ +_LIT8(KDmAdDdfVersion, "1.0"); + +//------------------------------------------------------------------------------------------------ +// ./NokiaIPSecVPN Type property +//------------------------------------------------------------------------------------------------ +_LIT8(KDmAdNokiaIpSecVpnRootTypeProperty, "com.nokia.devman/1.0/ipsecvpn"); + +//------------------------------------------------------------------------------------------------ +// ./NokiaIPSecVPN/General/ClientVersion - see version.h +//------------------------------------------------------------------------------------------------ +//_LIT8(KDmAdClientVersion, "0.0"); + +//------------------------------------------------------------------------------------------------ +// URIs +//------------------------------------------------------------------------------------------------ +_LIT8(KDmAdOwnAdUriForGetLuidAllocLFix, "NokiaIPSecVPN/Policy"); // URI not object group level? + + //------- root ----------------- +_LIT8(KDmAdNodeNokiaIpSecVpn, "NokiaIPSecVPN"); + + //------- common ----------------- +_LIT8(KDmAdNodeRt, ""); +_LIT8(KDmAdNodeGeneral, "General"); + +_LIT8(KDmAdLeafClientVersion, "ClientVersion"); +_LIT8(KDmAdLeafEventLog, "EventLog"); +_LIT8(KDmAdLeafName, "Name"); +_LIT8(KDmAdLeafId, "ID"); +_LIT8(KDmAdLeafContent, "Content"); + + //------- AP ----------------- +_LIT8(KDmAdNodeAp, "AP"); +_LIT8(KDmAdNodePolicyRef, "PolicyRef"); +_LIT8(KDmAdLeafConRef, "ConRef"); +_LIT8(KDmAdLeafThisRef, "ThisRef"); +_LIT8(KDmAdLeafUri, "URI"); + + //------- Policy ----------------- +_LIT8(KDmAdNodePolicy, "Policy"); +_LIT8(KDmAdLeafVersion, "Version"); +_LIT8(KDmAdLeafDescription, "Description"); +_LIT8(KDmAdLeafIssuer, "Issuer"); +_LIT8(KDmAdLeafContact, "Contact"); + +//------------------------------------------------------------------------------------------------ +// URI descriptions +//------------------------------------------------------------------------------------------------ + //------- root ----------------- +_LIT8(KDmAdDescNodeNokiaIpSecVpn, "NokiaIPSecVPN"); + + //------- common ----------------- +_LIT8(KDmAdDescNodeRt, "Placeholder for one set of settings"); +_LIT8(KDmAdDescNodeGeneral, "General"); + +_LIT8(KDmAdDescLeafClientVersion, "ClientVersion"); +_LIT8(KDmAdDescLeafEventLog, "EventLog"); +_LIT8(KDmAdDescLeafName, "Name"); +_LIT8(KDmAdDescLeafId, "ID"); +_LIT8(KDmAdDescLeafContent, "Content"); + + //------- AP ----------------- +_LIT8(KDmAdDescNodeAp, "AP"); +_LIT8(KDmAdDescNodePolicyRef, "PolicyRef"); +_LIT8(KDmAdDescLeafConRef, "ConRef"); +_LIT8(KDmAdDescLeafThisRef, "ThisRef"); +_LIT8(KDmAdDescLeafUri, "URI"); + + //------- Policy ----------------- +_LIT8(KDmAdDescNodePolicy, "Policy"); +_LIT8(KDmAdDescLeafVersion, "Version"); +_LIT8(KDmAdDescLeafDescription, "Description"); +_LIT8(KDmAdDescLeafIssuer, "Issuer"); +_LIT8(KDmAdDescLeafContact, "Contact"); + +//------------------------------------------------------------------------------------------------ +// ChildURIListL constants +//------------------------------------------------------------------------------------------------ +_LIT8(KDmAdListOfNokiaIpSecVpnChildren, "General/AP/Policy"); + +_LIT8(KDmAdListOfPolicyXChildren, "Name/ID/Version/Description/Issuer/Contact/Content"); +_LIT8(KDmAdListOfApXChildren, "Name/ThisRef/PolicyRef/ConRef"); + +_LIT8(KDmAdListOfPolicyRefChildren, "ID/URI"); + +_LIT8(KDmAdListOfIpSecVpnGeneralChildren, "ClientVersion/EventLog"); + + + +//------------------------------------------------------------------------------------------------ +// FetchLink URIs +//------------------------------------------------------------------------------------------------ +_LIT8(KDmAdFetchLinkAp, "AP"); +_LIT8(KDmAdFetchLinkSnap, "BearerManagementSNAP"); +_LIT8(KDmAdFetchLinkPolicy, "NokiaIPSecVPN/Policy"); + +//------------------------------------------------------------------------------------------------ +// TDFFormat - EBool +//------------------------------------------------------------------------------------------------ +_LIT8(KDmAdDfFormatBoolTrue, "True" ); +_LIT8(KDmAdDfFormatBoolFalse, "False" ); + +//------------------------------------------------------------------------------------------------ +// CDmAdDdf +//------------------------------------------------------------------------------------------------ +class CDmAdDdf : public CBase, public MDmAdDdfApi + { +public: + static CDmAdDdf* NewL(MDmAdCallBack* aDmAdCallBack, CDmAdStore* aStore); + static CDmAdDdf* NewLC(MDmAdCallBack* aDmAdCallBack, CDmAdStore* aStore); + ~CDmAdDdf(); + + void BuildDDFVersionL(CBufBase& aDDFVersion); + void BuildDDFStructureL(MSmlDmDDFObject& aDDF); + + void NotRtNodeAddNodeObjectL(const TDesC8& aUri, const TDesC8& aParentLuid, TInt aStatusRef); + void NotRtNodeUpdateLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aObject, const TDesC8& aType, TInt aStatusRef); + TInt NotRtNodeFetchLeafObjectLC(const TDesC8& aUri, const TDesC8& /*aLuid*/, const TDesC8& /*aType*/, CBufBase*& aObject); + void NotRtNodeDeleteObjectL(const TDesC8& aUri, const TDesC8& aLuid, TInt aStatusRef); + + TBool IsNodeRtNodeL(const TDesC8& aUri); + TBool IsLeafUnderRtNodeL(const TDesC8& aUri); + TPtrC8 RtNodeUriForLeafL(const TDesC8& aLeafUri); + TBool IsTopLevelRtNode(const TDesC8& aUri); + HBufC8* ParentRtNodeUriForRtNodeLC(const TDesC8& aUri); + void BuildChildUriListLC(const TDesC8& aUri, const TDesC8& aParentLuid, const CArrayFix& aPreviousUriSegmentList, CBufBase*& aCurrentList); + +private: + CDmAdDdf(MDmAdCallBack* aDmAdCallBack, CDmAdStore* aStore); + void ConstructL(void); + +private: + MDmAdCallBack* iCallBack; + CDmAdStore* iStore; + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/inc/dmadeventlog.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/inc/dmadeventlog.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of TDmAdEventLog. +* +*/ + + + +#ifndef __DMADEVENTLOG_H__ +#define __DMADEVENTLOG_H__ + +#include +#include +#include + +#include "eventviewer2.h" + +//------------------------------------------------------------------------------------------------ +// TDmAdEventLog +//------------------------------------------------------------------------------------------------ +class TDmAdEventLog + { +public: + static void DeleteLogL(void); + static void EventLogL(CBufBase& aEventLog); +private: + static void FormatTimeL(RResourceFile& aResourceFile, TDes& aDateTimeText, TTime aTime); + static HBufC* CategoryTextLC(RResourceFile& aResourceFile, TLogCategory2 aCategory); + static void OpenResourceFileL(RFs& aFs, RResourceFile& aResourceFile, const TDesC& aFilename); + static HBufC* ReadResourceLC(RResourceFile& aResourceFile, TInt aMsgId); + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/inc/dmadrtnodedataapic.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/inc/dmadrtnodedataapic.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdRtNodeDataApi. +* +*/ + + + +#ifndef __DMADRTNODEDATAAPIC_H__ +#define __DMADRTNODEDATAAPIC_H__ + +#include + +#include "dmadrtnodedataapi.h" +#include "DmAdRtNodeData.h" +#include "dmadcallback.h" + +//------------------------------------------------------------------------------------------------ +// CDmAdRtNodeDataApi +//------------------------------------------------------------------------------------------------ +class CDmAdRtNodeDataApi : public CBase, public MDmAdRtNodeDataApi + { +public: + static CDmAdRtNodeDataApi* NewL(void); + static CDmAdRtNodeDataApi* NewLC(void); + ~CDmAdRtNodeDataApi(); + + CDmAdRtNodeData* CreateDmAdRtNodeDataL(const TDesC8& aUri, MDmAdCallBack* aCallBack); + void DeleteDmAdRtNodeData(CDmAdRtNodeData* aDmAdRtNodeData); + void UpdateLeafDataL(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri, const TDesC8& aObject); + void FetchLeafObjectLC(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri, const TDesC8& aLuid, CBufBase*& aObject); + void SetDefaultSettingsL(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri); + TBool AreUriTypesSame(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri); + +private: + void ConstructL(void); + CDmAdRtNodeDataApi(); + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/inc/dmadstorevpnap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/inc/dmadstorevpnap.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,87 @@ +/* +* Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: VPN AP storer +* +*/ + + + +#ifndef __DMADSTOREVPNAP_H__ +#define __DMADSTOREVPNAP_H__ + +#include +#include + +typedef TInt32 TVpnApCommsId; +const TInt KVpnApSvrMaxFieldLength = 50; + +class TVpnApParms + { + public: + enum TRealConnRefType + { + EIapRealConnRef, + ESnapRealConnRef + }; + + TBuf iName; + TBuf iPolicyId; + + TRealConnRefType iRealConnRefType; + TVpnApCommsId iRealConnRef; + }; + + +class RCmConnectionMethodExt; + +/** + * Store VPN AP + * + * Store VPN accesspoints data to commsdb. + * + * @lib (internal) dmadipsecvpn.lib + * @since S60 3.0 + */ +class CVpnAp : public CBase + { +public: + static CVpnAp* NewL(void); + ~CVpnAp(); + + TBool FindVpnApL(TVpnApCommsId aId); + void DeleteVpnApL(TVpnApCommsId aId); + void ListVpnApsL(RArray& aIdArray); + void GetVpnApL(TVpnApCommsId aId, TVpnApParms& aVpnApParms); + TVpnApCommsId AddVpnApL(const TVpnApParms& aVpnApParms); + void UpdateVpnApL(TVpnApCommsId aId, const TVpnApParms& aVpnApParms); + +private: // implementation + void ConstructL(void); + CVpnAp(); + + + void UpdateVpnApL(RCmConnectionMethodExt& aConnectionMethod, + const TVpnApParms& aVpnApParms); + + TBool IsVpnConnectionMethodL(RCmConnectionMethodExt& aConnectionMethod) const; + +private: // data + + RCmManagerExt iCmManagerExt; + + }; + +#endif // __DMADSTOREVPNAP_H__ + + diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/inc/eventlogger.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/inc/eventlogger.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CEventLogger. +* +*/ + + + +#ifndef __EVENTLOGGER_H__ +#define __EVENTLOGGER_H__ + + +#include + +#include "eventmediatorapi.h" +#include "vpnapi.h" + +class CEventLogger : CBase + { +public: + static CEventLogger* NewL(); + void LogEvent(RVpnServ& vpnApi, TUint aMsgId, const TDesC* aDes1, TInt aInt1, TInt aInt2); + ~CEventLogger(); + +private: + CEventLogger(); + void ConstructL(); + void LogEvent(TUint aMsgId, const TDesC8* aDes1, TInt aInt1, TInt aInt2); + +private: + REventMediator iEventMediator; + }; + +#define DEFINE_EVENT_LOGGER CEventLogger* iEventLogger; +#define INIT_EVENT_LOGGER TRAP_IGNORE(iEventLogger = CEventLogger::NewL();); +#define RELEASE_EVENT_LOGGER delete iEventLogger; iEventLogger = NULL; + +#define LOG_EVENT(a, b, c, d, e) if (iEventLogger) iEventLogger->LogEvent(a, b, c, d, e); + +#endif // __EVENTLOGGER_H__ diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/inc/log.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/inc/log.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Logging utility. +* +*/ + + + +#if !defined(__LOG_H__) +#define __LOG_H__ + +_LIT(KLogFile,"dmad.txt"); + +#include "logcommon.h" + +#endif // __LOG_H__ diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/rom/dmadipsecvpn.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/rom/dmadipsecvpn.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Image description file for project dmadipsecvpn +* +*/ + + + +#ifndef __DMADIPSECVPN_IBY__ +#define __DMADIPSECVPN_IBY__ + +#ifdef SYMBIAN_EXCLUDE_IPSEC + +REM dmadipsecvpn not included in this rom + +#else + +ECOM_PLUGIN(dmadipsecvpn.dll, dmadipsecvpn.rsc) + +#endif // SYMBIAN_EXCLUDE_IPSEC + +#endif // __DMADIPSECVPN_IBY__ diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/src/DmAdRtNodeData.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/src/DmAdRtNodeData.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,915 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CDmAdRtNodeData. +* +*/ + + + +#include + +#include "DmAdRtNodeData.h" +#include "dmadddf.h" +#include "dmadutil.h" +#include "vpnlogger.h" + +CDmAdRtNodeData* CDmAdRtNodeData::NewL(const TDesC8& aUri, MDmAdCallBack* aCallBack) + { + TRACE("CDmAdRtNodeData::NewL"); + + CDmAdRtNodeData *self = new (ELeave) CDmAdRtNodeData(); + CleanupStack::PushL(self); + self->ConstructL(aUri, aCallBack); + CleanupStack::Pop(); // self + return self; + } + +void CDmAdRtNodeData::ConstructL(const TDesC8& aUri, MDmAdCallBack* aCallBack) + { + TRACE("CDmAdRtNodeData::ConstructL"); + + iUriType = UriTypeL(aUri); + + switch (iUriType) + { + case EDmAdUriTypeVpnAp: + u.iVpnAp = CDmAdVpnApData::NewL(aCallBack); + break; + case EDmAdUriTypePolicy: + u.iPolicy = CDmAdPolicyData::NewL(); + break; + default: + DEBUG_LOG(_L("Unknown URI type")); + User::Leave(KErrGeneral); + break; + } + } + +CDmAdRtNodeData::CDmAdRtNodeData() + { + TRACE("CDmAdRtNodeData::CDmAdRtNodeData"); + } + +CDmAdRtNodeData::~CDmAdRtNodeData() + { + TRACE("CDmAdRtNodeData::~CDmAdRtNodeData"); + + switch (iUriType) + { + case EDmAdUriTypeVpnAp: + delete u.iVpnAp; + break; + case EDmAdUriTypePolicy: + delete u.iPolicy; + break; + default: + DEBUG_LOG(_L("Unknown URI type")); + User::Invariant(); + break; + } + } + +//-------------------------------------------------------------------------- + +TDmAdUriType CDmAdRtNodeData::UriType(void) const + { + TRACE("CDmAdRtNodeData::UriType"); + return iUriType; + } + +TDmAdUriType CDmAdRtNodeData::UriTypeL(const TDesC8& aUri) + { + TRACE("CDmAdRtNodeData::UriTypeL"); + + TDmAdUriType ret = EDmAdUriTypeVpnAp; + CArrayFix* uriSegList; + TDmAdUtil::ParseUriLC(aUri, uriSegList); + + if (uriSegList->Count() < 2) + { + DEBUG_LOG(_L("Uri seg count < 2")); + User::Leave(KErrGeneral); + } + + if (uriSegList->At(0).Compare(KDmAdNodeNokiaIpSecVpn) == 0) + { + if (uriSegList->At(1).Compare(KDmAdNodePolicy) == 0) + { + ret = EDmAdUriTypePolicy; + } + else if (uriSegList->At(1).Compare(KDmAdNodeAp) == 0) + { + ret = EDmAdUriTypeVpnAp; + } + else + { + DEBUG_LOG(_L("Unknown URI element")); + User::Leave(KErrGeneral); + } + } + else + { + DEBUG_LOG(_L("Unknown URI element")); + User::Leave(KErrGeneral); + } + + CleanupStack::PopAndDestroy(); // uriSegList + return ret; + } + +//-------------------------------------------------------------------------- + +void CDmAdRtNodeData::UpdateLeafDataL(const TDesC8& aUri, const TDesC8& aObject) + { + TRACE("CDmAdRtNodeData::UpdateLeafDataL"); + + switch (iUriType) + { + case EDmAdUriTypeVpnAp: + UpdateLeafDataVpnApL(aUri, aObject); + break; + case EDmAdUriTypePolicy: + UpdateLeafDataPolicyL(aUri, aObject); + break; + default: + DEBUG_LOG(_L("Unknown URI type")); + User::Leave(KErrGeneral); + break; + } + } + +void CDmAdRtNodeData::UpdateLeafDataVpnApL(const TDesC8& aUri, const TDesC8& aObject) + { + TRACE("CDmAdRtNodeData::UpdateLeafDataVpnApL"); + + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdLeafName) == 0) + { + u.iVpnAp->SetNameL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafId) == 0) + { + HBufC* policyRef = CnvUtfConverter::ConvertToUnicodeFromUtf8L(aObject); + CleanupStack::PushL(policyRef); + u.iVpnAp->SetPolicyRefIdL(*policyRef); + CleanupStack::PopAndDestroy(policyRef); + } + else if (lastSeg.Compare(KDmAdLeafConRef) == 0) + { + u.iVpnAp->SetConRefL(aObject); + } + else + { + DEBUG_LOG(_L("Node not found")); + User::Leave(KErrNotFound); + } + } + +void CDmAdRtNodeData::UpdateLeafDataPolicyL(const TDesC8& aUri, const TDesC8& aObject) + { + TRACE("CDmAdRtNodeData::UpdateLeafDataPolicyL"); + + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdLeafName) == 0) + { + u.iPolicy->SetNameL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafId) == 0) + { + u.iPolicy->SetIdL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafVersion) == 0) + { + u.iPolicy->SetVersionL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafDescription) == 0) + { + u.iPolicy->SetDescriptionL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafIssuer) == 0) + { + u.iPolicy->SetIssuerL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafContact) == 0) + { + u.iPolicy->SetContactL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafContent) == 0) + { + u.iPolicy->SetContentL(aObject); + } + else + { + DEBUG_LOG(_L("Node not found")); + User::Leave(KErrNotFound); + } + } + +void CDmAdRtNodeData::FetchLeafObjectLC(const TDesC8& aUri, const TDesC8& aLuid, CBufBase*& aObject) + { + switch (iUriType) + { + case EDmAdUriTypeVpnAp: + FetchLeafObjectVpnApLC(aUri, aLuid, aObject); + break; + case EDmAdUriTypePolicy: + FetchLeafObjectPolicyLC(aUri, aLuid, aObject); + break; + default: + DEBUG_LOG(_L("Unknown URI type")); + User::Leave(KErrGeneral); + break; + } + } + +void CDmAdRtNodeData::FetchLeafObjectVpnApLC(const TDesC8& aUri, const TDesC8& aLuid, CBufBase*& aObject) + { + CBufBase* object = CBufFlat::NewL(32); + CleanupStack::PushL(object); + + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdLeafName) == 0) + { + HBufC8* obj = u.iVpnAp->NameLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(); //obj + } + else if (lastSeg.Compare(KDmAdLeafThisRef) == 0) + { + HBufC8* obj = u.iVpnAp->ThisRefLC(aLuid); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(); //obj + } + else if (lastSeg.Compare(KDmAdLeafId) == 0) + { + HBufC* policyRef = u.iVpnAp->PolicyRefIdLC(); + HBufC8* obj = CnvUtfConverter::ConvertFromUnicodeToUtf8L(*policyRef); + CleanupStack::PushL(obj); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + CleanupStack::PopAndDestroy(policyRef); + } + else if (lastSeg.Compare(KDmAdLeafUri) == 0) + { + HBufC8* obj = u.iVpnAp->PolicyRefUriLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(); //obj + } + else if (lastSeg.Compare(KDmAdLeafConRef) == 0) + { + HBufC8* obj = u.iVpnAp->ConRefLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(); //obj + } + else + { + DEBUG_LOG(_L("Node not found")); + User::Leave(KErrNotFound); + } + + aObject = object; + } + +void CDmAdRtNodeData::FetchLeafObjectPolicyLC(const TDesC8& aUri, const TDesC8& aLuid, CBufBase*& aObject) + { + (void)aLuid; + CBufBase* object = CBufFlat::NewL(32); + CleanupStack::PushL(object); + + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdLeafName) == 0) + { + HBufC8* obj = u.iPolicy->NameLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(); //obj + } + else if (lastSeg.Compare(KDmAdLeafId) == 0) + { + HBufC8* obj = u.iPolicy->IdLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(); //obj + } + else if (lastSeg.Compare(KDmAdLeafVersion) == 0) + { + HBufC8* obj = u.iPolicy->VersionLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(); //obj + } + else if (lastSeg.Compare(KDmAdLeafDescription) == 0) + { + HBufC8* obj = u.iPolicy->DescriptionLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(); //obj + } + else if (lastSeg.Compare(KDmAdLeafIssuer) == 0) + { + HBufC8* obj = u.iPolicy->IssuerLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(); //obj + } + else if (lastSeg.Compare(KDmAdLeafContact) == 0) + { + HBufC8* obj = u.iPolicy->ContactLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(); //obj + } + else if (lastSeg.Compare(KDmAdLeafContent) == 0) + { + TPtrC8 obj(u.iPolicy->Content()); + object->InsertL(0, obj); + } + else + { + DEBUG_LOG(_L("Node not found")); + User::Leave(KErrNotFound); + } + + aObject = object; + } + + +//====================================================================================== +//====================================================================================== + +CDmAdVpnApData* CDmAdVpnApData::NewL(MDmAdCallBack* aCallBack) + { + TRACE("CDmAdVpnApData::NewL"); + + CDmAdVpnApData *self = new (ELeave) CDmAdVpnApData(aCallBack); + return self; + } + + +CDmAdVpnApData::CDmAdVpnApData(MDmAdCallBack* aCallBack) : iCallBack(aCallBack) + { + TRACE("CDmAdVpnApData::CDmAdVpnApData"); + } + +CDmAdVpnApData::~CDmAdVpnApData() + { + TRACE("CDmAdVpnApData::~CDmAdVpnApData"); + + delete iName; + delete iPolicyRefId; + delete iConRef; + } + +void CDmAdVpnApData::SetNameL(const TDesC8& aName) + { + TRACE("CDmAdVpnApData::SetNameL"); + + delete iName; + iName = NULL; + if (aName.Length() > 0) + { + iName = CnvUtfConverter::ConvertToUnicodeFromUtf8L(aName); + } + } + +HBufC8* CDmAdVpnApData::NameLC(void) + { + if (iName == 0) + { + return HBufC8::NewLC(1); + } + HBufC8* ret = CnvUtfConverter::ConvertFromUnicodeToUtf8L(*iName); + CleanupStack::PushL(ret); + return ret; + } + +void CDmAdVpnApData::SetPolicyRefIdL(const TDesC& aPolicyRefId) + { + TRACE("CDmAdVpnApData::SetPolicyRefIdL"); + + delete iPolicyRefId; + iPolicyRefId = 0; + if (aPolicyRefId.Length() > 0) + { + iPolicyRefId = aPolicyRefId.AllocL(); + } + } + +HBufC* CDmAdVpnApData::PolicyRefIdLC(void) + { + if (iPolicyRefId == 0) + { + return HBufC::NewLC(1); + } + HBufC* ret = iPolicyRefId->AllocLC(); + return ret; + } + +void CDmAdVpnApData::SetConRefL(const TDesC8& aConRef) + { + TRACE("CDmAdVpnApData::SetConRefL"); + + delete iConRef; + iConRef = 0; + if (aConRef.Length() > 0) + { + iConRef = aConRef.AllocL(); + } + } + +HBufC8* CDmAdVpnApData::ConRefLC(void) + { + if (iConRef == 0) + { + return HBufC8::NewLC(1); + } + HBufC8* ret = iConRef->AllocLC(); + return ret; + } + +HBufC8* CDmAdVpnApData::ThisRefLC(const TDesC8& aLuid) + { + HBufC8* thisRef = iCallBack->FindChildUriL(KDmAdFetchLinkAp, aLuid); + if (thisRef == 0) + { + return HBufC8::NewLC(1); + } + CleanupStack::PushL(thisRef); + return thisRef; + } + +HBufC8* CDmAdVpnApData::PolicyRefUriLC(void) + { + if (iPolicyRefId == 0) + { + return HBufC8::NewLC(1); + } + + const TPtrC8 policyLuid((const TUint8*)iPolicyRefId->Ptr(), iPolicyRefId->Size()); + HBufC8* refUri = iCallBack->FindChildUriL(KDmAdFetchLinkPolicy, policyLuid); + if (refUri == 0) + { + return HBufC8::NewLC(1); + } + CleanupStack::PushL(refUri); + return refUri; + } + +void CDmAdVpnApData::RestoreL(const TVpnApParms& aVpnApParms) + { + TRACE("CDmAdVpnApData::RestoreL"); + + delete iName; + iName = NULL; + if (aVpnApParms.iName.Length() > 0) + { + iName = aVpnApParms.iName.AllocL(); + } + + delete iPolicyRefId; + iPolicyRefId = 0; + if (aVpnApParms.iPolicyId.Length() > 0) + { + iPolicyRefId = aVpnApParms.iPolicyId.AllocL(); + } + + delete iConRef; + iConRef = NULL; + if (aVpnApParms.iRealConnRef != 0) + { + HBufC8* luid = TDmAdUtil::IntToDes8LC(aVpnApParms.iRealConnRef); + + switch(aVpnApParms.iRealConnRefType) + { + case TVpnApParms::EIapRealConnRef: + iConRef = iCallBack->FindChildUriL(KDmAdFetchLinkAp, *luid); + break; + case TVpnApParms::ESnapRealConnRef: + iConRef = iCallBack->FindChildUriL(KDmAdFetchLinkSnap, *luid); + break; + default: + User::Invariant(); + break; + } + CleanupStack::PopAndDestroy(); // luid + } + } + +void CDmAdVpnApData::ToStoreL(TVpnApParms& aVpnApParms) + { + TRACE("CDmAdVpnApData::ToStoreL"); + + if (iName == 0) + { + aVpnApParms.iName.SetLength(0); + } + else + { + if (iName->Length() > aVpnApParms.iName.MaxLength()) + { + DEBUG_LOG(_L("iName too long")); + User::Leave(KErrOverflow); + } + aVpnApParms.iName.Copy(*iName); + } + + if (iPolicyRefId == 0) + { + aVpnApParms.iPolicyId.SetLength(0); + } + else + { + if (iPolicyRefId->Length() > aVpnApParms.iPolicyId.MaxLength()) + { + DEBUG_LOG(_L("iPolicyRefId too long")); + User::Leave(KErrOverflow); + } + aVpnApParms.iPolicyId.Copy(*iPolicyRefId); + } + + aVpnApParms.iRealConnRef = 0; + if (iConRef != NULL) + { + if (iConRef->Find(KDmAdFetchLinkAp) == 0) + { + aVpnApParms.iRealConnRefType = TVpnApParms::EIapRealConnRef; + } + else if (iConRef->Find(KDmAdFetchLinkSnap) == 0) + { + aVpnApParms.iRealConnRefType = TVpnApParms::ESnapRealConnRef; + } + else + { + User::Leave(KErrGeneral); + } + + HBufC8* luid = iCallBack->GetLuidAllocL(*iConRef); + CleanupStack::PushL(luid); + if (luid->Length() > 0) + { + aVpnApParms.iRealConnRef = TDmAdUtil::DesToInt(*luid); + } + CleanupStack::PopAndDestroy(luid); + } + } + +//====================================================================================== +//====================================================================================== + +CDmAdPolicyData* CDmAdPolicyData::NewL(void) + { + TRACE("CDmAdPolicyData::NewL"); + + CDmAdPolicyData *self = new (ELeave) CDmAdPolicyData(); + return self; + } + + +CDmAdPolicyData::CDmAdPolicyData() + { + TRACE("CDmAdPolicyData::CDmAdPolicyData"); + } + +CDmAdPolicyData::~CDmAdPolicyData() + { + TRACE("CDmAdPolicyData::~CDmAdPolicyData"); + + delete iName; + delete iId; + delete iVersion; + delete iDescription; + delete iIssuer; + delete iContact; + delete iContent; + } + +//-------------------------------------------------------------------------- + +void CDmAdPolicyData::SetNameL(const TDesC8& aName) + { + TRACE("CDmAdPolicyData::SetNameL"); + + delete iName; + iName = 0; + if (aName.Length() > 0) + { + iName = CnvUtfConverter::ConvertToUnicodeFromUtf8L(aName); + } + } + +HBufC8* CDmAdPolicyData::NameLC(void) + { + if (iName == 0) + { + return HBufC8::NewLC(1); + } + HBufC8* ret = CnvUtfConverter::ConvertFromUnicodeToUtf8L(*iName); + CleanupStack::PushL(ret); + return ret; + } + +void CDmAdPolicyData::SetIdL(const TDesC8& aId) + { + TRACE("CDmAdPolicyData::SetIdL"); + + delete iId; + iId = NULL; + if (aId.Length() > 0) + { + iId = CnvUtfConverter::ConvertToUnicodeFromUtf8L(aId); + } + } + +HBufC8* CDmAdPolicyData::IdLC(void) + { + if (iId == 0) + { + return HBufC8::NewLC(1); + } + HBufC8* ret = CnvUtfConverter::ConvertFromUnicodeToUtf8L(*iId); + CleanupStack::PushL(ret); + return ret; + } + +void CDmAdPolicyData::SetVersionL(const TDesC8& aVersion) + { + TRACE("CDmAdPolicyData::SetVersionL"); + + delete iVersion; + iVersion = 0; + if (aVersion.Length() > 0) + { + iVersion = CnvUtfConverter::ConvertToUnicodeFromUtf8L(aVersion); + } + } + +HBufC8* CDmAdPolicyData::VersionLC(void) + { + if (iVersion == 0) + { + return HBufC8::NewLC(1); + } + HBufC8* ret = CnvUtfConverter::ConvertFromUnicodeToUtf8L(*iVersion); + CleanupStack::PushL(ret); + return ret; + } + +void CDmAdPolicyData::SetDescriptionL(const TDesC8& aDescription) + { + TRACE("CDmAdPolicyData::SetDescriptionL"); + + delete iDescription; + iDescription = NULL; + if (aDescription.Length() > 0) + { + iDescription = CnvUtfConverter::ConvertToUnicodeFromUtf8L(aDescription); + } + } + +HBufC8* CDmAdPolicyData::DescriptionLC(void) + { + if (iDescription == 0) + { + return HBufC8::NewLC(1); + } + HBufC8* ret = CnvUtfConverter::ConvertFromUnicodeToUtf8L(*iDescription); + CleanupStack::PushL(ret); + return ret; + } + +void CDmAdPolicyData::SetIssuerL(const TDesC8& aIssuer) + { + TRACE("CDmAdPolicyData::SetIssuerL"); + + delete iIssuer; + iIssuer = NULL; + if (aIssuer.Length() > 0) + { + iIssuer = CnvUtfConverter::ConvertToUnicodeFromUtf8L(aIssuer); + } + } + +HBufC8* CDmAdPolicyData::IssuerLC(void) + { + if (iIssuer == 0) + { + return HBufC8::NewLC(1); + } + HBufC8* ret = CnvUtfConverter::ConvertFromUnicodeToUtf8L(*iIssuer); + CleanupStack::PushL(ret); + return ret; + } + +void CDmAdPolicyData::SetContactL(const TDesC8& aContact) + { + TRACE("CDmAdPolicyData::SetContactL"); + + delete iContact; + iContact = NULL; + if (aContact.Length() > 0) + { + iContact = CnvUtfConverter::ConvertToUnicodeFromUtf8L(aContact); + } + } + +HBufC8* CDmAdPolicyData::ContactLC(void) + { + if (iContact == 0) + { + return HBufC8::NewLC(1); + } + HBufC8* ret = CnvUtfConverter::ConvertFromUnicodeToUtf8L(*iContact); + CleanupStack::PushL(ret); + return ret; + } + +void CDmAdPolicyData::SetContentL(const TDesC8& aContent) + { + TRACE("CDmAdPolicyData::SetContentL"); + + delete iContent; + iContent = NULL; + if (aContent.Length() > 0) + { + iContent = aContent.AllocL(); + } + } + +TPtrC8 CDmAdPolicyData::Content(void) + { + TRACE("CDmAdPolicyData::Content"); + + TPtrC8 ret(KNullDesC8); + if (iContent != 0) + { + ret.Set(*iContent); + } + return ret; + } + +//-------------------------------------------------------------------------- + +void CDmAdPolicyData::DetailsRestoreL(const TVpnPolicyDetails& aDetails) + { + TRACE("CDmAdPolicyData::DetailsRestoreL"); + + delete iName; + iName = NULL; + if (aDetails.iName.Length() > 0) + { + iName = aDetails.iName.AllocL(); + } + + delete iId; + iId = 0; + if (aDetails.iId.Length() > 0) + { + iId = aDetails.iId.AllocL(); + } + + delete iVersion; + iVersion = 0; + if (aDetails.iVersion.Length() > 0) + { + iVersion = aDetails.iVersion.AllocL(); + } + + delete iDescription; + iDescription = 0; + if (aDetails.iDescription.Length() > 0) + { + iDescription = aDetails.iDescription.AllocL(); + } + + delete iIssuer; + iIssuer = 0; + if (aDetails.iIssuerName.Length() > 0) + { + iIssuer = aDetails.iIssuerName.AllocL(); + } + + delete iContact; + iContact = 0; + if (aDetails.iContactInfo.Length() > 0) + { + iContact = aDetails.iContactInfo.AllocL(); + } + } + +void CDmAdPolicyData::DetailsToStoreL(TVpnPolicyDetails& aDetails) + { + TRACE("CDmAdPolicyData::DetailsToStoreL"); + + if (iName == 0) + { + aDetails.iName.SetLength(0); + } + else + { + if (iName->Length() > aDetails.iName.MaxLength()) + { + DEBUG_LOG(_L("iName too long")); + User::Leave(KErrOverflow); + } + aDetails.iName.Copy(*iName); + } + + if (iId == 0) + { + aDetails.iId.SetLength(0); + } + else + { + if (iId->Length() > aDetails.iId.MaxLength()) + { + DEBUG_LOG(_L("iId too long")); + User::Leave(KErrOverflow); + } + aDetails.iId.Copy(*iId); + } + + if (iVersion == 0) + { + aDetails.iVersion.SetLength(0); + } + else + { + if (iVersion->Length() > aDetails.iVersion.MaxLength()) + { + DEBUG_LOG(_L("iVersion too long")); + User::Leave(KErrOverflow); + } + aDetails.iVersion.Copy(*iVersion); + } + + if (iDescription == 0) + { + aDetails.iDescription.SetLength(0); + } + else + { + if (iDescription->Length() > aDetails.iDescription.MaxLength()) + { + DEBUG_LOG(_L("iDescription too long")); + User::Leave(KErrOverflow); + } + aDetails.iDescription.Copy(*iDescription); + } + + if (iIssuer == 0) + { + aDetails.iIssuerName.SetLength(0); + } + else + { + if (iIssuer->Length() > aDetails.iIssuerName.MaxLength()) + { + DEBUG_LOG(_L("iIssuer too long")); + User::Leave(KErrOverflow); + } + aDetails.iIssuerName.Copy(*iIssuer); + } + + if (iContact == 0) + { + aDetails.iContactInfo.SetLength(0); + } + else + { + if (iContact->Length() > aDetails.iContactInfo.MaxLength()) + { + DEBUG_LOG(_L("iContact too long")); + User::Leave(KErrOverflow); + } + aDetails.iContactInfo.Copy(*iContact); + } + } + +void CDmAdPolicyData::ContentRestoreL(const TDesC8& aContent) + { + TRACE("CDmAdPolicyData::ContentRestoreL"); + + delete iContent; + iContent = NULL; + if (aContent.Length() > 0) + { + iContent = aContent.AllocL(); + } + } + +TPtrC8 CDmAdPolicyData::ContentToStore(void) + { + TRACE("CDmAdPolicyData::ContentToStore"); + + TPtrC8 ret(KNullDesC8); + if (iContent != 0) + { + ret.Set(*iContent); + } + return ret; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/src/DmAdStore.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/src/DmAdStore.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,479 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CDmAdStore. +* +*/ + + + +#include "DmAdStore.h" +#include "DmAdRtNodeData.h" +#include "dmadutil.h" +#include "vpnlogger.h" + +#include + +CDmAdStore* CDmAdStore::NewL(void) + { + TRACE("CDmAdStore::NewL"); + + CDmAdStore *self = new (ELeave) CDmAdStore(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); // self + return self; + } + +void CDmAdStore::ConstructL(void) + { + TRACE("CDmAdStore::ConstructL"); + + INIT_EVENT_LOGGER; + + User::LeaveIfError(iVpnApi.Connect()); + iVpnAp = CVpnAp::NewL(); + } + +CDmAdStore::CDmAdStore() + { + } + +CDmAdStore::~CDmAdStore() + { + TRACE("CDmAdStore::~CDmAdStore"); + + iVpnApi.Close(); + delete iVpnAp; + + RELEASE_EVENT_LOGGER; + } + +TBool CDmAdStore::FindRtNodeL(const TDesC8& aLuid, const TDesC8& aUri) + { + TRACE("CDmAdStore::FindRtNodeL"); + + TDmAdUriType uriType = CDmAdRtNodeData::UriTypeL(aUri); + switch (uriType) + { + case EDmAdUriTypeVpnAp: + return VpnApFindRtNodeL(aLuid, aUri); + case EDmAdUriTypePolicy: + return PolicyFindRtNodeL(aLuid, aUri); + default: + DEBUG_LOG(_L("Unknown URI type")); + User::Leave(KErrGeneral); + return EFalse; + } + } + +void CDmAdStore::LuidListL(const TDesC8& aUri, const TDesC8& /*aLuid*/, RPointerArray& aLuidList) + { + TDmAdUriType uriType = CDmAdRtNodeData::UriTypeL(aUri); + switch (uriType) + { + case EDmAdUriTypeVpnAp: + VpnApLuidListL(aLuidList); + break; + case EDmAdUriTypePolicy: + PolicyLuidListL(aLuidList); + break; + default: + DEBUG_LOG(_L("Unknown URI type")); + User::Leave(KErrGeneral); + break; + } + } + +void CDmAdStore::FetchRtNodeL(CDmAdRtNode& aRtNode) + { + TRACE("CDmAdStore::FetchRtNodeL"); + + TDmAdUriType uriType = aRtNode.Data()->UriType(); + switch (uriType) + { + case EDmAdUriTypeVpnAp: + VpnApFetchRtNodeL(aRtNode); + break; + case EDmAdUriTypePolicy: + PolicyFetchRtNodeL(aRtNode); + break; + default: + DEBUG_LOG(_L("Unknown URI type")); + User::Leave(KErrGeneral); + break; + } + } + +void CDmAdStore::SaveTopLevelRtNodeL(CDmAdRtNode& aRtNode, CArrayPtr& aChildRtNodes) + { + TRACE("CDmAdStore::SaveTopLevelRtNodeL"); + + TDmAdUriType uriType = aRtNode.Data()->UriType(); + switch (uriType) + { + case EDmAdUriTypeVpnAp: + VpnApSaveTopLevelRtNodeL(aRtNode, aChildRtNodes); + break; + case EDmAdUriTypePolicy: + PolicySaveTopLevelRtNodeL(aRtNode, aChildRtNodes); + break; + default: + DEBUG_LOG(_L("Unknown URI type")); + User::Leave(KErrGeneral); + break; + } + } + +void CDmAdStore::SaveChildLevelRtNodeL(CDmAdRtNode& /*aRtNode*/) + { + TRACE("CDmAdStore::SaveChildLevelRtNodeL"); + User::Leave(KErrGeneral); + } + + +void CDmAdStore::DeleteRtNodeL(const TDesC8& aLuid, const TDesC8& aUri) + { + TRACE("CDmAdStore::DeleteRtNodeL"); + + TDmAdUriType uriType = CDmAdRtNodeData::UriTypeL(aUri); + switch (uriType) + { + case EDmAdUriTypeVpnAp: + VpnApDeleteRtNodeL(aLuid); + break; + case EDmAdUriTypePolicy: + PolicyDeleteRtNodeL(aLuid); + break; + default: + DEBUG_LOG(_L("Unknown URI type")); + User::Leave(KErrGeneral); + break; + } + } + +//========================================================================= +//========================================================================= + +TBool CDmAdStore::VpnApFindRtNodeL(const TDesC8& aLuid, const TDesC8& aUri) + { + TRACE("CDmAdStore::VpnApFindRtNodeL"); + + (void)aUri; + TBool ret = EFalse; + if (aLuid.Length() > 0) + { + if (iVpnAp->FindVpnApL(TDmAdUtil::DesToInt(aLuid))) + { + ret = ETrue; + } + } + return ret; + } + +void CDmAdStore::VpnApLuidListL(RPointerArray& aLuidList) + { + + TRACE("CDmAdStore::VpnApLuidListL"); + + RArray idArray; + CleanupClosePushL(idArray); + iVpnAp->ListVpnApsL(idArray); + + for (TInt i=0; iVpnApData(); + TVpnApParms* vpnApParms = new (ELeave) TVpnApParms(); + CleanupStack::PushL(vpnApParms); + iVpnAp->GetVpnApL(TDmAdUtil::DesToInt(luid), *vpnApParms); + data->RestoreL(*vpnApParms); + CleanupStack::PopAndDestroy(); //vpnApParms + } + +void CDmAdStore::VpnApSaveTopLevelRtNodeL(CDmAdRtNode& aRtNode, CArrayPtr& aChildRtNodes) + { + TRACE("CDmAdStore::VpnApSaveTopLevelRtNodeL"); + + if (aChildRtNodes.Count() > 0) + { + DEBUG_LOG(_L("aChildRtNodes.Count() > 0")); + User::Leave(KErrGeneral); + } + + if (aRtNode.IsJustFetched()) + { + return; + } + + CDmAdVpnApData* data = aRtNode.Data()->VpnApData(); + + TVpnApParms* vpnApParms = new (ELeave) TVpnApParms(); + CleanupStack::PushL(vpnApParms); + data->ToStoreL(*vpnApParms); + + + //Check the policy existence. + //It is possible to set the policyId to be empty, but + //if the policyId is set it has to be found. + if ( vpnApParms->iPolicyId.Length() > 0) + { + CArrayFixFlat* policyInfoList = new (ELeave) CArrayFixFlat(2); + CleanupStack::PushL(policyInfoList); + User::LeaveIfError(iVpnApi.GetPolicyInfoList(policyInfoList)); + + TBool policyFound = EFalse; + for (TInt i = 0; i < policyInfoList->Count(); ++i) + { + const TVpnPolicyInfo& info = (*policyInfoList)[i]; + if (info.iId.Compare(vpnApParms->iPolicyId) == 0) + { + policyFound = ETrue; + break; + } + } + CleanupStack::PopAndDestroy(policyInfoList); + if (!policyFound) + { + DEBUG_LOG1(_L("Policy with id %S not found"), &(vpnApParms->iPolicyId)); + User::Leave(KErrGeneral); + } + } + + if (aRtNode.IsSomeLeafAddedToRtNode()) + { + + TUint32 id = iVpnAp->AddVpnApL(*vpnApParms); + + TBuf buf; + buf.Copy(vpnApParms->iPolicyId); + + if (vpnApParms->iRealConnRefType == TVpnApParms::EIapRealConnRef) + { + LOG_EVENT(iVpnApi, R_VPN_MSG_CREATED_VPN_ACCESS_POINT_WITH_AP, &buf, + id, vpnApParms->iRealConnRef); + } + else //Connection type is SNAP + { + __ASSERT_DEBUG(vpnApParms->iRealConnRefType == TVpnApParms::ESnapRealConnRef, User::Invariant()); + LOG_EVENT(iVpnApi, R_VPN_MSG_CREATED_VPN_ACCESS_POINT_WITH_SNAP, &buf, + id, vpnApParms->iRealConnRef); + + } + + HBufC8* luid = TDmAdUtil::IntToDes8LC(id); + aRtNode.SetLuidL(*luid); + CleanupStack::PopAndDestroy(); //luid + } + else + { + TPtrC8 luid(aRtNode.Luid()); + iVpnAp->UpdateVpnApL(TDmAdUtil::DesToInt(luid), *vpnApParms); + } + + CleanupStack::PopAndDestroy(); //vpnApParms + } + + +void CDmAdStore::VpnApDeleteRtNodeL(const TDesC8& aLuid) + { + TRACE("CDmAdStore::VpnApDeleteRtNodeL"); + + if (aLuid.Length() == 0) + { + DEBUG_LOG(_L("aLuid length is 0")); + User::Leave(KErrNotFound); + } + + iVpnAp->DeleteVpnApL(TDmAdUtil::DesToInt(aLuid)); + } + +//========================================================================= +//========================================================================= + +TPtrC8 CDmAdStore::PolicyRefToLuid(const TDesC& aPolicyRef) + { + TRACE("CDmAdStore::PolicyRefToLuid"); + + TPtrC8 ret((const TUint8*)aPolicyRef.Ptr(), aPolicyRef.Length() * 2); + return ret; + } + +TPtrC CDmAdStore::LuidToPolicyRef(const TDesC8& aLuid) + { + TRACE("CDmAdStore::LuidToPolicyRef"); + + TPtrC ret((const TUint16*)aLuid.Ptr(), aLuid.Length() / 2); + return ret; + } + +TBool CDmAdStore::PolicyFindRtNodeL(const TDesC8& aLuid, const TDesC8& /*aUri*/) + { + TRACE("CDmAdStore::PolicyFindRtNodeL"); + + TBool ret = EFalse; + if (aLuid.Length() > 0) + { + TVpnPolicyDetails* details = new (ELeave) TVpnPolicyDetails(); + if (iVpnApi.GetPolicyDetails(LuidToPolicyRef(aLuid), *details) == KErrNone) + { + ret = ETrue; + } + delete details; + } + return ret; + } + + +void CDmAdStore::PolicyLuidListL(RPointerArray& aLuidList) + { + + TRACE("CDmAdStore::PolicyLuidListL"); + + CArrayFixFlat* policyList; + policyList = new (ELeave) CArrayFixFlat(2); + CleanupStack::PushL(policyList); + + User::LeaveIfError(iVpnApi.GetPolicyInfoList(policyList)); + + for (TInt i=0; iCount(); ++i) + { + HBufC8* luidElem = PolicyRefToLuid(policyList->At(i).iId).AllocLC(); + aLuidList.AppendL(luidElem); + CleanupStack::Pop(); // luidElem + } + + CleanupStack::PopAndDestroy(); //policyList + } + + +void CDmAdStore::PolicyFetchRtNodeL(CDmAdRtNode& aRtNode) + { + TRACE("CDmAdStore::PolicyFetchRtNodeL"); + + TPtrC policyRef(LuidToPolicyRef(aRtNode.Luid())); + + if (policyRef.Length() == 0) + { + DEBUG_LOG(_L("policyRef length is 0")); + User::Leave(KErrNotFound); + } + + CDmAdPolicyData* data = aRtNode.Data()->PolicyData(); + + TVpnPolicyDetails* details = new (ELeave) TVpnPolicyDetails(); + CleanupStack::PushL(details); + if (iVpnApi.GetPolicyDetails(policyRef, *details) != KErrNone) + { + DEBUG_LOG(_L("Details not found")); + User::Leave(KErrNotFound); + } + data->DetailsRestoreL(*details); + CleanupStack::PopAndDestroy(); //details + + HBufC8* policyData; + if (iVpnApi.GetPolicyData(policyRef, policyData) != KErrNone) + { + DEBUG_LOG(_L("Policy data not found")); + User::Leave(KErrNotFound); + } + CleanupStack::PushL(policyData); + data->ContentRestoreL(*policyData); + CleanupStack::PopAndDestroy(); //policyData + } + +void CDmAdStore::PolicySaveTopLevelRtNodeL(CDmAdRtNode& aRtNode, CArrayPtr& aChildRtNodes) + { + TRACE("CDmAdStore::PolicySaveTopLevelRtNodeL"); + + if (aChildRtNodes.Count() > 0) + { + DEBUG_LOG(_L("aChildRtNodes.Count() is more than 0")); + User::Leave(KErrGeneral); + } + + if (aRtNode.IsJustFetched()) + { + return; + } + + CDmAdPolicyData* data = aRtNode.Data()->PolicyData(); + + TVpnPolicyDetails* details = new (ELeave) TVpnPolicyDetails(); + CleanupStack::PushL(details); + data->DetailsToStoreL(*details); + + TInt err; + if (aRtNode.IsSomeLeafAddedToRtNode()) + { + if ((err = iVpnApi.AddPolicy(*details, data->ContentToStore())) != KErrNone) + { + DEBUG_LOG1(_L("iVpnApi.AddPolicy failed with %d"), err); + User::Leave(err); + } + aRtNode.SetLuidL(PolicyRefToLuid(details->iId)); + } + else + { + TPtrC policyRef(LuidToPolicyRef(aRtNode.Luid())); + if (policyRef.Compare(details->iId) != 0) + { + DEBUG_LOG(_L("Details Id doesn't match")); + User::Leave(KErrGeneral); + } + if ((err = iVpnApi.UpdatePolicyDetails(*details)) != KErrNone) + { + DEBUG_LOG1(_L("iVpnApi.UpdatePolicyDetails failed with %d"), err); + User::Leave(err); + } + if ((err = iVpnApi.UpdatePolicyData(details->iId, data->ContentToStore())) != KErrNone) + { + DEBUG_LOG1(_L("iVpnApi.UpdatePolicyData failed with %d"), err); + User::Leave(err); + } + } + + CleanupStack::PopAndDestroy(); //details + } + + +void CDmAdStore::PolicyDeleteRtNodeL(const TDesC8& aLuid) + { + TRACE("CDmAdStore::PolicyDeleteRtNodeL"); + + if (aLuid.Length() == 0) + { + DEBUG_LOG(_L("aLuid length is 0")); + User::Leave(KErrNotFound); + } + + User::LeaveIfError(iVpnApi.DeletePolicy(LuidToPolicyRef(aLuid))); + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/src/dmadadapter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/src/dmadadapter.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,263 @@ +/* +* Copyright (c) 2000-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: VPN OMA DM Adapter +* +*/ + + + +#include +#include + +#include "dmadadapter.h" +#include "dmadadapterimplconst.h" +#include "dmadengine.h" +#include "DmAdStore.h" +#include "dmadddf.h" +#include "dmadrtnodedataapic.h" +#include "vpnlogger.h" + +#if defined(_DEBUG) +_LIT(KDmAdLogFolder,"vpn"); +_LIT(KDmAdLogFile,"dmadipsecvpn.txt"); +#endif + + +//=================================================================================================== + +#ifndef IMPLEMENTATION_PROXY_ENTRY +#define IMPLEMENTATION_PROXY_ENTRY(aUid, aFuncPtr) {{aUid},(aFuncPtr)} +#endif + +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY(KDmAdImplUid, CDmAdAdapter::NewL) + }; + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) + { + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); + return ImplementationTable; + } + + +//=================================================================================================== + +CDmAdAdapter* CDmAdAdapter::NewL(MSmlDmCallback* aDmCallback) + { + CDmAdAdapter* self = NewLC(aDmCallback); + CleanupStack::Pop(); + return self; + } + +CDmAdAdapter* CDmAdAdapter::NewLC(MSmlDmCallback* aDmCallback) + { + INITIALIZE_DEBUG_LOG_L(KDmAdLogFolder, KDmAdLogFile); + DEBUG_LOG(_L("LOGGING INITIALIZED")); + + CDmAdAdapter* self = new (ELeave) CDmAdAdapter(aDmCallback); + CleanupStack::PushL(self); + self->ConstructL(aDmCallback); + return self; + } + +void CDmAdAdapter::ConstructL(MSmlDmCallback* aDmCallback) + { + TRACE("CDmAdAdapter::ConstructL"); + + iCallBack = CDmAdCallBack::NewL(aDmCallback, KDmAdOwnAdUriForGetLuidAllocLFix); + iStore = CDmAdStore::NewL(); + iDdf = CDmAdDdf::NewL(iCallBack, iStore); + iRtNodeDataApi = CDmAdRtNodeDataApi::NewL(); + iEngine = CDmAdEngine::NewL(iCallBack, iStore, iDdf, iRtNodeDataApi); + } + +CDmAdAdapter::CDmAdAdapter(MSmlDmCallback* aDmCallback) : + CSmlDmAdapter(aDmCallback) + { + TRACE("CDmAdAdapter::CDmAdAdapter"); + } + +CDmAdAdapter::~CDmAdAdapter() + { + DEBUG_LOG(_L("CDmAdAdapter::~CDmAdAdapter")); + delete iEngine; + delete iRtNodeDataApi; + delete iDdf; + delete iStore; + delete iCallBack; + + DEBUG_LOG(_L("FINALIZING LOGGING")); + FINALIZE_DEBUG_LOG; + } + +//=================================================================================================== + +void CDmAdAdapter::DDFVersionL(CBufBase& aDDFVersion) + { + TRACE("CDmAdAdapter::DDFVersionL"); + iDdf->BuildDDFVersionL(aDDFVersion); + } + +void CDmAdAdapter::DDFStructureL(MSmlDmDDFObject& aDDF) + { + TRACE("CDmAdAdapter::DDFStructureL"); + iDdf->BuildDDFStructureL(aDDF); + } + + +void CDmAdAdapter::ChildURIListL(const TDesC8& aUri, const TDesC8& aParentLuid, const CArrayFix& aPreviousUriSegmentList, TInt aResultsRef, TInt aStatusRef) + { + TRACE("CDmAdAdapter::ChildURIListL"); + DEBUG_LOG1(_L8("aUri = %S"), &aUri); + + iEngine->ChildURIListL(aUri, aParentLuid, aPreviousUriSegmentList, aResultsRef, aStatusRef); + } + +void CDmAdAdapter::AddNodeObjectL(const TDesC8& aUri, const TDesC8& aParentLuid, TInt aStatusRef) + { + TRACE("CDmAdAdapter::AddNodeObjectL"); + + DEBUG_LOG1(_L8("aUri = %S"), &aUri); + DEBUG_LOG1(_L8("aParentLuid = %S"), &aParentLuid); + DEBUG_LOG1(_L("aStatusRef = %d"), aStatusRef); + + iEngine->AddNodeObjectL(aUri, aParentLuid, aStatusRef); + } + +void CDmAdAdapter::UpdateLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aObject, const TDesC8& aType, TInt aStatusRef) + { + TRACE("CDmAdAdapter::UpdateLeafObjectL"); + + DEBUG_LOG1(_L8("aUri = %S"), &aUri); + DEBUG_LOG1(_L8("aLuid = %S"), &aLuid); + DEBUG_LOG(_L8("aObject:")); + DEBUG_LOG_HEX(aObject); + DEBUG_LOG1(_L8("aType = %S"), &aType); + DEBUG_LOG1(_L("aStatusRef = %d"), aStatusRef); + + iEngine->UpdateLeafObjectL(aUri, aLuid, aObject, aType, aStatusRef); + } + +void CDmAdAdapter::FetchLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aType, TInt aResultsRef, TInt aStatusRef) + { + TRACE("CDmAdAdapter::FetchLeafObjectL"); + DEBUG_LOG1(_L8("aUri = %S"), &aUri); + + iEngine->FetchLeafObjectL(aUri, aLuid, aType, aResultsRef, aStatusRef); + } + +void CDmAdAdapter::DeleteObjectL(const TDesC8& aUri, const TDesC8& aLuid, TInt aStatusRef) + { + TRACE("CDmAdAdapter::DeleteObjectL"); + DEBUG_LOG1(_L8("aUri = %S"), &aUri); + + iEngine->DeleteObjectL(aUri, aLuid, aStatusRef); + } + +void CDmAdAdapter::CompleteOutstandingCmdsL() + { + TRACE("CDmAdAdapter::CompleteOutstandingCmdsL"); + iEngine->CompleteOutstandingCmdsL(); + } + +void CDmAdAdapter::UpdateLeafObjectL(const TDesC8& aUri, + const TDesC8& aLuid, + RWriteStream*& aStream, + const TDesC8& aType, + TInt aStatusRef) + { + TRACE("CDmAdAdapter::UpdateLeafObjectL"); + iEngine->UpdateLeafObjectL(aUri, aLuid, aStream, aType, aStatusRef); + } + +void CDmAdAdapter::FetchLeafObjectSizeL(const TDesC8& aUri, + const TDesC8& aLuid, + const TDesC8& aType, + TInt aResultsRef, + TInt aStatusRef) + { + TRACE("CDmAdAdapter::FetchLeafObjectSizeL"); + DEBUG_LOG1(_L8("aUri = %S"), &aUri); + + iEngine->FetchLeafObjectSizeL(aUri, aLuid, aType, aResultsRef, aStatusRef); + } + +void CDmAdAdapter::ExecuteCommandL(const TDesC8& aUri, + const TDesC8& aLuid, + const TDesC8& aArgument, + const TDesC8& aType, + TInt aStatusRef) + { + TRACE("CDmAdAdapter::ExecuteCommandL"); + DEBUG_LOG1(_L8("aUri = %S"), &aUri); + + iEngine->ExecuteCommandL(aUri, aLuid, aArgument, aType, aStatusRef); + } + +void CDmAdAdapter::ExecuteCommandL(const TDesC8& aUri, + const TDesC8& aLuid, + RWriteStream*& aStream, + const TDesC8& aType, + TInt aStatusRef) + { + TRACE("CDmAdAdapter::ExecuteCommandL"); + DEBUG_LOG1(_L8("aUri = %S"), &aUri); + + iEngine->ExecuteCommandL(aUri, aLuid, aStream, aType, aStatusRef); + } + +void CDmAdAdapter::CopyCommandL(const TDesC8& aTargetUri, + const TDesC8& aTargetLuid, + const TDesC8& aSourceUri, + const TDesC8& aSourceLuid, + const TDesC8& aType, + TInt aStatusRef) + { + TRACE("CDmAdAdapter::CopyCommandL"); + + iEngine->CopyCommandL(aTargetUri, aTargetLuid, aSourceUri, aSourceLuid, aType, aStatusRef); + } + +void CDmAdAdapter::StartAtomicL() + { + TRACE("CDmAdAdapter::StartAtomicL"); + iEngine->StartAtomicL(); + } + +void CDmAdAdapter::CommitAtomicL() + { + TRACE("CDmAdAdapter::CommitAtomicL"); + iEngine->CommitAtomicL(); + } + +void CDmAdAdapter::RollbackAtomicL() + { + TRACE("CDmAdAdapter::RollbackAtomicL"); + iEngine->RollbackAtomicL(); + } + +TBool CDmAdAdapter::StreamingSupport(TInt& aItemSize) + { + TRACE("CDmAdAdapter::StreamingSupport"); + return iEngine->StreamingSupport(aItemSize); + } + +void CDmAdAdapter::StreamCommittedL() + { + TRACE("CDmAdAdapter::StreamCommittedL"); + iEngine->StreamCommittedL(); + } + + diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/src/dmadddf.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/src/dmadddf.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,546 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CDmAdDdf. +* +*/ + + +#include + +#include "dmadddf.h" +#include "dmadeventlog.h" +#include "dmadutil.h" +#include "vpnlogger.h" + +CDmAdDdf* CDmAdDdf::NewL(MDmAdCallBack* aDmAdCallBack, CDmAdStore* aStore) + { + TRACE("CDmAdDdf::NewL"); + + CDmAdDdf* self = NewLC(aDmAdCallBack, aStore); + CleanupStack::Pop(); + return self; + } + +CDmAdDdf* CDmAdDdf::NewLC(MDmAdCallBack* aDmAdCallBack, CDmAdStore* aStore) + { + CDmAdDdf* self = new (ELeave) CDmAdDdf(aDmAdCallBack, aStore); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +void CDmAdDdf::ConstructL(void) + { + TRACE("CDmAdDdf::ConstructL"); + } + +CDmAdDdf::CDmAdDdf(MDmAdCallBack* aDmAdCallBack, CDmAdStore* aStore) : + iCallBack(aDmAdCallBack), iStore(aStore) + { + TRACE("CDmAdDdf::CDmAdDdf"); + } + +CDmAdDdf::~CDmAdDdf() + { + TRACE("CDmAdDdf::~CDmAdDdf"); + } + +//=================================================================================================== + +void CDmAdDdf::BuildDDFVersionL(CBufBase& aDDFVersion) + { + TRACE("CDmAdDdf::BuildDDFVersionL"); + aDDFVersion.InsertL(0, KDmAdDdfVersion); + } + +void CDmAdDdf::BuildDDFStructureL(MSmlDmDDFObject& aDDF) + { + TRACE("CDmAdDdf::BuildDDFStructureL"); + + TSmlDmAccessTypes accessTypesExec; + accessTypesExec.SetReplace(); // accessTypesExec.SetExec(); + + TSmlDmAccessTypes accessTypesGet; + accessTypesGet.SetGet(); + + TSmlDmAccessTypes accessTypesAdd; + accessTypesAdd.SetAdd(); + + TSmlDmAccessTypes accessTypesGetAdd; + accessTypesGetAdd.SetGet(); + accessTypesGetAdd.SetAdd(); + + TSmlDmAccessTypes accessTypesGetDelete; + accessTypesGetDelete.SetGet(); + accessTypesGetDelete.SetDelete(); + + TSmlDmAccessTypes accessTypesAll; + accessTypesAll.SetGet(); + accessTypesAll.SetAdd(); + accessTypesAll.SetDelete(); + accessTypesAll.SetReplace(); + + TSmlDmAccessTypes accessTypesNoDelete; + accessTypesNoDelete.SetGet(); + accessTypesNoDelete.SetAdd(); + accessTypesNoDelete.SetReplace(); + + MSmlDmDDFObject* obj; + MSmlDmDDFObject* objNokiaIpSecVpn; + MSmlDmDDFObject* objIpSecVpnGeneral; + MSmlDmDDFObject* objPolicy; + MSmlDmDDFObject* objPolicyX; + MSmlDmDDFObject* objAp; + MSmlDmDDFObject* objApX; + MSmlDmDDFObject* objApXPolicyRef; + +//---------------------------------------------------------------- + + objNokiaIpSecVpn = &TDmAdUtil::AddChildObjectL(aDDF, KDmAdNodeNokiaIpSecVpn); + TDmAdUtil::FillNodeInfoL(*objNokiaIpSecVpn, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EPermanent, + MSmlDmDDFObject::ENode, + KDmAdDescNodeNokiaIpSecVpn, + ETrue, + KDmAdNokiaIpSecVpnRootTypeProperty); + +//---------------------------------------------------------------- + + objIpSecVpnGeneral = &TDmAdUtil::AddChildObjectL(*objNokiaIpSecVpn, KDmAdNodeGeneral); + TDmAdUtil::FillNodeInfoL(*objIpSecVpnGeneral, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EPermanent, + MSmlDmDDFObject::ENode, + KDmAdDescNodeGeneral, + EFalse, + KNullDesC8); + + obj = &TDmAdUtil::AddChildObjectL(*objIpSecVpnGeneral, KDmAdLeafClientVersion); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafClientVersion, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objIpSecVpnGeneral, KDmAdLeafEventLog); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGetDelete, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBin, + KDmAdDescLeafEventLog, + EFalse); + +//---------------------------------------------------------------- + + objPolicy = &TDmAdUtil::AddChildObjectL(*objNokiaIpSecVpn, KDmAdNodePolicy); + TDmAdUtil::FillNodeInfoL(*objPolicy, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EPermanent, + MSmlDmDDFObject::ENode, + KDmAdDescNodePolicy, + EFalse, + KNullDesC8); + + + objPolicyX = &TDmAdUtil::AddChildObjectL(*objPolicy, KDmAdNodeRt); + TDmAdUtil::FillNodeInfoL(*objPolicyX, + accessTypesAll, + MSmlDmDDFObject::EZeroOrMore, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::ENode, + KDmAdDescNodeRt, + EFalse, + KNullDesC8); + + obj = &TDmAdUtil::AddChildObjectL(*objPolicyX, KDmAdLeafName); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesNoDelete, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafName, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objPolicyX, KDmAdLeafId); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGetAdd, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafId, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objPolicyX, KDmAdLeafVersion); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesNoDelete, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafVersion, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objPolicyX, KDmAdLeafDescription); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesNoDelete, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafDescription, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objPolicyX, KDmAdLeafIssuer); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesNoDelete, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafIssuer, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objPolicyX, KDmAdLeafContact); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesNoDelete, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafContact, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objPolicyX, KDmAdLeafContent); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesNoDelete, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBin, + KDmAdDescLeafContent, + EFalse); + + +//---------------------------------------------------------------- + + objAp = &TDmAdUtil::AddChildObjectL(*objNokiaIpSecVpn, KDmAdNodeAp); + TDmAdUtil::FillNodeInfoL(*objAp, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EPermanent, + MSmlDmDDFObject::ENode, + KDmAdDescNodeAp, + EFalse, + KNullDesC8); + + + objApX = &TDmAdUtil::AddChildObjectL(*objAp, KDmAdNodeRt); + TDmAdUtil::FillNodeInfoL(*objApX, + accessTypesAll, + MSmlDmDDFObject::EZeroOrMore, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::ENode, + KDmAdDescNodeRt, + EFalse, + KNullDesC8); + + obj = &TDmAdUtil::AddChildObjectL(*objApX, KDmAdLeafName); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesNoDelete, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafName, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objApX, KDmAdLeafThisRef); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafThisRef, + EFalse); + + objApXPolicyRef = &TDmAdUtil::AddChildObjectL(*objApX, KDmAdNodePolicyRef); + TDmAdUtil::FillNodeInfoL(*objApXPolicyRef, + accessTypesGetAdd, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::ENode, + KDmAdDescNodePolicyRef, + EFalse, + KNullDesC8); + + obj = &TDmAdUtil::AddChildObjectL(*objApXPolicyRef, KDmAdLeafId); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesNoDelete, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafId, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objApXPolicyRef, KDmAdLeafUri); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafUri, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objApX, KDmAdLeafConRef); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesNoDelete, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafConRef, + EFalse); + + } + +//--------------------------------------------------------------------------------------- + +void CDmAdDdf::NotRtNodeAddNodeObjectL(const TDesC8& /*aUri*/, + const TDesC8& /*aParentLuid*/, + TInt aStatusRef) + { + TRACE("CDmAdDdf::NotRtNodeAddNodeObjectL"); + iCallBack->SetStatusL(aStatusRef, KErrNone); + } + +void CDmAdDdf::NotRtNodeUpdateLeafObjectL(const TDesC8& /*aUri*/, + const TDesC8& /*aLuid*/, + const TDesC8& /*aObject*/, + const TDesC8& /*aType*/, + TInt aStatusRef) + { + TRACE("CDmAdDdf::NotRtNodeUpdateLeafObjectL"); + iCallBack->SetStatusL(aStatusRef, KErrNone); + } + +TInt CDmAdDdf::NotRtNodeFetchLeafObjectLC(const TDesC8& aUri, + const TDesC8& /*aLuid*/, + const TDesC8& /*aType*/, + CBufBase*& aObject) + { + TInt status = KErrNotFound; + CBufBase* object = CBufFlat::NewL(32); + CleanupStack::PushL(object); + + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdLeafClientVersion) == 0) + { + HBufC8* version = CnvUtfConverter::ConvertFromUnicodeToUtf8L(KVersion); + CleanupStack::PushL(version); + object->InsertL(0, *version); + CleanupStack::PopAndDestroy(); //version + status = KErrNone; + } + else if (lastSeg.Compare(KDmAdLeafEventLog) == 0) + { + TDmAdEventLog::EventLogL(*object); + status = KErrNone; + } + aObject = object; + return status; + } + +void CDmAdDdf::NotRtNodeDeleteObjectL(const TDesC8& aUri, + const TDesC8& /*aLuid*/, + TInt aStatusRef) + { + TRACE("CDmAdDdf::NotRtNodeDeleteObjectL"); + + TInt status = KErrNone; //KErrNotFound; + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdLeafEventLog) == 0) + { + TDmAdEventLog::DeleteLogL(); + status = KErrNone; + } + iCallBack->SetStatusL(aStatusRef, status); + } + +//--------------------------------------------------------------------------------------- + +TBool CDmAdDdf::IsNodeRtNodeL(const TDesC8& aUri) + { + TRACE("CDmAdDdf::IsNodeRtNodeL"); + + TBool ret = EFalse; + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + + if (lastSeg.Compare(KDmAdLeafEventLog) == 0) // for DeleteObjectL: In this case this method is called also when URI is leaf (not always node) + { + return EFalse; + } + + if (lastSeg.Compare(KDmAdNodeNokiaIpSecVpn) == 0 || + lastSeg.Compare(KDmAdNodeGeneral) == 0 || + lastSeg.Compare(KDmAdNodePolicy) == 0 || + lastSeg.Compare(KDmAdNodeAp) == 0 || + lastSeg.Compare(KDmAdNodePolicyRef) == 0) + { + ret = EFalse; + } + else + { + if (TDmAdUtil::NumOfURISegs(aUri) < 2) + { + DEBUG_LOG(_L("Node not found")); + User::Leave(KErrNotFound); + } + TPtrC8 prevSeg = TDmAdUtil::LastUriSeg(TDmAdUtil::RemoveLastUriSeg(aUri)); + if (prevSeg.Compare(KDmAdNodePolicy) == 0 || + prevSeg.Compare(KDmAdNodeAp) == 0) + { + ret = ETrue; + } + else + { + DEBUG_LOG(_L("Node not found")); + User::Leave(KErrNotFound); + } + } + return ret; + } + +TBool CDmAdDdf::IsLeafUnderRtNodeL(const TDesC8& aUri) + { + TRACE("CDmAdDdf::IsLeafUnderRtNodeL"); + + TBool ret = EFalse; + TPtrC8 nodeUri(TDmAdUtil::RemoveLastUriSeg(aUri)); + ret = IsNodeRtNodeL(nodeUri); + if (!ret) + { + TPtrC8 nodeUriSeg = TDmAdUtil::LastUriSeg(nodeUri); + if (nodeUriSeg.Compare(KDmAdNodePolicyRef) == 0) + { + ret = ETrue; + } + } + return ret; + } + +TPtrC8 CDmAdDdf::RtNodeUriForLeafL(const TDesC8& aLeafUri) + { + TRACE("CDmAdDdf::RtNodeUriForLeafL"); + + TPtrC8 ret; + TPtrC8 nodeUri(TDmAdUtil::RemoveLastUriSeg(aLeafUri)); + TPtrC8 nodeUriSeg(TDmAdUtil::LastUriSeg(nodeUri)); + TPtrC8 prevNodeUri(TDmAdUtil::RemoveLastUriSeg(nodeUri)); + TPtrC8 prevNodeUriSeg(TDmAdUtil::LastUriSeg(prevNodeUri)); + + if (prevNodeUriSeg.Compare(KDmAdNodePolicy) == 0 || + prevNodeUriSeg.Compare(KDmAdNodeAp) == 0) + { + ret.Set(nodeUri); + } + else if (nodeUriSeg.Compare(KDmAdNodePolicyRef) == 0) + { + ret.Set(prevNodeUri); + } + else + { + DEBUG_LOG(_L("Node not found")); + User::Leave(KErrNotFound); + } + return ret; + } + +TBool CDmAdDdf::IsTopLevelRtNode(const TDesC8& aUri) + { + TRACE("CDmAdDdf::IsTopLevelRtNode"); + + (void)aUri; + return ETrue; + } + +HBufC8* CDmAdDdf::ParentRtNodeUriForRtNodeLC(const TDesC8& /*aUri*/) + { + DEBUG_LOG(_L("CDmAdDdf::ParentRtNodeUriForRtNodeLC method not implemented")); + User::Leave(KErrGeneral); + return NULL; + } + +//--------------------------------------------------------------------------------------- + +void CDmAdDdf::BuildChildUriListLC(const TDesC8& aUri, + const TDesC8& aParentLuid, + const CArrayFix& aPreviousUriSegmentList, + CBufBase*& aCurrentList) + { + CBufBase* currentList = CBufFlat::NewL(128); + CleanupStack::PushL(currentList); + + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdNodeNokiaIpSecVpn) == 0) + { + currentList->InsertL(0, KDmAdListOfNokiaIpSecVpnChildren); + } + else if (lastSeg.Compare(KDmAdNodeGeneral) == 0) + { + currentList->InsertL(0, KDmAdListOfIpSecVpnGeneralChildren); + } + else if (lastSeg.Compare(KDmAdNodePolicyRef) == 0) + { + if (!iStore->FindRtNodeL(aParentLuid, aUri)) + { + DEBUG_LOG(_L("Node not found")); + User::Leave(KErrNotFound); + } + currentList->InsertL(0, KDmAdListOfPolicyRefChildren); + } + else if (lastSeg.Compare(KDmAdNodePolicy) == 0 || + lastSeg.Compare(KDmAdNodeAp) == 0) + { + TDmAdUtil::BuildRtNodeChildUriListL(iCallBack, iStore, aUri, aParentLuid, aPreviousUriSegmentList, *currentList); + } + else + { + TPtrC8 prevSeg = TDmAdUtil::LastUriSeg(TDmAdUtil::RemoveLastUriSeg(aUri)); + if (prevSeg.Compare(KDmAdNodePolicy) == 0 || + prevSeg.Compare(KDmAdNodeAp) == 0) + { + if (!iStore->FindRtNodeL(aParentLuid, aUri)) + { + DEBUG_LOG(_L("Node not found")); + User::Leave(KErrNotFound); + } + + if (prevSeg.Compare(KDmAdNodePolicy) == 0) + { + currentList->InsertL(0, KDmAdListOfPolicyXChildren); + } + else if (prevSeg.Compare(KDmAdNodeAp) == 0) + { + currentList->InsertL(0, KDmAdListOfApXChildren); + } + } + else + { + DEBUG_LOG(_L("Node not found")); + User::Leave(KErrNotFound); + } + } + + aCurrentList = currentList; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/src/dmadeventlog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/src/dmadeventlog.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,217 @@ +/* +* Copyright (c) 2000 - 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of TDmAdEventLog. +* +*/ + + +#include +#include +#include "vpnlogger.h" + +//#include +//#include + +#include "dmadeventlog.h" + +// "dd/mm/yyyy0" +const TInt KDmAdMaxLengthTextDateString = 11; + +void TDmAdEventLog::DeleteLogL(void) + { + TRACE("TDmAdEventLog::DeleteLogL"); + + CEventViewer* eventViewer = CEventViewer::NewL(); + CleanupStack::PushL(eventViewer); + User::LeaveIfError(eventViewer->DeleteLogFile()); + CleanupStack::PopAndDestroy(); //eventViewer + } + +void TDmAdEventLog::EventLogL(CBufBase& aEventLog) + { + + TRACE("TDmAdEventLog::EventLogL"); +/* + _LIT(KResourceFileVpnLog, "\\resource\\vpnmanagementui.rsc"); + _LIT(KResourceFileAvkon, "\\resource\\avkon.rsc"); +*/ + + CEventViewer* eventViewer = 0; + TRAPD(err, eventViewer = CEventViewer::NewL()); + if (err == KErrNotFound) + { + return; + } + User::LeaveIfError(err); + CleanupStack::PushL(eventViewer); + + RFs fs; + CleanupClosePushL(fs); + User::LeaveIfError(fs.Connect()); + + RResourceFile resourceFileVpnLog; + CleanupClosePushL(resourceFileVpnLog); + + RResourceFile resourceFileAvkon; + CleanupClosePushL(resourceFileAvkon); + + //OpenResourceFileL(fs, resourceFileVpnLog, KResourceFileVpnLog); + //OpenResourceFileL(fs, resourceFileAvkon, KResourceFileAvkon); + + TEventProperties eventProperties; + HBufC* eventText = NULL; + + TInt ret = eventViewer->GetMostRecentEvent(eventText, eventProperties); + while (ret == KErrNone) + { + CleanupStack::PushL(eventText); + + TBuf<2 * KDmAdMaxLengthTextDateString + 3> timeBuf; + FormatTimeL(resourceFileAvkon, timeBuf, eventProperties.iTimeStamp); + + HBufC* categoryText = CategoryTextLC(resourceFileVpnLog, eventProperties.iCategory); + + _LIT(KDmAdCr, "\n"); + _LIT(KDmAdSpace, " "); + HBufC* messageText = HBufC::NewLC(timeBuf.Length() + + KDmAdCr().Length() + + categoryText->Length() + + KDmAdSpace().Length() + + eventText->Length() + + KDmAdCr().Length()); + messageText->Des().Copy(timeBuf); + messageText->Des().Append(KDmAdCr); + messageText->Des().Append(*categoryText); + messageText->Des().Append(KDmAdSpace); + messageText->Des().Append(*eventText); + messageText->Des().Append(KDmAdCr); + + HBufC8* messageText8 = CnvUtfConverter::ConvertFromUnicodeToUtf8L(*messageText); + CleanupStack::PushL(messageText8); + aEventLog.InsertL(aEventLog.Size(), *messageText8); + + CleanupStack::PopAndDestroy(4); // messageText8, messageText, categoryText, eventText + + ret = eventViewer->GetPreviousEvent(eventText, eventProperties); + } + CleanupStack::PopAndDestroy(4); //resourceFileAvkon, resourceFileVpnLog, fs, eventViewer + } + +void TDmAdEventLog::FormatTimeL(RResourceFile& aResourceFile, TDes& aDateTimeText, TTime aTime) + { + TRACE("TDmAdEventLog::FormatTimeL"); + + (void)aResourceFile; + _LIT(KDmAdDateFromat, "%D%M%Y%/0%1%/1%2%/2%3%/3"); + _LIT(KDmAdTimeFromat, "%-B%:0%J%:1%T%:3%+B"); + + // Date + HBufC* dateFormat = KDmAdDateFromat().AllocLC(); + //HBufC* dateFormat = ReadResourceLC(aResourceFile, R_QTN_DATE_USUAL_WITH_ZERO); + //HBufC* dateFormat = StringLoader::LoadLC(R_QTN_DATE_USUAL_WITH_ZERO); + TBuf dateString; + aTime.FormatL(dateString, *dateFormat); + CleanupStack::PopAndDestroy(); //dateFormat + + // Time + dateFormat = KDmAdTimeFromat().AllocLC(); + //dateFormat = ReadResourceLC(aResourceFile, R_QTN_TIME_USUAL_WITH_ZERO); + //dateFormat = StringLoader::LoadLC(R_QTN_TIME_USUAL_WITH_ZERO); + TBuf timeString; + aTime.FormatL(timeString, *dateFormat); + CleanupStack::PopAndDestroy(); //dateFormat + + TBuf<2 * KDmAdMaxLengthTextDateString + 3> timeBuf; + + /* + TTime now; + now.HomeTime(); + if ( (now.YearsFrom(aTime).Int() > 0) || + (aTime.DayNoInYear() < now.DayNoInYear())) + { + timeBuf.Append(dateString); + _LIT(KDmAdSpaceHyphenSpace, " - "); + timeBuf.Append(KDmAdSpaceHyphenSpace); + } + */ + + timeBuf.Append(dateString); + _LIT(KDmAdSpaceHyphenSpace, " - "); + timeBuf.Append(KDmAdSpaceHyphenSpace); + + timeBuf.Append(timeString); + aDateTimeText = timeBuf; + } + +HBufC* TDmAdEventLog::CategoryTextLC(RResourceFile& aResourceFile, TLogCategory2 aCategory) + { + (void)aResourceFile; + HBufC* categoryText = NULL; + _LIT(KDmAdInfo, "Information:"); + _LIT(KDmAdWarning, "Warning:"); + _LIT(KDmAdError, "Error:"); + + if (aCategory == ELogInfo) + { + categoryText = KDmAdInfo().AllocLC(); + //categoryText = ReadResourceLC(aResourceFile, R_VPN_DETAIL_LOG_ENTRY_INFO); + //categoryText = StringLoader::LoadLC(R_VPN_DETAIL_LOG_ENTRY_INFO); + } + else if (aCategory == ELogWarning) + { + categoryText = KDmAdWarning().AllocLC(); + //categoryText = ReadResourceLC(aResourceFile, R_VPN_DETAIL_LOG_ENTRY_WARNING); + //categoryText = StringLoader::LoadLC(R_VPN_DETAIL_LOG_ENTRY_WARNING); + } + else // ELogError (or ELogDebug) + { + categoryText = KDmAdError().AllocLC(); + //categoryText = ReadResourceLC(aResourceFile, R_VPN_DETAIL_LOG_ENTRY_ERROR); + //categoryText = StringLoader::LoadLC(R_VPN_DETAIL_LOG_ENTRY_ERROR); + } + return categoryText; + } + +void TDmAdEventLog::OpenResourceFileL(RFs& aFs, RResourceFile& aResourceFile, const TDesC& aFilename) + { + TRACE("TDmAdEventLog::OpenResourceFileL"); + + TFileName resourceFileName; + TFileName dllName; + + Dll::FileName(dllName); + TBuf<2> drive = dllName.Left(2); // always z: for ... ? + + resourceFileName.Copy(drive); + resourceFileName.Append(aFilename); + + aResourceFile.OpenL(aFs, resourceFileName); + aResourceFile.ConfirmSignatureL(); + } + +HBufC* TDmAdEventLog::ReadResourceLC(RResourceFile& aResourceFile, TInt aMsgId) + { + HBufC8* resourceBuf = aResourceFile.AllocReadLC(aMsgId); + + TResourceReader resourceReader; + resourceReader.SetBuffer(resourceBuf); + + HBufC* textDataBuf = HBufC::NewL(resourceBuf->Length()); + resourceReader.Read((void*)textDataBuf->Ptr(), resourceBuf->Length()); + textDataBuf->Des().SetLength(resourceBuf->Length()/2); + + CleanupStack::PopAndDestroy(); // resourceBuf + CleanupStack::PushL(textDataBuf); + return textDataBuf; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/src/dmadrtnodedataapi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/src/dmadrtnodedataapi.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,104 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CDmAdRtNodeDataApi. +* +*/ + + +#include "dmadrtnodedataapic.h" +#include "DmAdRtNodeData.h" +#include "dmadcallback.h" +#include "vpnlogger.h" + +CDmAdRtNodeDataApi* CDmAdRtNodeDataApi::NewL(void) + { + TRACE("CDmAdRtNodeDataApi::NewL"); + + CDmAdRtNodeDataApi* self = NewLC(); + CleanupStack::Pop(); // self + return self; + } + +CDmAdRtNodeDataApi* CDmAdRtNodeDataApi::NewLC(void) + { + CDmAdRtNodeDataApi* self = new (ELeave) CDmAdRtNodeDataApi(); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +void CDmAdRtNodeDataApi::ConstructL(void) + { + TRACE("CDmAdRtNodeDataApi::ConstructL"); + } + +CDmAdRtNodeDataApi::CDmAdRtNodeDataApi() + { + TRACE("CDmAdRtNodeDataApi::CDmAdRtNodeDataApi"); + } + +CDmAdRtNodeDataApi::~CDmAdRtNodeDataApi() + { + TRACE("CDmAdRtNodeDataApi::~CDmAdRtNodeDataApi"); + } + +//--------------------------------------------------------------------------------------- + +CDmAdRtNodeData* CDmAdRtNodeDataApi::CreateDmAdRtNodeDataL(const TDesC8& aUri, MDmAdCallBack* aCallBack) + { + TRACE("CDmAdRtNodeDataApi::CreateDmAdRtNodeDataL"); + return CDmAdRtNodeData::NewL(aUri, aCallBack); + } + +void CDmAdRtNodeDataApi::DeleteDmAdRtNodeData(CDmAdRtNodeData* aDmAdRtNodeData) + { + TRACE("CDmAdRtNodeDataApi::DeleteDmAdRtNodeData"); + delete aDmAdRtNodeData; + } + +void CDmAdRtNodeDataApi::UpdateLeafDataL(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri, const TDesC8& aObject) + { + TRACE("CDmAdRtNodeDataApi::UpdateLeafDataL"); + aDmAdRtNodeData->UpdateLeafDataL(aUri, aObject); + } + +void CDmAdRtNodeDataApi::FetchLeafObjectLC(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri, const TDesC8& aLuid, CBufBase*& aObject) + { + aDmAdRtNodeData->FetchLeafObjectLC(aUri, aLuid, aObject); + } + +void CDmAdRtNodeDataApi::SetDefaultSettingsL(CDmAdRtNodeData* /*aDmAdRtNodeData*/, const TDesC8& /*aUri*/) + { + TRACE("CDmAdRtNodeDataApi::SetDefaultSettingsL"); + } + +TBool CDmAdRtNodeDataApi::AreUriTypesSame(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri) + { + TRACE("CDmAdRtNodeDataApi::AreUriTypesSameL"); + + TDmAdUriType uriType1 = EDmAdUriTypeVpnAp; + + //CDmAdRtNodeData::UriTypeL leaves if uri is unknown + TRAPD(err, uriType1 = CDmAdRtNodeData::UriTypeL(aUri)); + TDmAdUriType uriType2 = aDmAdRtNodeData->UriType(); + + if (err == KErrNone && uriType1 == uriType2) + { + return ETrue; + } + else + { + return EFalse; + } + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/src/dmadstorevpnapcmm.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/src/dmadstorevpnapcmm.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,295 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: VPN access point manipulation. +* +*/ + + + +#include +#include + +#include "dmadstorevpnap.h" +#include "vpnlogger.h" + +using namespace CMManager; +// ======== LOCAL FUNCTIONS ======== + +CVpnAp* CVpnAp::NewL(void) + { + TRACE("CVpnAp::NewL"); + CVpnAp* self = new (ELeave) CVpnAp; + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + + return self; + } + + +CVpnAp::CVpnAp() + { + TRACE("CVpnAp::CVpnAp"); + } + + +void CVpnAp::ConstructL() + { + TRACE("CVpnAp::ConstructL"); + + iCmManagerExt.OpenL(); + } + + +CVpnAp::~CVpnAp() + { + TRACE("CVpnAp::~CVpnAp"); + + iCmManagerExt.Close(); + } + + +TBool CVpnAp::FindVpnApL(TVpnApCommsId aId) + { + TRACE("CVpnAp::FindVpnApL"); + + TBool connectionFound = EFalse; + + RCmConnectionMethodExt vpnConnectionMethod; + TRAPD(err, vpnConnectionMethod = iCmManagerExt.ConnectionMethodL( aId )); + CleanupClosePushL(vpnConnectionMethod); + + switch(err) + { + case KErrNone: + if ( IsVpnConnectionMethodL(vpnConnectionMethod) ) + { + connectionFound = ETrue; + } + break; + case KErrNotFound: + //do nothing + break; + default: + User::Leave(err); + break; + } + + CleanupStack::PopAndDestroy(); //vpnConnectionMethod + return connectionFound; + } + + +void CVpnAp::DeleteVpnApL(TVpnApCommsId aId) + { + TRACE("CVpnAp::DeleteVpnApL"); + + RCmConnectionMethodExt vpnConnectionMethod = iCmManagerExt.ConnectionMethodL( aId ); + CleanupClosePushL(vpnConnectionMethod); + + //Check that the type of the connection is correct. + if ( !IsVpnConnectionMethodL(vpnConnectionMethod) ) + { + User::Leave(KErrNotFound); + } + + if ( !vpnConnectionMethod.DeleteL() ) + { + User::Leave(KErrGeneral); + } + + CleanupStack::PopAndDestroy(); //vpnConnectionMethod + } + + +void CVpnAp::ListVpnApsL(RArray& aIdArray) + { + TRACE("CVpnAp::ListVpnApsL"); + + aIdArray.Reset(); + + //First collect all VPN connection methods from destinations + RArray destinationArray; + iCmManagerExt.AllDestinationsL( destinationArray ); + CleanupClosePushL(destinationArray); + + for (TInt i = 0; i < destinationArray.Count(); ++i) + { + RCmDestinationExt destination = iCmManagerExt.DestinationL( destinationArray[i] ); + CleanupClosePushL(destination); + + TInt connectionMethodCount = destination.ConnectionMethodCount(); + for (TInt j = 0; j < connectionMethodCount; ++j) + { + RCmConnectionMethodExt connectionMethod = destination.ConnectionMethodL( j ); + CleanupClosePushL(connectionMethod); + if ( IsVpnConnectionMethodL(connectionMethod) ) + { + TUint32 apId = connectionMethod.GetIntAttributeL( ECmId ); + User::LeaveIfError(aIdArray.Append(apId)); + } + CleanupStack::PopAndDestroy(); //connectionMethod + } + + CleanupStack::PopAndDestroy(); //destination + } + CleanupStack::PopAndDestroy(); //destinationArray + + //Second collect VPN connection methods, which are not inside a destination. + RArray connectionMethodArray; + iCmManagerExt.ConnectionMethodL( connectionMethodArray ); + CleanupClosePushL(connectionMethodArray); + + for ( TInt i = 0; i < connectionMethodArray.Count(); ++i) + { + RCmConnectionMethodExt connectionMethod = + iCmManagerExt.ConnectionMethodL( connectionMethodArray[i] ); + CleanupClosePushL(connectionMethod); + if ( IsVpnConnectionMethodL(connectionMethod) ) + { + User::LeaveIfError(aIdArray.Append(connectionMethodArray[i])); + } + CleanupStack::PopAndDestroy(); //connectionMethod + } + CleanupStack::PopAndDestroy(); //connectionMethodArray + } + + +void CVpnAp::GetVpnApL(TVpnApCommsId aId, TVpnApParms& aVpnApParms) + { + TRACE("CVpnAp::GetVpnApL"); + + RCmConnectionMethodExt vpnConnectionMethod = iCmManagerExt.ConnectionMethodL( aId ); + CleanupClosePushL(vpnConnectionMethod); + + //Check that the type of the connection is correct. + if ( !IsVpnConnectionMethodL(vpnConnectionMethod) ) + { + User::Leave(KErrNotFound); + } + + HBufC* string = vpnConnectionMethod.GetStringAttributeL( ECmName ); + aVpnApParms.iName = *string; + delete string; + string = NULL; + + string = vpnConnectionMethod.GetStringAttributeL( EVpnServicePolicy ); + aVpnApParms.iPolicyId = *string; + delete string; + string = NULL; + + // real IAP or SNAP. ECmNextLayerIapId == EVpnIapId + TUint32 realConn = vpnConnectionMethod.GetIntAttributeL(EVpnIapId); + if (realConn != 0) + { + DEBUG_LOG1(_L("Real connection is IAP %d"), realConn); + aVpnApParms.iRealConnRefType = TVpnApParms::EIapRealConnRef; + aVpnApParms.iRealConnRef = realConn; + } + else + { + realConn = vpnConnectionMethod.GetIntAttributeL(ECmNextLayerSNAPId); + DEBUG_LOG1(_L("Real connection is snap %d"), realConn); + aVpnApParms.iRealConnRefType = TVpnApParms::ESnapRealConnRef; + aVpnApParms.iRealConnRef = realConn; + } + + CleanupStack::PopAndDestroy(); //vpnConnectionMethod + } + + +TVpnApCommsId CVpnAp::AddVpnApL(const TVpnApParms& aVpnApParms) + { + TRACE("CVpnAp::AddVpnApL"); + + RCmConnectionMethodExt vpnConnectionMethod = + iCmManagerExt.CreateConnectionMethodL( KPluginVPNBearerTypeUid ); + + CleanupClosePushL( vpnConnectionMethod ); + + UpdateVpnApL(vpnConnectionMethod, aVpnApParms); + + // save changes + vpnConnectionMethod.UpdateL(); + + TUint32 apId = vpnConnectionMethod.GetIntAttributeL( ECmId ); + + CleanupStack::PopAndDestroy(); // vpnConnectionMethod + + return apId; + } + + +void CVpnAp::UpdateVpnApL(TVpnApCommsId aId, const TVpnApParms& aVpnApParms) + { + TRACE("CVpnAp::UpdateVpnApL"); + + RCmConnectionMethodExt vpnConnectionMethod = iCmManagerExt.ConnectionMethodL( aId ); + CleanupClosePushL(vpnConnectionMethod); + + //Check that the type of the connection is correct. + if ( !IsVpnConnectionMethodL(vpnConnectionMethod) ) + { + User::Leave(KErrNotFound); + } + + UpdateVpnApL(vpnConnectionMethod, aVpnApParms); + vpnConnectionMethod.UpdateL(); + CleanupStack::PopAndDestroy(); //vpnConnectionMethod + } + + +void CVpnAp::UpdateVpnApL(RCmConnectionMethodExt& aConnectionMethod, + const TVpnApParms& aVpnApParms) + { + + TRACE("CVpnAp::UpdateVpnApL"); + + __ASSERT_DEBUG( aConnectionMethod.GetBoolAttributeL(ECmVirtual), User::Invariant() ); + + aConnectionMethod.SetIntAttributeL( ECmNamingMethod, ENamingNothing ); + aConnectionMethod.SetStringAttributeL( ECmName, aVpnApParms.iName ); + aConnectionMethod.SetStringAttributeL( EVpnServicePolicy, aVpnApParms.iPolicyId ); + + switch(aVpnApParms.iRealConnRefType) + { + case TVpnApParms::EIapRealConnRef: + aConnectionMethod.SetIntAttributeL( EVpnIapId, aVpnApParms.iRealConnRef ); + DEBUG_LOG1(_L("VPN iap uses real iap %d"), aVpnApParms.iRealConnRef); + DEBUG_LOG1(_L("ECmNextLayerSNAPId is %d"), aConnectionMethod.GetIntAttributeL(ECmNextLayerSNAPId)); + break; + case TVpnApParms::ESnapRealConnRef: + aConnectionMethod.SetIntAttributeL( ECmNextLayerSNAPId, aVpnApParms.iRealConnRef ); + DEBUG_LOG1(_L("VPN iap uses real SNAP %d"), aVpnApParms.iRealConnRef); + DEBUG_LOG1(_L("EVpnIapId is %d"), aConnectionMethod.GetIntAttributeL(EVpnIapId)); + break; + default: + User::Invariant(); + break; + } + } + + +TBool CVpnAp::IsVpnConnectionMethodL(RCmConnectionMethodExt& aConnectionMethod) const + { + TBool isVPNConnectionMethod = EFalse; + + if ( aConnectionMethod.GetBoolAttributeL(ECmVirtual) && + aConnectionMethod.GetIntAttributeL( ECmBearerType ) == KPluginVPNBearerTypeUid) + { + isVPNConnectionMethod = ETrue; + } + + return isVPNConnectionMethod; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadipsecvpn/src/eventlogger.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadipsecvpn/src/eventlogger.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,130 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CEventLogger +* +*/ + +#include + +#include "eventlogger.h" +#include "vpnlogger.h" +#include "eventviewer.h" + +#include "dmadadapterimplconst.h" +#include + +_LIT(KUnknownPolicy, "unknown"); +_LIT8(KUnknownVpnAp, "unknown"); +_LIT8(KUnknownIap, "unknown"); + + +CEventLogger* CEventLogger::NewL() + { + CEventLogger* self = new (ELeave) CEventLogger(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CEventLogger::CEventLogger() + { + } + +void CEventLogger::ConstructL() + { + User::LeaveIfError(iEventMediator.Connect()); + } + +CEventLogger::~CEventLogger() + { + iEventMediator.Close(); + } + +void CEventLogger::LogEvent(RVpnServ& vpnApi, TUint aMsgId, const TDesC* aDes1, TInt aInt1, TInt aInt2) + { + TRACE("CEventLogger::LogEvent"); + + TVpnPolicyDetails policyDetails; + + if (aMsgId == R_VPN_MSG_CREATED_VPN_ACCESS_POINT_WITH_AP || + aMsgId == R_VPN_MSG_CREATED_VPN_ACCESS_POINT_WITH_SNAP) + { + // Descriptor parameter 1 is a policy ID + if (aDes1 && aDes1->Length() > 0) + { + TInt err = KErrNone; + err = vpnApi.GetPolicyDetails(*aDes1, policyDetails); + + // If we cannot find the policy name... + if (err) + { + // ...use the policy ID as the name + policyDetails.iName.Copy(*aDes1); + } + } + else + { + // Completely unknown policy reference + policyDetails.iName.Copy(KUnknownPolicy); + } + } + + // Make a 8 bit copy of the policy name + + HBufC8* nameCopy = HBufC8::New(policyDetails.iName.Length()); + if (!nameCopy) + { + return; + } + + TPtr8 nameCopyPtr = nameCopy->Des(); + CnvUtfConverter::ConvertFromUnicodeToUtf8(nameCopyPtr, policyDetails.iName); + LogEvent(aMsgId, nameCopy, aInt1, aInt2); + + delete nameCopy; + } + +void CEventLogger::LogEvent(TUint aMsgId, const TDesC8* aDes1, TInt aInt1, TInt aInt2) + { + TRACE("CEventLogger::LogEvent 2"); + + TUid sourceUid = TUid::Uid(KDmAdDllUid); + + TIapName vpnApName(KUnknownVpnAp); + TIapName realConnectionName(KUnknownIap); + + switch (aMsgId) + { + case R_VPN_MSG_CREATED_VPN_ACCESS_POINT_WITH_AP: + EventViewer::GetIapNames(aInt1, vpnApName, aInt2, realConnectionName); + + //The return value is ignored + iEventMediator.ReportLogEvent(sourceUid, EInfo, + R_VPN_MSG_CREATED_VPN_ACCESS_POINT_WITH_AP, + 3, &vpnApName, aDes1, &realConnectionName); + break; + case R_VPN_MSG_CREATED_VPN_ACCESS_POINT_WITH_SNAP: + EventViewer::GetIapName(aInt1, vpnApName); + EventViewer::GetSnapName(aInt2, realConnectionName); + + iEventMediator.ReportLogEvent(sourceUid, EInfo, + R_VPN_MSG_CREATED_VPN_ACCESS_POINT_WITH_SNAP, + 3, &vpnApName, aDes1, &realConnectionName); + + break; + default: + return; + } + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/BWINS/DMADTESTU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/BWINS/DMADTESTU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?StartTest@TDmAdStartTest@@SAXXZ @ 1 NONAME ; public: static void __cdecl TDmAdStartTest::StartTest(void) + diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/data/102069a5.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/data/102069a5.rss Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Resource definitions for dmadpki. +* +*/ + +CHARACTER_SET UTF8 + +/* +* ============================================================================ +* Name : 102069A5.rss +* ============================================================================ +*/ + +#include + +#define KSmlDMInterfaceUid 0x102018B4 +#include "dmadadapterimplconst.h" + +RESOURCE REGISTRY_INFO theRegistryInfo + { + dll_uid = KDmAdDllUid; //The DLL's 3rd UID. + interfaces = + { + INTERFACE_INFO + { + interface_uid = KSmlDMInterfaceUid; // DM interface UID + implementations = + { + IMPLEMENTATION_INFO + { + implementation_uid = KDmAdImplUid; + version_no = 1; + display_name = ""; + default_data = ""; + opaque_data = ""; + } + }; + } + }; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Build information file for project DmAdPki +* +*/ + + + +#include + +PRJ_MMPFILES +#ifdef VPNCLIENT_USE_STUBS + dmadpki_test.mmp +#else + dmadpki.mmp +#endif + +PRJ_TESTMMPFILES + diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/group/dmadpki.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/group/dmadpki.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,88 @@ +/* +* Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project dmadpki +* +*/ + + + +#include + +TARGET dmadpki.dll +TARGETTYPE PLUGIN +UID 0x10009D8D 0x102069A5 + +CAPABILITY CAP_ECOM_PLUGIN +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE dmadadapter.cpp +SOURCE dmadcertparms.cpp +SOURCE dmadcertreqparms.cpp +SOURCE dmadcertutil.cpp +SOURCE dmadddf.cpp +SOURCE dmadprivkeyparms.cpp +SOURCE DmAdRtNodeData.cpp +SOURCE dmadrtnodedataapi.cpp +SOURCE DmAdStore.cpp +SOURCE dmadstorecert.cpp +SOURCE dmadstorecertreq.cpp +SOURCE dmadstoreprivkey.cpp +SOURCE dmadcertluidmappingelem.cpp +SOURCE dmadpkcs12parms.cpp +SOURCE dmadstorepkcs12.cpp + +START RESOURCE ../data/102069a5.rss +TARGET dmadpki.rsc +END + +USERINCLUDE ../inc +USERINCLUDE ../../vpnmanager/inc +USERINCLUDE ../../dmadengine/inc +USERINCLUDE ../../pkiserviceapi/inc +USERINCLUDE ../../utlbase64/inc +USERINCLUDE ../../utlpkcs10/inc +USERINCLUDE ../../utlcrypto/inc +USERINCLUDE ../../utlxml/inc +USERINCLUDE ../../eventmediatorapi/inc +USERINCLUDE ../../vpncommon/inc +USERINCLUDE ../../ikepolparser/inc +USERINCLUDE ../../utlpkcs12/inc + +MW_LAYER_SYSTEMINCLUDE +SYSTEMINCLUDE /epoc32/include/ecom + +LIBRARY euser.lib +LIBRARY ecom.lib +LIBRARY dmadengine.lib +LIBRARY pkiserviceapi.lib +LIBRARY eventmedapi.lib +LIBRARY utlbase64.lib +LIBRARY x509.lib +LIBRARY x500.lib +LIBRARY crypto.lib +LIBRARY utlcrypto.lib +LIBRARY cryptography.lib +LIBRARY asn1.lib +LIBRARY charconv.lib +LIBRARY utlxml.lib +LIBRARY certstore.lib +LIBRARY efsrv.lib +LIBRARY ctframework.lib +LIBRARY bafl.lib +LIBRARY utlpkcs10.lib +LIBRARY utlpkcs12.lib +DEBUGLIBRARY flogger.lib + +MACRO DMAD_ENGINE_EXPORT diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/group/dmadpki_test.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/group/dmadpki_test.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,91 @@ +/* +* Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project dmadpki +* +*/ + + + +#include + +TARGET dmadpki.dll +TARGETTYPE PLUGIN +UID 0x10009D8D 0x102069A5 + +CAPABILITY CAP_ECOM_PLUGIN +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE dmadadapter.cpp +SOURCE dmadcertparms.cpp +SOURCE dmadcertreqparms.cpp +SOURCE dmadcertutil.cpp +SOURCE dmadddf.cpp +SOURCE dmadprivkeyparms.cpp +SOURCE DmAdRtNodeData.cpp +SOURCE dmadrtnodedataapi.cpp +SOURCE DmAdStore.cpp +SOURCE dmadstorecert.cpp +SOURCE dmadstorecertreq.cpp +SOURCE dmadstoreprivkey.cpp +SOURCE dmadcertluidmappingelem.cpp +SOURCE dmadpkcs12parms.cpp +SOURCE dmadstorepkcs12.cpp + +START RESOURCE ../data/102069A5.rss +TARGET dmadpki.rsc +END + +LANG sc + +USERINCLUDE ../inc +USERINCLUDE ../../vpnmanager/inc +USERINCLUDE ../../dmadengine/inc +USERINCLUDE ../../pkiserviceapi/inc +USERINCLUDE ../../utlbase64/inc +USERINCLUDE ../../utlpkcs10/inc +USERINCLUDE ../../utlcrypto/inc +USERINCLUDE ../../utlxml/inc +USERINCLUDE ../../eventmediatorapi/inc +USERINCLUDE ../../vpncommon/inc +USERINCLUDE ../../ikepolparser/inc +USERINCLUDE ../../utlpkcs12/inc + +MW_LAYER_SYSTEMINCLUDE +SYSTEMINCLUDE /epoc32/include/ecom + +LIBRARY DMADPKI_proxy.lib +LIBRARY euser.lib +LIBRARY ecom.lib +LIBRARY dmadengine.lib +LIBRARY pkiserviceapi.lib +LIBRARY eventmedapi.lib +LIBRARY utlbase64.lib +LIBRARY x509.lib +LIBRARY x500.lib +LIBRARY crypto.lib +LIBRARY utlcrypto.lib +LIBRARY cryptography.lib +LIBRARY asn1.lib +LIBRARY charconv.lib +LIBRARY utlxml.lib +LIBRARY certstore.lib +LIBRARY efsrv.lib +LIBRARY ctframework.lib +LIBRARY bafl.lib + +LIBRARY utlpkcs12.lib +DEBUGLIBRARY flogger.lib + +MACRO DMAD_ENGINE_EXPORT diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/DmAdRtNodeData.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/DmAdRtNodeData.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,234 @@ +/* +* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdCertData +* +*/ + + + +#ifndef __DMADRTNODEDATA_H__ +#define __DMADRTNODEDATA_H__ + + +#include +#include + +#include "dmadcallback.h" +#include "dmadcertparms.h" +#include "dmadcertreqparms.h" +#include "dmadprivkeyparms.h" +#include "dmadpkcs12parms.h" +#include "eventlogger.h" + +class CX509Certificate; + +typedef enum + { + EDmAdUriTypeCert, + EDmAdUriTypeCertReq, + EDmAdUriTypePrivKey, + EDmAdUriTypePKCS12 + } TDmAdUriType; + +//------------------------------------------------------------------------------------------------ +// CDmAdCertData +//------------------------------------------------------------------------------------------------ +class CDmAdCertData : public CBase + { +public: + static CDmAdCertData* NewL(MDmAdCallBack* aCallBack); + ~CDmAdCertData(); + + void SetDefaultSettings(); + + void SetTypeL(const TDesC8& aType); + HBufC8* TypeLC(); + void SetFormatL(const TDesC8& aFormat); + HBufC8* FormatLC(); + void SetDeletableL(const TDesC8& aDeletable); + HBufC8* DeletableLC(); + void SetTrustedL(const TDesC8& aTrusted); + HBufC8* TrustedLC(); + void SetApplicabilityL(const RArray& aApplicability); + const RArray& Applicability() const; + void SetContentL(const TDesC8& aContent); + TPtrC8 Content(); + HBufC8* SerialNumberLC(); + HBufC8* IssuerNameLC(); + HBufC8* FingerprintAlgLC(); + HBufC8* FingerprintValueLC(); + HBufC8* ValidityBeginLC(); + HBufC8* ValidityEndLC(); + HBufC8* SubjectNameLC(); + HBufC8* SubjectAltNameLC(); + HBufC8* KeyUriLC(); + HBufC8* KeyIdLC(); + HBufC8* KeyUsageLC(); + HBufC8* FormatCertValidityTimeLC(const TTime& aTime); + HBufC8* FindKeyUriLC(const TDesC8& aKeyId); + void RestoreL(const CDmAdCertParms& aCertParms); + void ToStoreL(CDmAdCertParms& aCertParms); + +private: + void ConstructL(); + CDmAdCertData(MDmAdCallBack* aCallBack); + +private: + MDmAdCallBack* iCallBack; + + CDmAdCertParms* iCertParms; + CX509Certificate* iCertCx509; + }; + +//------------------------------------------------------------------------------------------------ +// CDmAdCertReqData +//------------------------------------------------------------------------------------------------ +class CDmAdCertReqData : public CBase + { +public: + static CDmAdCertReqData* NewL(MDmAdCallBack* aCallBack); + ~CDmAdCertReqData(); + + void SetDefaultSettings(); + void SetSubjectNameL(const TDesC8& aSubjectName); + TPtrC8 SubjectName(); + void SetRfc822NameL(const TDesC8& aRfc822Name); + TPtrC8 Rfc822Name(); + void SetKeyUriL(const TDesC8& aKeyUri); + HBufC8* KeyUriL() const; + void SetKeyLength(const TDesC8& aKeyLength); + HBufC8* KeyLengthLC(); + + TPtrC8 Content(); + + void RestoreL(const CDmAdCertReqParms& aCertReqParms); + void ToStoreL(CDmAdCertReqParms& aCertReqParms); + +private: + void ConstructL(); + CDmAdCertReqData(MDmAdCallBack* aCallBack); + +private: + + MDmAdCallBack* iCallBack; + CDmAdCertReqParms* iCertReqParms; + }; + +//------------------------------------------------------------------------------------------------ +// CDmAdPrivKeyData +//------------------------------------------------------------------------------------------------ +class CDmAdPrivKeyData : public CBase + { +public: + static CDmAdPrivKeyData* NewL(); + ~CDmAdPrivKeyData(); + + void SetDefaultSettingsL(); + void SetKeyTypeL(const TDesC8& aKeyType); + HBufC8* KeyTypeLC(); + void SetKeyLength(const TDesC8& aKeyLength); + HBufC8* KeyLengthLC(); + TPtrC8 KeyId(); + + void RestoreL(const CDmAdPrivKeyParms& aPrivKeyParms); + void ToStoreL(CDmAdPrivKeyParms& aPrivKeyParms); + +private: + void ConstructL(); + CDmAdPrivKeyData(); + +private: + CDmAdPrivKeyParms* iPrivKeyParms; + }; + +//------------------------------------------------------------------------------------------------ +// CDmAdPKCS12Data +//------------------------------------------------------------------------------------------------ +class CDmAdPKCS12Data : public CBase + { +public: + static CDmAdPKCS12Data* NewL(/*MDmAdCallBack* aCallBack*/); + ~CDmAdPKCS12Data(); + + void SetDefaultSettings(); + + void SetDeletableL(const TDesC8& aDeletable); + HBufC8* DeletableLC(); + void SetApplicabilityL(const RArray& aApplicability); + const RArray& Applicability() const; + void SetContentL(const TDesC8& aContent); + TPtrC8 Content(); + void SetPasswordL(const TDesC8& aContent); + TPtrC8 Password(); + + void RestoreL(const CDmAdPKCS12Parms& aPKCS12Parms); + void ToStoreL(CDmAdPKCS12Parms& aPKCS12Parms); + +private: + void ConstructL(); + CDmAdPKCS12Data(); + +private: + CDmAdPKCS12Parms* iPKCS12Parms; + }; + +//------------------------------------------------------------------------------------------------ +// CDmAdRtNodeData +//------------------------------------------------------------------------------------------------ +class CDmAdRtNodeData : public CBase + { +public: + static CDmAdRtNodeData* NewL(const TDesC8& aUri, MDmAdCallBack* aCallBack); + ~CDmAdRtNodeData(); + TDmAdUriType UriType() const; + static TDmAdUriType UriTypeL(const TDesC8& aUri); + void UpdateLeafDataL(const TDesC8& aUri, const TDesC8& aObject); + void FetchLeafObjectLC(const TDesC8& aUri, const TDesC8& aLuid, CBufBase*& aObject); + void SetDefaultSettingsL(const TDesC8& aUri); + + inline CDmAdCertData* CertData() const; + inline CDmAdCertReqData* CertReqData() const; + inline CDmAdPrivKeyData* PrivKeyData() const; + inline CDmAdPKCS12Data* PKCS12Data() const; + +private: + void ConstructL(const TDesC8& aUri, MDmAdCallBack* aCallBack); + CDmAdRtNodeData(); + void UpdateLeafDataCertL(const TDesC8& aUri, const TDesC8& aObject); + void UpdateLeafDataCertReqL(const TDesC8& aUri, const TDesC8& aObject); + void UpdateLeafDataPrivKeyL(const TDesC8& aUri, const TDesC8& aObject); + void FetchLeafObjectCertLC(const TDesC8& aUri, const TDesC8& aLuid, CBufBase*& aObject); + void FetchLeafObjectCertReqLC(const TDesC8& aUri, const TDesC8& aLuid, CBufBase*& aObject); + void FetchLeafObjectPrivKeyLC(const TDesC8& aUri, const TDesC8& aLuid, CBufBase*& aObject); + + void UpdateLeafDataPKCS12L(const TDesC8& aUri, const TDesC8& aObject); + void ParseApplicabilityL(const TDesC8& aApplicabilityData, + RArray& aApplicabilityList) const; + + +private: + TDmAdUriType iUriType; + union + { + CDmAdCertData* iCert; + CDmAdCertReqData* iCertReq; + CDmAdPrivKeyData* iPrivKey; + CDmAdPKCS12Data* iPKCS12; + } u; + DEFINE_EVENT_LOGGER + }; + +#include "DmAdRtNodeData.inl" + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/DmAdRtNodeData.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/DmAdRtNodeData.inl Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Inlined node data methods +* +*/ + + + +#ifndef __DMADRTNODEDATA_INL__ +#define __DMADRTNODEDATA_INL__ + +inline CDmAdCertData* CDmAdRtNodeData::CertData(void) const + { + return u.iCert; + } + +inline CDmAdCertReqData* CDmAdRtNodeData::CertReqData(void) const + { + return u.iCertReq; + } + +inline CDmAdPrivKeyData* CDmAdRtNodeData::PrivKeyData(void) const + { + return u.iPrivKey; + } + +inline CDmAdPKCS12Data* CDmAdRtNodeData::PKCS12Data(void) const + { + return u.iPKCS12; + } + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/DmAdStore.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/DmAdStore.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,88 @@ +/* +* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdStore +* +*/ + + + +#ifndef __DMADSTORE_H__ +#define __DMADSTORE_H__ + +#include + +#include "dmadstoreapi.h" +#include "DmAdRtNode.h" + +#include "dmadstorecert.h" +#include "dmadstorecertreq.h" +#include "dmadstoreprivkey.h" +#include "dmadstorepkcs12.h" + +//------------------------------------------------------------------------------------------------ +// CDmAdStore +//------------------------------------------------------------------------------------------------ +class CDmAdStore : public CBase, public MDmAdStoreApi + { +public: + static CDmAdStore* NewL(MDmAdCallBack* aDmAdCallBack); + ~CDmAdStore(); + TBool FindRtNodeL(const TDesC8& aLuid, const TDesC8& aUri); + void LuidListL(const TDesC8& aUri, const TDesC8& aLuid, RPointerArray& aLuidList); + void FetchRtNodeL(CDmAdRtNode& aRtNode); + void SaveTopLevelRtNodeL(CDmAdRtNode& aRtNode, CArrayPtr& aChildRtNodes); + void SaveChildLevelRtNodeL(CDmAdRtNode& aRtNode); + void DeleteRtNodeL(const TDesC8& aLuid, const TDesC8& aUri); + + void PkiLogonL(); + void PkiLogoffL(); + void SetStoreTypeL(TInt aStore, TPkiServiceStoreType aStoreType); + +private: + void ConstructL(MDmAdCallBack* aDmAdCallBack); + CDmAdStore(); + + TBool CertFindRtNodeL(const TDesC8& aLuid, const TDesC8& aUri); + void CertLuidListL(const TDesC8& aUri, const TDesC8& aLuid, RPointerArray& aLuidList); + void CertFetchRtNodeL(CDmAdRtNode& aRtNode); + void CertSaveTopLevelRtNodeL(CDmAdRtNode& aRtNode, CArrayPtr& aChildRtNodes); + void CertSaveChildLevelRtNodeL(CDmAdRtNode& aRtNode); + void CertDeleteRtNodeL(const TDesC8& aLuid, const TDesC8& aUri); + + TBool CertReqFindRtNodeL(const TDesC8& aLuid, const TDesC8& aUri); + void CertReqLuidListL(const TDesC8& aUri, const TDesC8& aLuid, RPointerArray& aLuidList); + void CertReqFetchRtNodeL(CDmAdRtNode& aRtNode); + void CertReqSaveTopLevelRtNodeL(CDmAdRtNode& aRtNode, CArrayPtr& aChildRtNodes); + void CertReqSaveChildLevelRtNodeL(CDmAdRtNode& aRtNode); + void CertReqDeleteRtNodeL(const TDesC8& aLuid, const TDesC8& aUri); + + TBool PrivKeyFindRtNodeL(const TDesC8& aLuid, const TDesC8& aUri); + void PrivKeyLuidListL(const TDesC8& aUri, const TDesC8& aLuid, RPointerArray& aLuidList); + void PrivKeyFetchRtNodeL(CDmAdRtNode& aRtNode); + void PrivKeyDeleteRtNodeL(const TDesC8& aLuid, const TDesC8& aUri); + + TBool PKCS12FindRtNodeL(const TDesC8& aLuid, const TDesC8& aUri); + void PKCS12LuidListL(const TDesC8& aUri, const TDesC8& aLuid, RPointerArray& aLuidList); + void PKCS12SaveTopLevelRtNodeL(CDmAdRtNode& aRtNode, CArrayPtr& aChildRtNodes); + +private: + CDmAdCert* iCert; + CDmAdCertReq* iCertReq; + CDmAdPrivKey* iPrivKey; + CDmAdPKCS12* iPKCS12Obj; + + RPKIServiceAPI iPkiServiceApi; + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/dmadadapter.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/dmadadapter.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,111 @@ +/* +* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: PKI OMA DM Adapter +* +*/ + + + +#ifndef __DMADADAPTER_H__ +#define __DMADADAPTER_H__ + +#include + +#include "dmadcallbackc.h" +#include "DmAdStore.h" +#include "dmadddf.h" +#include "dmadrtnodedataapic.h" +#include "dmadengine.h" + +//------------------------------------------------------------------------------------------------ +// CDmAdAdapter +//------------------------------------------------------------------------------------------------ +class CDmAdAdapter : public CSmlDmAdapter + { +public: + static CDmAdAdapter* NewL(MSmlDmCallback* aDmCallback); + static CDmAdAdapter* NewLC(MSmlDmCallback* aDmCallback); + ~CDmAdAdapter(); + + void DDFVersionL(CBufBase& aVersion); + void DDFStructureL(MSmlDmDDFObject& aDDF); + + void ChildURIListL(const TDesC8& aUri, const TDesC8& aLuid, const CArrayFix& aPreviousURISegmentList, TInt aResultsRef, TInt aStatusRef); + void AddNodeObjectL(const TDesC8& aUri, const TDesC8& aParentLuid, const TInt aStatusRef); + void UpdateLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aObject, const TDesC8& aType, TInt aStatusRef); + void FetchLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aType, TInt aResultsRef, TInt aStatusRef); + void DeleteObjectL(const TDesC8& aUri, const TDesC8& aLuid, TInt aStatusRef); + void CompleteOutstandingCmdsL(); + void UpdateLeafObjectL(const TDesC8& aUri, + const TDesC8& aLuid, + RWriteStream*& aStream, + const TDesC8& aType, + TInt aStatusRef); + void FetchLeafObjectSizeL(const TDesC8& aUri, + const TDesC8& aLuid, + const TDesC8& aType, + TInt aResultsRef, + TInt aStatusRef); + void ExecuteCommandL(const TDesC8& aUri, + const TDesC8& aLuid, + const TDesC8& aArgument, + const TDesC8& aType, + TInt aStatusRef); + void ExecuteCommandL(const TDesC8& aUri, + const TDesC8& aLuid, + RWriteStream*& aStream, + const TDesC8& aType, + TInt aStatusRef); + void CopyCommandL(const TDesC8& aTargetUri, + const TDesC8& aTargetLuid, + const TDesC8& aSourceUri, + const TDesC8& aSourceLuid, + const TDesC8& aType, + TInt aStatusRef); + void StartAtomicL(); + void CommitAtomicL(); + void RollbackAtomicL(); + TBool StreamingSupport(TInt& aItemSize); + void StreamCommittedL(); + +private: + CDmAdAdapter(MSmlDmCallback* aDmCallback); + void ConstructL(MSmlDmCallback* aDmCallback); + + /** + * At the moment, only used for PKCS#12 node identification + * purposes + * + * @return KErrNone if the node can be added, KErrAlreadyExists + * if the PKCS#12 node already exists in the luid map. + */ + TInt CheckNodeStatus(const TDesC8& aUri); + + /** + * Find out whether a luid mapping for the given PKCS#12 URI + * already exists. + * + * @leave Leaves with KErrAlreadyExists if the luid mapping is found + */ + void CheckPKCS12ExistenceL(const TDesC8& aUri); + +private: + CDmAdCallBack* iCallBack; + CDmAdStore* iStore; + CDmAdDdf* iDdf; + CDmAdRtNodeDataApi* iRtNodeDataApi; + CDmAdEngine* iEngine; + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/dmadadapterimplconst.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/dmadadapterimplconst.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: PKI OMA DM Adapter contants. +* +*/ + + + +#ifndef __DMADADAPTERIMPLCONST_H__ +#define __DMADADAPTERIMPLCONST_H__ + +#define KDmAdDllUid 0x102069A5 +#define KDmAdImplUid 0x102069A6 + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/dmadcertluidmappingelem.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/dmadcertluidmappingelem.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdCertLuidMappingElem. +* +*/ + + + +#ifndef __DMADCERTLUIDMAPPINGELEM_H__ +#define __DMADCERTLUIDMAPPINGELEM_H__ + +#include + +class CDmAdCertLuidMappingElem : public CBase + { +public: + static CDmAdCertLuidMappingElem* NewL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber); + static CDmAdCertLuidMappingElem* NewLC(const TDesC8& aIssuerName, const TDesC8& aSerialNumber); + ~CDmAdCertLuidMappingElem(); + static void CleanupOperationDeleteCArrayPtr(TAny* aPtr); + TPtrC8 Luid() const; + TPtrC8 IssuerName() const; + TPtrC8 SerialNumber() const; + static HBufC8* BuildLuidL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber); + +private: + void ConstructL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber); + CDmAdCertLuidMappingElem(); + +private: + HBufC8* iLuid; + HBufC8* iIssuerName; + HBufC8* iSerialNumber; + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/dmadcertparms.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/dmadcertparms.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdCertParms. +* +*/ + + + +#ifndef __DMADCERTPARMS_H__ +#define __DMADCERTPARMS_H__ + +#include +#include + +#include "pkidefs.h" + + +class CDmAdCertParms : public CBase + { +public: + static CDmAdCertParms* NewL(); + static CDmAdCertParms* NewLC(); + ~CDmAdCertParms(); + + TPKICertificateOwnerType Type() const; + void SetType(TPKICertificateOwnerType aType); + + TBool Deletable() const; + void SetDeletable(TBool aDeletable); + + TBool Trusted() const; + void SetTrusted(TBool aTrusted); + + const RArray& Applicability() const; + void SetApplicabilityL(const RArray& aApplicability); + + TPtrC8 Content() const; + void SetContentL(const TDesC8& aContent); + + TPtrC8 KeyId() const; + void SetKeyId(const TDesC8& aKeyLuid); + +private: + CDmAdCertParms(); + +private: + TPKICertificateOwnerType iType; + TBool iDeletable; + TBool iTrusted; + RArray iApplicability; + HBufC8* iContent; //CertificateDer; + + //----- only for AttachCertificateL -------- + TKeyIdentifier iKeyId; + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/dmadcertreqparms.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/dmadcertreqparms.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdCertReqParms. +* +*/ + + + +#ifndef __DMADCERTREQPARMS_H__ +#define __DMADCERTREQPARMS_H__ + +#include + +class CDmAdCertReqParms : public CBase + { +public: + static CDmAdCertReqParms* NewL(); + static CDmAdCertReqParms* NewLC(); + ~CDmAdCertReqParms(); + + TPtrC8 SubjectName() const; + void SetSubjectNameL(const TDesC8& aSubjectName); + TPtrC8 Rfc822Name() const; + void SetRfc822NameL(const TDesC8& aRfc822Name); + TInt KeyLength() const; + void SetKeyLength(TInt aKeyLength); + TPtrC8 Content() const; + void SetContentL(const TDesC8& aContent); + TPtrC KeyUri() const; + void SetKeyUriL(const TDesC& aContent); + + TPtrC8 KeyIdentifierByUri() const; + void SetKeyIdentifierByUriL(const TDesC8& aKeyIdentifierByUri); + +private: + CDmAdCertReqParms(); + +private: + HBufC8* iSubjectName; + HBufC8* iRfc822Name; + TInt iKeyLength; + HBufC8* iContent; + + HBufC8* iKeyIdentifierByUri; // key luid + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/dmadcertutil.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/dmadcertutil.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of TDmAdCertUtil. +* +*/ + + + +#ifndef __DMADCERTUTIL_H__ +#define __DMADCERTUTIL_H__ + +class TDmAdCertUtil + { +public: + static void ParseAvaL(const CX520AttributeTypeAndValue& aAva, TDes8& aOut); + static void CertDnL(const CX500DistinguishedName& aName, TDes8& aOut); + static HBufC8* Sha1DigestL(const TDesC8& aData); + static HBufC8* RSAKeyIdentifierLC(const TDesC8& aKeyData); + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/dmadcertxmldefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/dmadcertxmldefs.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: PKI OMA DM Adapter definitions. +* +*/ + + + +#ifndef __DMADCERTXMLDEFS_H__ +#define __DMADCERTXMLDEFS_H__ + +#include + +//------------------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------------------ +_LIT8(KXmlElemCertApps, "CertApps"); +_LIT8(KXmlElemApp, "App"); + +_LIT8(KXmlAttrId, "id"); +_LIT8(KXmlAttrName, "name"); + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/dmadddf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/dmadddf.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdDdf +* +*/ + + + +#ifndef __DMADDDF_H__ +#define __DMADDDF_H__ + +#include +#include "dmadddfapi.h" +#include "dmadcallback.h" +#include "DmAdStore.h" +#include "dmadddf_lits.h" +//------------------------------------------------------------------------------------------------ +// CDmAdDdf +//------------------------------------------------------------------------------------------------ +class CDmAdDdf : public CBase, public MDmAdDdfApi + { +public: + static CDmAdDdf* NewL(MDmAdCallBack* aDmAdCallBack, CDmAdStore* aStore); + static CDmAdDdf* NewLC(MDmAdCallBack* aDmAdCallBack, CDmAdStore* aStore); + ~CDmAdDdf(); + + void BuildDDFVersionL(CBufBase& aDDFVersion); + void BuildDDFStructureL(MSmlDmDDFObject& aDDF); + + void NotRtNodeAddNodeObjectL(const TDesC8& aUri, const TDesC8& aParentLuid, TInt aStatusRef); + void NotRtNodeUpdateLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aObject, const TDesC8& aType, TInt aStatusRef); + TInt NotRtNodeFetchLeafObjectLC(const TDesC8& aUri, const TDesC8& /*aLuid*/, const TDesC8& /*aType*/, CBufBase*& aObject); + void NotRtNodeDeleteObjectL(const TDesC8& aUri, const TDesC8& aLuid, TInt aStatusRef); + + TBool IsNodeRtNodeL(const TDesC8& aUri); + TBool IsLeafUnderRtNodeL(const TDesC8& aUri); + TPtrC8 RtNodeUriForLeafL(const TDesC8& aLeafUri); + TBool IsTopLevelRtNode(const TDesC8& aUri); + HBufC8* ParentRtNodeUriForRtNodeLC(const TDesC8& aUri); + void BuildChildUriListLC(const TDesC8& aUri, const TDesC8& aParentLuid, const CArrayFix& aPreviousUriSegmentList, CBufBase*& aCurrentList); + +private: + CDmAdDdf(MDmAdCallBack* aDmAdCallBack, CDmAdStore* aStore); + +private: + MDmAdCallBack* iCallBack; + CDmAdStore* iStore; + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/dmadddf_lits.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/dmadddf_lits.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,164 @@ +/* +* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: String literals for OMA DM PKI use +* +*/ + + + +#ifndef __DMADDDF_LITS_H__ +#define __DMADDDF_LITS_H__ + + +//------------------------------------------------------------------------------------------------ +// DDF version +//------------------------------------------------------------------------------------------------ +_LIT8(KDmAdDdfVersion, "1.0"); + +//------------------------------------------------------------------------------------------------ +// ./NokiaPKI Type property +//------------------------------------------------------------------------------------------------ +_LIT8(KDmAdNokiaPkiRootTypeProperty, "com.nokia.devman/1.0/pki"); + +//------------------------------------------------------------------------------------------------ +// URIs +//------------------------------------------------------------------------------------------------ +_LIT8(KDmAdOwnAdUriForGetLuidAllocLFix, "NokiaPKI/Cert"); // URI not object group level? +_LIT8(KDmAdOwnAdUriForPrivateKeys, "NokiaPKI/PrivKey"); +_LIT8(KDmAdOwnAdUriForPKCS12, "NokiaPKI/PKCS12"); + + //------- root ----------------- +_LIT8(KDmAdNodeNokiaPki, "NokiaPKI"); + + //------- common ----------------- +_LIT8(KDmAdNodeRt, ""); +_LIT8(KDmAdNodeGeneral, "General"); + +_LIT8(KDmAdLeafCertApplications, "CertApplications"); +_LIT8(KDmAdLeafLogon, "Logon"); +_LIT8(KDmAdLeafLogoff, "Logoff"); +_LIT8(KDmAdLeafKeyStore, "KeyStore"); +_LIT8(KDmAdLeafCertStore, "CertStore"); + + +_LIT8(KDmAdLeafContent, "Content"); +_LIT8(KDmAdLeafSubjectName, "SubjectName"); +_LIT8(KDmAdLeafKeyId, "KeyID"); +_LIT8(KDmAdLeafKeyLength, "KeyLength"); +_LIT8(KDmAdLeafKeyURI, "KeyURI"); + + //------- Cert ----------------- +_LIT8(KDmAdNodeCert, "Cert"); +_LIT8(KDmAdLeafType, "Type"); +_LIT8(KDmAdLeafFormat, "Format"); +_LIT8(KDmAdLeafSerialNumber, "SerialNumber"); +_LIT8(KDmAdLeafIssuerName, "IssuerName"); +_LIT8(KDmAdLeafFingerprintAlg, "FingerprintAlg"); +_LIT8(KDmAdLeafFingerprintValue, "FingerprintValue"); +_LIT8(KDmAdLeafValidityBegin, "ValidityBegin"); +_LIT8(KDmAdLeafValidityEnd, "ValidityEnd"); +_LIT8(KDmAdLeafSubjectAltName, "SubjectAltName"); +_LIT8(KDmAdLeafKeyUsage, "KeyUsage"); +_LIT8(KDmAdLeafDeletable, "Deletable"); +_LIT8(KDmAdLeafTrusted, "Trusted"); +_LIT8(KDmAdLeafApplicability, "Applicability"); + + //------- CertReq ----------------- +_LIT8(KDmAdNodeCertReq, "CertReq"); +_LIT8(KDmAdLeafRfc822Name, "RFC822Name"); + + //------- PrivKey ----------------- +_LIT8(KDmAdNodePrivKey, "PrivKey"); +_LIT8(KDmAdLeafKeyType, "KeyType"); + + //------- PKCS#12 ----------------- +_LIT8(KDmAdNodePKCS12, "PKCS12"); +_LIT8(KDmAdLeafPKCS12Password, "Password"); +// Note: Nodes "Deletable" (KDmAdLeafDeletable), +// "Applicability" (KDmAdLeafApplicability) and +// "Content" (KDmAdLeafContent) are valid in PKCS#12 +// context as well. + +//------------------------------------------------------------------------------------------------ +// URI descriptions +//------------------------------------------------------------------------------------------------ + //------- root ----------------- +_LIT8(KDmAdDescNodeNokiaPki, "NokiaPKI"); + + //------- common ----------------- +_LIT8(KDmAdDescNodeRt, "Placeholder for one set of settings"); +_LIT8(KDmAdDescNodeGeneral, "General"); + +_LIT8(KDmAdDescLeafCertApplications, "CertApplications"); +_LIT8(KDmAdDescLeafLogon, "Logon"); +_LIT8(KDmAdDescLeafLogoff, "Logoff"); +_LIT8(KDmAdDescLeafKeyStore, "KeyStore"); +_LIT8(KDmAdDescLeafCertStore, "CertStore"); + +_LIT8(KDmAdDescLeafType, "Type"); +_LIT8(KDmAdDescLeafContent, "Content"); +_LIT8(KDmAdDescLeafStatus, "Status"); +_LIT8(KDmAdDescLeafIssuerName, "IssuerName"); +_LIT8(KDmAdDescLeafSubjectName, "SubjectName"); +_LIT8(KDmAdDescLeafSubjectAltName, "SubjectAltName"); +_LIT8(KDmAdDescLeafRfc822Name, "RFC822Name"); +_LIT8(KDmAdDescLeafKeyId, "KeyID"); +_LIT8(KDmAdDescLeafKeyLength, "KeyLength"); + + //------- Cert ----------------- +_LIT8(KDmAdDescNodeCert, "Cert"); +_LIT8(KDmAdDescLeafFormat, "Format"); +_LIT8(KDmAdDescLeafSerialNumber, "SerialNumber"); +_LIT8(KDmAdDescLeafFingerprintAlg, "FingerprintAlg"); +_LIT8(KDmAdDescLeafFingerprintValue, "FingerprintValue"); +_LIT8(KDmAdDescLeafValidityBegin, "ValidityBegin"); +_LIT8(KDmAdDescLeafValidityEnd, "ValidityEnd"); +_LIT8(KDmAdDescLeafKeyURI, "KeyURI"); +_LIT8(KDmAdDescLeafKeyUsage, "KeyUsage"); +_LIT8(KDmAdDescLeafDeletable, "Deletable"); +_LIT8(KDmAdDescLeafTrusted, "Trusted"); +_LIT8(KDmAdDescLeafApplicability, "Applicability"); + + //------- CertReq ----------------- +_LIT8(KDmAdDescNodeCertReq, "CertReq"); +_LIT8(KDmAdDescLeafKeyUri, "KeyURI"); + + //------- PrivKey ----------------- +_LIT8(KDmAdDescNodePrivKey, "PrivKey"); +_LIT8(KDmAdDescLeafKeyType, "KeyType"); +_LIT8(KDmAdDescLeafKeyFormat, "KeyFormat"); + + //------- PKCS#12 ----------------- +_LIT8(KDmAdDescNodePKCS12, "PKCS12"); +_LIT8(KDmAdDescLeafPKCS12Password, "Password"); + +//------------------------------------------------------------------------------------------------ +// ChildURIListL constants +//------------------------------------------------------------------------------------------------ +_LIT8(KDmAdListOfNokiaPkiChildren, "Logon/Logoff/KeyStore/CertStore/General/Cert/CertReq/PrivKey/PKCS12"); +_LIT8(KDmAdListOfCertXChildren, "Type/Format/SerialNumber/IssuerName/FingerprintAlg/FingerprintValue/ValidityBegin/ValidityEnd/SubjectName/SubjectAltName/KeyURI/KeyID/KeyUsage/Deletable/Trusted/Applicability/Content"); +_LIT8(KDmAdListOfCertReqXChildren, "SubjectName/RFC822Name/KeyURI/KeyLength/Content"); +_LIT8(KDmAdListOfPrivKeyXChildren, "KeyType/KeyLength/KeyID"); + +_LIT8(KDmAdListOfPKCS12XChildren, "Password/Deletable/Applicability/Content"); + +_LIT8(KDmAdListOfPkiGeneralChildren, "CertApplications"); + +//------------------------------------------------------------------------------------------------ +// TDFFormat - EBool +//------------------------------------------------------------------------------------------------ +_LIT8(KDmAdDfFormatBoolTrue, "True" ); +_LIT8(KDmAdDfFormatBoolFalse, "False" ); + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/dmadpkcs12parms.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/dmadpkcs12parms.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdPKCS12Parms +* +*/ + + + + +#ifndef __DMADPKCS12PARMS_H__ +#define __DMADPKCS12PARMS_H__ + +#include +#include + +#include "pkidefs.h" + + +class CDmAdPKCS12Parms : public CBase + { +public: + static CDmAdPKCS12Parms* NewL(); + static CDmAdPKCS12Parms* NewLC(); + ~CDmAdPKCS12Parms(); + + TBool Deletable() const; + void SetDeletable(TBool aDeletable); + + const RArray& Applicability() const; + void SetApplicabilityL(const RArray& aApplicability); + + TPtrC8 Content() const; + void SetContentL(const TDesC8& aContent); + + TPtrC8 Password() const; + void SetPasswordL(const TDesC8& aPassword); + +private: + CDmAdPKCS12Parms(); + +private: + TBool iDeletable; + TBool iTrusted; + RArray iApplicability; + HBufC8* iContent; //CertificateDer; + HBufC8* iPassword; + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/dmadprivkeyparms.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/dmadprivkeyparms.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdPrivKeyParms. +* +*/ + + + +#ifndef __DMADPRIVKEYPARMS_H__ +#define __DMADPRIVKEYPARMS_H__ + +#include + +#include "pkidefs.h" + +class CDmAdPrivKeyParms : public CBase + { +public: + static CDmAdPrivKeyParms* NewL(); + static CDmAdPrivKeyParms* NewLC(); + ~CDmAdPrivKeyParms(); + + TPKIKeyAlgorithm KeyType() const; + void SetKeyTypeL(TPKIKeyAlgorithm aType); + TPtrC8 KeyId() const; + void SetKeyIdL(const TDesC8& aKeyId); + TInt KeyLength() const; + void SetKeyLength(TInt aType); + +private: + CDmAdPrivKeyParms(); + +private: + TPKIKeyAlgorithm iKeyType; + TInt iKeyLength; + HBufC8* iKeyId; + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/dmadrtnodedataapic.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/dmadrtnodedataapic.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdRtNodeDataApi. +* +*/ + + + +#ifndef __DMADRTNODEDATAAPIC_H__ +#define __DMADRTNODEDATAAPIC_H__ + +#include + +#include "dmadrtnodedataapi.h" +#include "DmAdRtNodeData.h" +#include "dmadcallback.h" + +//------------------------------------------------------------------------------------------------ +// CDmAdRtNodeDataApi +//------------------------------------------------------------------------------------------------ +class CDmAdRtNodeDataApi : public CBase, public MDmAdRtNodeDataApi + { +public: + static CDmAdRtNodeDataApi* NewL(); + static CDmAdRtNodeDataApi* NewLC(); + ~CDmAdRtNodeDataApi(); + + CDmAdRtNodeData* CreateDmAdRtNodeDataL(const TDesC8& aUri, MDmAdCallBack* aCallBack); + void DeleteDmAdRtNodeData(CDmAdRtNodeData* aDmAdRtNodeData); + void UpdateLeafDataL(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri, const TDesC8& aObject); + void FetchLeafObjectLC(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri, const TDesC8& aLuid, CBufBase*& aObject); + void SetDefaultSettingsL(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri); + TBool AreUriTypesSame(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri); + +private: + CDmAdRtNodeDataApi(); + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/dmadstorecert.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/dmadstorecert.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,70 @@ +/* +* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdCert +* +*/ + + + +#ifndef __DMADSTORECERT_H__ +#define __DMADSTORECERT_H__ + +#include + +#include +//#include +#include + +#include "pkiserviceapi.h" +#include "dmadcertparms.h" +#include "dmadcertluidmappingelem.h" +#include "eventlogger.h" + +class CDmAdCert : public CBase + { +public: + static CDmAdCert* NewL(RPKIServiceAPI& aPkiServiceApi); + static CDmAdCert* NewLC(RPKIServiceAPI& aPkiServiceApi); + ~CDmAdCert(); + + TBool FindL(const TDesC8& aLuid); + HBufC8* AddL(const CDmAdCertParms& aData); // returns Luid + void UpdateL(const TDesC8& aLuid, const CDmAdCertParms& aData); + void FetchL(const TDesC8& aLuid, CDmAdCertParms& aData); + void DeleteL(const TDesC8& aLuid); + void ListL(RPointerArray& aLuidList); + +private: + void ConstructL(); + CDmAdCert(RPKIServiceAPI& aPkiServiceApi); + void ReadCertDetailsL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber, CDmAdCertParms& aParms); + void UpdateTrustedL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber, const CDmAdCertParms& aParms); + void UpdateApplicabilityL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber, const CDmAdCertParms& aParms); + TPtrC8 AppendCertLuidMappingElemL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber); + void RemoveCertLuidMappingElem(const TDesC8& aLuid); + CDmAdCertLuidMappingElem* FindCertLuidMappingElemL(const TDesC8& aLuid); + void BuildCertLuidMappingTableL(); + HBufC8* BuildCertRefL(const TDesC8& aCertificateDer, TBool aAppend); + void GetIssuerAndSerialFromCertRefLC(const TDesC8& aCertRef, + HBufC8*& aIssuerName, + HBufC8*& aSerialNumber); + HBufC8* CertSubjectNameL(const TDesC8& aCertificateDer); + +private: + RPKIServiceAPI* iPkiServiceApi; + CArrayPtr* iCertLuidMapping; + DEFINE_EVENT_LOGGER + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/dmadstorecertreq.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/dmadstorecertreq.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdCertReq. +* +*/ + + + +#ifndef __DMADSTORECERTREQ_H__ +#define __DMADSTORECERTREQ_H__ + +#include +#include + +#include "pkiserviceapi.h" +#include "dmadcertreqparms.h" + +class MDmAdCallBack; + +class CDmAdCertReq : public CBase + { +public: + static CDmAdCertReq* NewL(RPKIServiceAPI& aPkiServiceApi, MDmAdCallBack* aDmAdCallBack); + static CDmAdCertReq* NewLC(RPKIServiceAPI& aPkiServiceApi, MDmAdCallBack* aDmAdCallBack); + ~CDmAdCertReq(); + + TBool FindL(const TDesC8& aLuid); + HBufC8* AddL(const CDmAdCertReqParms& aData); // returns Luid + void UpdateL(const TDesC8& aLuid, const CDmAdCertReqParms& aData); + void FetchL(const TDesC8& aLuid, CDmAdCertReqParms& aData); + void DeleteL(const TDesC8& aLuid); + void ListL(RPointerArray& aLuidList); + +private: + CDmAdCertReq(RPKIServiceAPI& aPkiServiceApi, MDmAdCallBack* aDmAdCallBack); + void CreateKeypairL(TPKIKeyAlgorithm aKeyAlgorithm, + TInt aKeyLength, + TPKIKeyIdentifier& aKeyIdentifier); + HBufC8* CertReqRefToLuidL(const TDesC& aCertReqRef); + HBufC* LuidToCertReqRefL(const TDesC8& aLuid); + void SetKeyIDMappingL(const TPKIKeyIdentifier& keyIdentifier); + +private: + RPKIServiceAPI* iPkiServiceApi; + MDmAdCallBack* iDmAdCallBack; + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/dmadstorepkcs12.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/dmadstorepkcs12.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdPKCS12 +* +*/ + + + +#ifndef __DMADSTOREPKCS12_H__ +#define __DMADSTOREPKCS12_H__ + +#include +#include +#include + +#include "eventlogger.h" + +#include "pkiserviceapi.h" +#include "dmadpkcs12parms.h" + +class CDmAdPKCS12 : public CBase + { +public: + static CDmAdPKCS12* NewL(RPKIServiceAPI& aPkiServiceApi); + static CDmAdPKCS12* NewLC(RPKIServiceAPI& aPkiServiceApi); + ~CDmAdPKCS12(); + + HBufC8* AddL(const CDmAdPKCS12Parms& aData); // returns Luid + +private: + void ConstructL(); + CDmAdPKCS12(RPKIServiceAPI& aPkiServiceApi); + +private: + RPKIServiceAPI* iPkiServiceApi; // ref + DEFINE_EVENT_LOGGER + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/dmadstoreprivkey.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/dmadstoreprivkey.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class definition of CDmAdPrivKey. +* +*/ + + + +#ifndef __DMADSTOREPRIVKEY_H__ +#define __DMADSTOREPRIVKEY_H__ + +#include +#include +#include + +#include "pkiserviceapi.h" +#include "dmadprivkeyparms.h" + +class CDmAdPrivKey : public CBase + { +public: + static CDmAdPrivKey* NewL(RPKIServiceAPI& aPkiServiceApi); + static CDmAdPrivKey* NewLC(RPKIServiceAPI& aPkiServiceApi); + ~CDmAdPrivKey(); + + TBool FindL(const TDesC8& aLuid); + void FetchL(const TDesC8& aLuid, CDmAdPrivKeyParms& aData); + void DeleteL(const TDesC8& aLuid); + void ListL(RPointerArray& aLuidList); + +private: + CDmAdPrivKey(RPKIServiceAPI& aPkiServiceApi); + + + RPKIServiceAPI* iPkiServiceApi; + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/inc/log.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/inc/log.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Logging utility. +* +*/ + + + +#if !defined(__LOG_H__) +#define __LOG_H__ + +_LIT(KLogFile,"dmad.txt"); + +#include "logcommon.h" + +#endif // __LOG_H__ diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/rom/dmadpki.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/rom/dmadpki.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Image description file for project dmadpki +* +*/ + + + +#ifndef __DMADPKI_IBY__ +#define __DMADPKI_IBY__ + +#ifdef SYMBIAN_EXCLUDE_IPSEC + +REM dmadpki not included in this rom + +#else + +ECOM_PLUGIN(dmadpki.dll, dmadpki.rsc) + +#endif // SYMBIAN_EXCLUDE_IPSEC + +#endif // __DMADPKI_IBY__ diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/src/DmAdRtNodeData.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/src/DmAdRtNodeData.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,1596 @@ +/* +* Copyright (c) 2000-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CDmAdRtNodeData +* +*/ + + + +#include + +#include +#include +#include +#include + +#include "DmAdRtNodeData.h" +#include "dmadddf.h" +#include "dmadutil.h" +#include "vpnlogger.h" +#include "dmadstoreprivkey.h" +#include "pkidefs.h" +#include "XwImpl.h" +#include "dmadcertxmldefs.h" +#include "XppImpl.h" +#include + + +// Macro to encode key usage bits +// See method CDmAdCertData::KeyUsageLC +#define ENC_BIT(a) \ + if( EFalse == keyUsageExt->IsSet(a) ) \ + { \ + keyUsagePtr.Append('0'); \ + } \ + else \ + { \ + keyUsagePtr.Append('1'); \ + } + + +CDmAdRtNodeData* CDmAdRtNodeData::NewL(const TDesC8& aUri, MDmAdCallBack* aCallBack) + { + TRACE("CDmAdRtNodeData::NewL"); + + CDmAdRtNodeData *self = new (ELeave) CDmAdRtNodeData(); + CleanupStack::PushL(self); + self->ConstructL(aUri, aCallBack); + CleanupStack::Pop(self); + return self; + } + +void CDmAdRtNodeData::ConstructL(const TDesC8& aUri, MDmAdCallBack* aCallBack) + { + TRACE("CDmAdRtNodeData::ConstructL"); + + iUriType = UriTypeL(aUri); + + switch (iUriType) + { + case EDmAdUriTypeCert: + u.iCert = CDmAdCertData::NewL(aCallBack); + break; + case EDmAdUriTypeCertReq: + u.iCertReq = CDmAdCertReqData::NewL(aCallBack); + break; + case EDmAdUriTypePrivKey: + u.iPrivKey = CDmAdPrivKeyData::NewL(); + break; + case EDmAdUriTypePKCS12: + u.iPKCS12 = CDmAdPKCS12Data::NewL(); + break; + default: + DEBUG_LOG(_L("Unknown URI type")); + User::Leave(KErrGeneral); + break; + } + } + +CDmAdRtNodeData::CDmAdRtNodeData() + { + } + +CDmAdRtNodeData::~CDmAdRtNodeData() + { + TRACE("CDmAdRtNodeData::~CDmAdRtNodeData"); + + switch (iUriType) + { + case EDmAdUriTypeCert: + delete u.iCert; + break; + case EDmAdUriTypeCertReq: + delete u.iCertReq; + break; + case EDmAdUriTypePrivKey: + delete u.iPrivKey; + break; + case EDmAdUriTypePKCS12: + delete u.iPKCS12; + break; + default: + DEBUG_LOG(_L("Unknown URI type")); + break; + } + } + +//-------------------------------------------------------------------------- + +TDmAdUriType CDmAdRtNodeData::UriType() const + { + TRACE("CDmAdRtNodeData::UriType"); + + return iUriType; + } + +TDmAdUriType CDmAdRtNodeData::UriTypeL(const TDesC8& aUri) + { + TRACE("CDmAdRtNodeData::UriTypeL"); + + TDmAdUriType ret = EDmAdUriTypeCert; + CArrayFix* uriSegList; + TDmAdUtil::ParseUriLC(aUri, uriSegList); + + if (uriSegList->Count() < 2) + { + DEBUG_LOG(_L("uriSegList->Count() is less than 2")); + User::Leave(KErrGeneral); + } + + if (uriSegList->At(0).Compare(KDmAdNodeNokiaPki) == 0) + { + if (uriSegList->At(1).Compare(KDmAdNodeCert) == 0) + { + ret = EDmAdUriTypeCert; + } + else if (uriSegList->At(1).Compare(KDmAdNodeCertReq) == 0) + { + ret = EDmAdUriTypeCertReq; + } + else if (uriSegList->At(1).Compare(KDmAdNodePrivKey) == 0) + { + ret = EDmAdUriTypePrivKey; + } + else if (uriSegList->At(1).Compare(KDmAdNodePKCS12) == 0) + { + ret = EDmAdUriTypePKCS12; + } + else + { + DEBUG_LOG(_L("Unknown URI type")); + User::Leave(KErrGeneral); + } + } + else + { + DEBUG_LOG(_L("Unknown URI type")); + User::Leave(KErrGeneral); + } + + CleanupStack::PopAndDestroy(uriSegList); + return ret; + } + +//-------------------------------------------------------------------------- + +void CDmAdRtNodeData::UpdateLeafDataL(const TDesC8& aUri, const TDesC8& aObject) + { + TRACE("CDmAdRtNodeData::UpdateLeafDataL"); + + switch (iUriType) + { + case EDmAdUriTypeCert: + TRAPD(err, UpdateLeafDataCertL(aUri, aObject)); + if(err != KErrNone) + User::Leave(err); + break; + case EDmAdUriTypeCertReq: + UpdateLeafDataCertReqL(aUri, aObject); + break; + case EDmAdUriTypePrivKey: + UpdateLeafDataPrivKeyL(aUri, aObject); + break; + case EDmAdUriTypePKCS12: + UpdateLeafDataPKCS12L(aUri, aObject); + break; + default: + DEBUG_LOG(_L("Unknown URI type")); + User::Leave(KErrGeneral); + break; + } + } + +void CDmAdRtNodeData::UpdateLeafDataCertL(const TDesC8& aUri, const TDesC8& aObject) + { + TRACE("CDmAdRtNodeData::UpdateLeafDataCertL"); + + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdLeafContent) == 0) + { + u.iCert->SetContentL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafType) == 0) + { + u.iCert->SetTypeL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafFormat) == 0) + { + u.iCert->SetFormatL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafDeletable) == 0) + { + u.iCert->SetDeletableL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafTrusted) == 0) + { + u.iCert->SetTrustedL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafApplicability) == 0) + { + RArray applicability; + CleanupClosePushL(applicability); + + ParseApplicabilityL(aObject, applicability); + u.iCert->SetApplicabilityL(applicability); + + CleanupStack::PopAndDestroy(); //applicability + } + else + { + DEBUG_LOG(_L("No match found")); + User::Leave(KErrNotFound); + } + } + +void CDmAdRtNodeData::UpdateLeafDataCertReqL(const TDesC8& aUri, const TDesC8& aObject) + { + TRACE("CDmAdRtNodeData::UpdateLeafDataCertReqL"); + + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdLeafSubjectName) == 0) + { + u.iCertReq->SetSubjectNameL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafRfc822Name) == 0) + { + u.iCertReq->SetRfc822NameL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafKeyURI) == 0) + { + u.iCertReq->SetKeyUriL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafKeyLength) == 0) + { + u.iCertReq->SetKeyLength(aObject); + } + else + { + DEBUG_LOG(_L("No match found")); + User::Leave(KErrNotFound); + } + } + +void CDmAdRtNodeData::UpdateLeafDataPrivKeyL(const TDesC8& aUri, const TDesC8& aObject) + { + TRACE("CDmAdRtNodeData::UpdateLeafDataPrivKeyL"); + + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdLeafKeyType) == 0) + { + u.iPrivKey->SetKeyTypeL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafKeyLength) == 0) + { + u.iPrivKey->SetKeyLength(aObject); + } + else + { + DEBUG_LOG(_L("No match found")); + User::Leave(KErrNotFound); + } + } + +void CDmAdRtNodeData::UpdateLeafDataPKCS12L(const TDesC8& aUri, const TDesC8& aObject) + { + TRACE("CDmAdRtNodeData::UpdateLeafDataPKCS12L"); + + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdLeafContent) == 0) + { + u.iPKCS12->SetContentL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafDeletable) == 0) + { + u.iPKCS12->SetDeletableL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafPKCS12Password) == 0) + { + u.iPKCS12->SetPasswordL(aObject); + } + else if (lastSeg.Compare(KDmAdLeafApplicability) == 0) + { + RArray applicability; + CleanupClosePushL(applicability); + + ParseApplicabilityL(aObject, applicability); + u.iPKCS12->SetApplicabilityL(applicability); + + CleanupStack::PopAndDestroy(); //applicability + } + else + { + DEBUG_LOG(_L("No match found")); + User::Leave(KErrNotFound); + } + + } + +void CDmAdRtNodeData::FetchLeafObjectLC(const TDesC8& aUri, const TDesC8& aLuid, CBufBase*& aObject) + { + switch (iUriType) + { + case EDmAdUriTypeCert: + FetchLeafObjectCertLC(aUri, aLuid, aObject); + break; + case EDmAdUriTypeCertReq: + FetchLeafObjectCertReqLC(aUri, aLuid, aObject); + break; + case EDmAdUriTypePrivKey: + FetchLeafObjectPrivKeyLC(aUri, aLuid, aObject); + break; + case EDmAdUriTypePKCS12: + // PKCS#12 special case + break; + default: + DEBUG_LOG(_L("Unknown URI type")); + User::Leave(KErrGeneral); + break; + } + } + +void CDmAdRtNodeData::FetchLeafObjectCertLC(const TDesC8& aUri, const TDesC8& /*aLuid*/, CBufBase*& aObject) + { + CBufBase* object = CBufFlat::NewL(32); + CleanupStack::PushL(object); + + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdLeafType) == 0) + { + HBufC8* obj = u.iCert->TypeLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + } + else if (lastSeg.Compare(KDmAdLeafFormat) == 0) + { + HBufC8* obj = u.iCert->FormatLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + } + else if (lastSeg.Compare(KDmAdLeafDeletable) == 0) + { + HBufC8* obj = u.iCert->DeletableLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + } + else if (lastSeg.Compare(KDmAdLeafTrusted) == 0) + { + HBufC8* obj = u.iCert->TrustedLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + } + else if (lastSeg.Compare(KDmAdLeafApplicability) == 0) + { + + DEBUG_LOG(_L("Fetching applicability")); + const RArray& applicability = u.iCert->Applicability(); + + CXmlWriter* writer = CXmlWriter::NewL(); + CleanupStack::PushL(static_cast(writer)); + writer->AddStartTagL(KXmlElemCertApps); + + DEBUG_LOG(_L("KXmlElemCertApps Start tag added")); + + for (TInt i = 0; i < applicability.Count(); ++i) + { + HBufC8* idInt = TDmAdUtil::IntToDes8LC((TInt)applicability[i].iUid); + writer->OpenStartTagL(KXmlElemApp); + writer->AddAttributeL(KXmlAttrId, *idInt); + writer->CloseStartTagL(ETrue); + CleanupStack::PopAndDestroy(idInt); + } + writer->AddEndTagL(KXmlElemCertApps); + + DEBUG_LOG(_L("KXmlElemCertApps end tag added")); + + TPtrC8 docDataPtr(writer->DocPart(0, writer->Length()-1)); + object->InsertL(0, docDataPtr); + + DEBUG_LOG(_L("document inserted")); + + CleanupStack::PopAndDestroy(static_cast(writer)); + + DEBUG_LOG(_L("writer popped")); + } + else if (lastSeg.Compare(KDmAdLeafContent) == 0) + { + TPtrC8 obj(u.iCert->Content()); + object->InsertL(0, obj); + } + else if (lastSeg.Compare(KDmAdLeafSerialNumber) == 0) + { + HBufC8* obj = u.iCert->SerialNumberLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + } + else if (lastSeg.Compare(KDmAdLeafIssuerName) == 0) + { + HBufC8* obj = u.iCert->IssuerNameLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + } + else if (lastSeg.Compare(KDmAdLeafFingerprintAlg) == 0) + { + HBufC8* obj = u.iCert->FingerprintAlgLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + } + else if (lastSeg.Compare(KDmAdLeafFingerprintValue) == 0) + { + HBufC8* obj = u.iCert->FingerprintValueLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + } + else if (lastSeg.Compare(KDmAdLeafValidityBegin) == 0) + { + HBufC8* obj = u.iCert->ValidityBeginLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + } + else if (lastSeg.Compare(KDmAdLeafValidityEnd) == 0) + { + HBufC8* obj = u.iCert->ValidityEndLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + } + else if (lastSeg.Compare(KDmAdLeafSubjectName) == 0) + { + HBufC8* obj = u.iCert->SubjectNameLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + } + else if (lastSeg.Compare(KDmAdLeafSubjectAltName) == 0) + { + HBufC8* obj = u.iCert->SubjectAltNameLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + } + else if (lastSeg.Compare(KDmAdLeafKeyURI) == 0) + { + HBufC8* obj = u.iCert->KeyUriLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + } + else if (lastSeg.Compare(KDmAdLeafKeyId) == 0) + { + HBufC8* obj = u.iCert->KeyIdLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + } + else if (lastSeg.Compare(KDmAdLeafKeyUsage) == 0) + { + HBufC8* obj = u.iCert->KeyUsageLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + } + else + { + DEBUG_LOG(_L("No match found")); + User::Leave(KErrNotFound); + } + + aObject = object; + } + +void CDmAdRtNodeData::FetchLeafObjectCertReqLC(const TDesC8& aUri, const TDesC8& /*aLuid*/, CBufBase*& aObject) + { + CBufBase* object = CBufFlat::NewL(32); + CleanupStack::PushL(object); + + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdLeafSubjectName) == 0) + { + TPtrC8 obj(u.iCertReq->SubjectName()); + object->InsertL(0, obj); + } + else if (lastSeg.Compare(KDmAdLeafRfc822Name) == 0) + { + TPtrC8 obj(u.iCertReq->Rfc822Name()); + object->InsertL(0, obj); + } + else if (lastSeg.Compare(KDmAdLeafKeyURI) == 0) + { + HBufC8* obj = u.iCertReq->KeyUriL(); + CleanupStack::PushL(obj); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(obj); + } + else if (lastSeg.Compare(KDmAdLeafKeyLength) == 0) + { + HBufC8* obj = u.iCertReq->KeyLengthLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(); //obj + } + else if (lastSeg.Compare(KDmAdLeafContent) == 0) + { + TPtrC8 obj(u.iCertReq->Content()); + object->InsertL(0, obj); + } + else + { + DEBUG_LOG(_L("No match found")); + User::Leave(KErrNotFound); + } + + aObject = object; + } + +void CDmAdRtNodeData::FetchLeafObjectPrivKeyLC(const TDesC8& aUri, const TDesC8& /*aLuid*/, CBufBase*& aObject) + { + CBufBase* object = CBufFlat::NewL(32); + CleanupStack::PushL(object); + + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdLeafKeyType) == 0) + { + HBufC8* obj = u.iPrivKey->KeyTypeLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(); //obj + } + else if (lastSeg.Compare(KDmAdLeafKeyLength) == 0) + { + HBufC8* obj = u.iPrivKey->KeyLengthLC(); + object->InsertL(0, *obj); + CleanupStack::PopAndDestroy(); //obj + } + else if (lastSeg.Compare(KDmAdLeafKeyId) == 0) + { + TPtrC8 obj(u.iPrivKey->KeyId()); + object->InsertL(0, obj); + } + else + { + DEBUG_LOG(_L("No match found")); + User::Leave(KErrNotFound); + } + + aObject = object; + } + +void CDmAdRtNodeData::SetDefaultSettingsL(const TDesC8& /*aUri*/) + { + TRACE("CDmAdRtNodeData::SetDefaultSettingsL"); + + switch (iUriType) + { + case EDmAdUriTypeCert: + u.iCert->SetDefaultSettings(); + break; + case EDmAdUriTypeCertReq: + u.iCertReq->SetDefaultSettings(); + break; + case EDmAdUriTypePrivKey: + u.iPrivKey->SetDefaultSettingsL(); + break; + case EDmAdUriTypePKCS12: + u.iPKCS12->SetDefaultSettings(); + break; + default: + DEBUG_LOG(_L("Unknown URI type")); + User::Leave(KErrGeneral); + break; + } + } + + +void CDmAdRtNodeData::ParseApplicabilityL(const TDesC8& aApplicabilityData, + RArray& aApplicabilityList) const + { + TRACE("CDmAdRtNodeData::ParseApplicabilityL"); + + aApplicabilityList.Reset(); + + if (aApplicabilityData.Length() == 0) + { + return; + } + + CDesC8ArrayFlat* parserValueArray = new (ELeave) CDesC8ArrayFlat(10); + CleanupStack::PushL(parserValueArray); + CXmlPullParser* parser = CXmlPullParser::NewLC(*parserValueArray); + TPtrC8 name; + TPtrC8 attribute; + + parser->SetInput(aApplicabilityData); + parser->NextL(); + parser->Name(name); + + if (parser->State() != CXmlPullParser::EStateStartTag || name != KXmlElemCertApps) + { + DEBUG_LOG(_L("Wrong state or name. (Expected EStateStartTag and CertApps")); + DEBUG_LOG2(_L8("State = %d, name = %S"), parser->State(), &name); + User::Leave(KErrCorrupt); + } + + parser->NextL(); + while (parser->State() == CXmlPullParser::EStateText) + { + DEBUG_LOG(_L8("Found text. Ignoring it...")); + parser->NextL(); + } + + while (parser->State() == CXmlPullParser::EStateStartTag) + { + parser->Name(name); + DEBUG_LOG1(_L8("Parsed: %S"), &name); + + if (name != KXmlElemApp) + { + DEBUG_LOG1(_L8("Invalid name: %S"), &name); + User::Leave(KErrCorrupt); + } + + parser->AttributeValueL(KXmlAttrId, attribute); + TUid uid = { TDmAdUtil::DesToInt(attribute) }; + DEBUG_LOG1(_L("Uid: 0x%x"), uid.iUid); + + aApplicabilityList.Append(uid); + parser->NextL(); + + while (parser->State() == CXmlPullParser::EStateText) + { + DEBUG_LOG(_L8("Found text. Ignoring it...")); + parser->NextL(); + } + } + parser->Name(name); + + if (parser->State() != CXmlPullParser::EStateEndTag || name != KXmlElemCertApps) + { + DEBUG_LOG(_L("Wrong state or name. (Expected EStateEndTag and CertApps)")); + DEBUG_LOG2(_L8("State = %d, name = %S"), parser->State(), &name); + User::Leave(KErrCorrupt); + } + CleanupStack::PopAndDestroy(2); //parser, parserValueArray + } + + +//====================================================================================== +//====================================================================================== + +CDmAdCertData* CDmAdCertData::NewL(MDmAdCallBack* aCallBack) + { + TRACE("CDmAdCertData::NewL"); + + CDmAdCertData* self = new (ELeave) CDmAdCertData(aCallBack); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +void CDmAdCertData::ConstructL() + { + TRACE("CDmAdCertData::ConstructL"); + + iCertParms = CDmAdCertParms::NewL(); + } + +CDmAdCertData::CDmAdCertData(MDmAdCallBack* aCallBack) : iCallBack(aCallBack) + { + } + +CDmAdCertData::~CDmAdCertData() + { + TRACE("CDmAdCertData::~CDmAdCertData"); + + delete iCertParms; + delete iCertCx509; + } + +void CDmAdCertData::SetDefaultSettings() + { + TRACE("CDmAdCertData::SetDefaultSettings"); + + iCertParms->SetDeletable(ETrue); + iCertParms->SetTrusted(ETrue); + } + +//-------------------------------------------------------------------------- + +void CDmAdCertData::SetTypeL(const TDesC8& aType) + { + TRACE("CDmAdCertData::SetType"); + + TInt value = TDmAdUtil::DesToInt(aType); + + TPKICertificateOwnerType type = EPKICACertificate; + switch(value) + { + case 1: + type = EPKICACertificate; + break; + case 2: + type = EPKIUserCertificate; + break; + case 3: + type = EPKIPeerCertificate; + break; + default: + User::Leave(KErrCorrupt); + break; + } + + iCertParms->SetType(type); + } + +HBufC8* CDmAdCertData::TypeLC() + { + + TPKICertificateOwnerType type = iCertParms->Type(); + TInt omaDmType = 0; + switch(type) + { + case EPKICACertificate: + omaDmType = 1; + break; + case EPKIUserCertificate: + omaDmType = 2; + break; + case EPKIPeerCertificate: + omaDmType = 3; + break; + default: + User::Leave(KErrCorrupt); + break; + } + + return TDmAdUtil::IntToDes8LC(omaDmType); + } + +void CDmAdCertData::SetFormatL(const TDesC8& aFormat) + { + TRACE("CDmAdCertData::SetFormat"); + TInt value = TDmAdUtil::DesToInt(aFormat); + + if (value != 1) + { + User::Leave(KErrCorrupt); + } + } + +HBufC8* CDmAdCertData::FormatLC() + { + //The format is always 1, which means X509 cert. + return TDmAdUtil::IntToDes8LC(1); + } + +void CDmAdCertData::SetDeletableL(const TDesC8& aDeletable) + { + TRACE("CDmAdCertData::SetDeletableL"); + + if (aDeletable.Compare(KDmAdDfFormatBoolTrue) == 0) + { + iCertParms->SetDeletable(ETrue); + } + else if (aDeletable.Compare(KDmAdDfFormatBoolFalse) == 0) + { + iCertParms->SetDeletable(EFalse); + } + else + { + DEBUG_LOG(_L("Comparization failed")); + User::Leave(KErrGeneral); + } + } + +HBufC8* CDmAdCertData::DeletableLC() + { + if (iCertParms->Deletable()) + { + return KDmAdDfFormatBoolTrue().AllocLC(); + } + else + { + return KDmAdDfFormatBoolFalse().AllocLC(); + } + } + +void CDmAdCertData::SetTrustedL(const TDesC8& aTrusted) + { + TRACE("CDmAdCertData::SetTrustedL"); + + if (aTrusted.Compare(KDmAdDfFormatBoolTrue) == 0) + { + iCertParms->SetTrusted(ETrue); + } + else if (aTrusted.Compare(KDmAdDfFormatBoolFalse) == 0) + { + iCertParms->SetTrusted(EFalse); + } + else + { + DEBUG_LOG(_L("No match found")); + User::Leave(KErrGeneral); + } + } + +HBufC8* CDmAdCertData::TrustedLC() + { + if (iCertParms->Trusted()) + { + return KDmAdDfFormatBoolTrue().AllocLC(); + } + else + { + return KDmAdDfFormatBoolFalse().AllocLC(); + } + } + +void CDmAdCertData::SetApplicabilityL(const RArray& aApplicability) + { + TRACE("CDmAdCertData::SetApplicabilityL"); + + iCertParms->SetApplicabilityL(aApplicability); + } + +const RArray& CDmAdCertData::Applicability() const + { + TRACE("CDmAdCertData::Applicability"); + + return iCertParms->Applicability(); + } + +void CDmAdCertData::SetContentL(const TDesC8& aContent) + { + TRACE("CDmAdCertData::SetContentL"); + + delete iCertCx509; + iCertCx509 = NULL; + iCertParms->SetContentL(aContent); + if (iCertParms->Content().Length() > 0) + { + iCertCx509 = CX509Certificate::NewL(iCertParms->Content()); + } + } + +TPtrC8 CDmAdCertData::Content() + { + TRACE("CDmAdCertData::Content"); + + return iCertParms->Content(); + } + +//----------------- + +HBufC8* CDmAdCertData::SerialNumberLC() + { + HBufC8* ret = NULL; + const TPtrC8 serialNumber(iCertCx509->SerialNumber()); + //const TPtrC8 serialNumber(*(iCertCx509->DataElementEncoding(CX509Certificate::ESerialNumber))); + if (serialNumber.Length() == 0) + { + ret = HBufC8::NewLC(1); + } + else + { + ret = serialNumber.AllocLC(); + } + return ret; + } + +HBufC8* CDmAdCertData::IssuerNameLC() + { + HBufC8* ret = NULL; + const TPtrC8 issuerName(*(iCertCx509->DataElementEncoding(CX509Certificate::EIssuerName))); + if (issuerName.Length() == 0) + { + ret = HBufC8::NewLC(1); + } + else + { + ret = issuerName.AllocLC(); + } + return ret; + } + +HBufC8* CDmAdCertData::FingerprintAlgLC() + { + if (iCertCx509->Fingerprint().Length() == 16) + { + return TDmAdUtil::IntToDes8LC(1); // MD5 + } + else + { + return TDmAdUtil::IntToDes8LC(2); // SHA1 + } + } + +HBufC8* CDmAdCertData::FingerprintValueLC() + { + return iCertCx509->Fingerprint().AllocLC(); + } + +HBufC8* CDmAdCertData::ValidityBeginLC() + { + TTime beginTime = iCertCx509->ValidityPeriod().Start(); + return FormatCertValidityTimeLC(beginTime); + } + +HBufC8* CDmAdCertData::ValidityEndLC() + { + TTime endTime = iCertCx509->ValidityPeriod().Finish(); + return FormatCertValidityTimeLC(endTime); + } + +HBufC8* CDmAdCertData::SubjectNameLC() + { + HBufC8* ret = NULL; + const TPtrC8 subjectName(*(iCertCx509->DataElementEncoding(CX509Certificate::ESubjectName))); + if (subjectName.Length() == 0) + { + ret = HBufC8::NewLC(1); + } + else + { + ret = subjectName.AllocLC(); + } + return ret; + } + +HBufC8* CDmAdCertData::SubjectAltNameLC() + { + HBufC8* subjectAltNameExtRfc822 = HBufC8::NewLC(KMaxRfc822); + TPtr8 subjectAltNameExtRfc822Ptr(subjectAltNameExtRfc822->Des()); + + const CX509CertExtension* subjAltName; + subjAltName = iCertCx509->Extension(KSubjectAltName); + if (subjAltName) + { + CX509AltNameExt* subjectAlt = CX509AltNameExt::NewLC(subjAltName->Data()); + if (subjectAlt) + { + const CArrayPtrFlat* nameArray; + nameArray = &subjectAlt->AltName(); + // Search rfc822 + for (TInt i = 0; i < nameArray->Count(); i++) + { + if(nameArray->At(i)->Tag() == EX509RFC822Name) + { + TPtrC8 data = nameArray->At(i)->Data(); + subjectAltNameExtRfc822Ptr.Copy(data.Right(data.Length() - 2)); + break; + } + } + CleanupStack::PopAndDestroy(subjectAlt); + } + } + return subjectAltNameExtRfc822; + } + +HBufC8* CDmAdCertData::KeyUriLC() + { + HBufC8* keyId = KeyIdLC(); + HBufC8* keyUri = FindKeyUriLC(*keyId); + CleanupStack::Pop(keyUri); + CleanupStack::PopAndDestroy(keyId); + CleanupStack::PushL(keyUri); + return keyUri; + } + +HBufC8* CDmAdCertData::KeyIdLC() + { +#if 0 + const CSubjectPublicKeyInfo* subjectPublicKeyInfo = &iCertCx509->PublicKey(); + if (subjectPublicKeyInfo->AlgorithmId() != ERSA) + { + return HBufC8::NewLC(1); + } + + return TDmAdCertUtil::RSAKeyIdentifierLC(subjectPublicKeyInfo->KeyData()); +#else + return iCertCx509->KeyIdentifierL().AllocLC(); +#endif + } + + +HBufC8* CDmAdCertData::KeyUsageLC() + { + const TInt KKeyUsageTxtLen = 12; + HBufC8* keyUsage = HBufC8::NewLC(KKeyUsageTxtLen); + TPtr8 keyUsagePtr(keyUsage->Des()); + + const CX509CertExtension* certExt = iCertCx509->Extension(KKeyUsage); + + if(0 == certExt) + { + return keyUsage; + } + + const CX509KeyUsageExt* keyUsageExt = + CX509KeyUsageExt::NewLC(certExt->Data()); + + // Encode key usage values to bstring format + // See IETF RFC 3641. + keyUsagePtr.Append('\''); + + ENC_BIT( EX509DigitalSignature ); + ENC_BIT( EX509NonRepudiation ); + ENC_BIT( EX509KeyEncipherment ); + ENC_BIT( EX509DataEncipherment ); + ENC_BIT( EX509KeyAgreement ); + ENC_BIT( EX509KeyCertSign ); + ENC_BIT( EX509CRLSign ); + ENC_BIT( EX509EncipherOnly ); + ENC_BIT( EX509DecipherOnly ); + + keyUsagePtr.Append(_L8("'B")); + + CleanupStack::PopAndDestroy(); // keyUsageExt + + return keyUsage; + } + + +HBufC8* CDmAdCertData::FormatCertValidityTimeLC(const TTime& aTime) + { + TDateTime time = aTime.DateTime(); + + HBufC8* ret = HBufC8::NewLC(20); + TPtr8 retPtr(ret->Des()); + + _LIT8(KFormatTxt,"%4d%02d%02dT%02d%02d%02dZ"); + retPtr.Format(KFormatTxt, + time.Year(), + TInt(time.Month()+1), + // Format the month as a TInt to preserve locale independence + time.Day()+1, + // Day and month ranges begin at zero (0-30 and 0-11), + // so add one when formatting + time.Hour(), + time.Minute(), + time.Second()); + return ret; + } + +HBufC8* CDmAdCertData::FindKeyUriLC(const TDesC8& aKeyId) + { + DEBUG_LOG(_L("CDmAdCertData::FindKeyUriLC:")); + DEBUG_LOG_HEX(aKeyId); + + _LIT8(KDmAdPrivKeyUri, "NokiaPKI/PrivKey"); + +#if 1 + + HBufC8* uri = iCallBack->FindChildUriL(KDmAdPrivKeyUri, aKeyId); + if (uri != 0) + { + DEBUG_LOG(_L("CDmAdCertData::FindKeyUriLC:")); + DEBUG_LOG_HEX(*uri); + } + else + { + DEBUG_LOG(_L("URI not found")); + uri = HBufC8::NewL(1); + } + + CleanupStack::PushL(uri); + return uri; + +#else + + HBufC8* ret = 0; + + CBufBase* childUriList = CBufFlat::NewL(16); + CleanupStack::PushL(childUriList); + MSmlDmAdapter::TError status; + iCallBack->FetchLinkL(KDmAdPrivKeyUri, *childUriList, status); + if (status != MSmlDmAdapter::EOk) + { + DMADERR(DmAdErr::Printf(_L("***CDmAdCertData::FindKeyUriLC: %d (line=%d)\n"), KDmAdErr1, __LINE__)); + User::Leave(KErrGeneral); + } + + CArrayFix* uriSegList; + TDmAdUtil::ParseUriLC(childUriList->Ptr(0), uriSegList); + + TBool found = EFalse; + HBufC8* uri = 0; + HBufC8* uriKeyId = 0; + for (TInt i=0; iCount(); ++i) + { + uri = TDmAdUtil::BuildUriLC(KDmAdPrivKeyUri, uriSegList->At(i)); + uriKeyId = TDmAdUtil::BuildUriLC(*uri, KDmAdLeafKeyId); + + CBufBase* keyId = CBufFlat::NewL(16); + CleanupStack::PushL(keyId); + iCallBack->FetchLinkL(*uriKeyId, *keyId, status); + if (status != MSmlDmAdapter::EOk) + { + DMADERR(DmAdErr::Printf(_L("***CDmAdCertData::FindKeyUriLC: %d (line=%d)\n"), KDmAdErr1, __LINE__)); + User::Leave(KErrGeneral); + } + if (keyId->Ptr(0).Compare(aKeyId) == 0) + { + found = ETrue; + CleanupStack::PopAndDestroy(2); // keyId, uriKeyId + break; + } + CleanupStack::PopAndDestroy(3); // keyId, uriKeyId, uri + } + + if (found) + { + DMADLOG(DmAdLog::Printf(_L("CDmAdCertData::FindKeyUriLC:\n"))); + DMADLOG(DmAdLog::HexDump(NULL, NULL, uri->Ptr(), uri->Size())); + CleanupStack::Pop(uri); + ret = uri; + } + else + { + DMADLOG(DmAdLog::Printf(_L("CDmAdCertData::FindKeyUriLC: not found\n"))); + ret = HBufC8::NewL(1); + } + + CleanupStack::PopAndDestroy(2); //uriSegList, childUriList + CleanupStack::PushL(ret); + return ret; +#endif + } + + + +//-------------------------------------------------------------------------- + +void CDmAdCertData::RestoreL(const CDmAdCertParms& aCertParms) + { + TRACE("CDmAdCertData::RestoreL"); + + iCertParms->SetType(aCertParms.Type()); + iCertParms->SetDeletable(aCertParms.Deletable()); + iCertParms->SetTrusted(aCertParms.Trusted()); + iCertParms->SetApplicabilityL(aCertParms.Applicability()); + + delete iCertCx509; + iCertCx509 = 0; + iCertParms->SetContentL(aCertParms.Content()); + if (iCertParms->Content().Length() > 0) + { + iCertCx509 = CX509Certificate::NewL(iCertParms->Content()); + } + + iCertParms->SetKeyId(aCertParms.KeyId()); // now NULL + } + +void CDmAdCertData::ToStoreL(CDmAdCertParms& aCertParms) + { + TRACE("CDmAdCertData::ToStoreL"); + + aCertParms.SetType(iCertParms->Type()); + aCertParms.SetDeletable(iCertParms->Deletable()); + aCertParms.SetTrusted(iCertParms->Trusted()); + aCertParms.SetApplicabilityL(iCertParms->Applicability()); + aCertParms.SetContentL(iCertParms->Content()); + + if (iCertCx509 == NULL) + { + DEBUG_LOG(_L("No cert!")); + User::Leave(KErrGeneral); + } + TKeyIdentifier keyId = iCertCx509->KeyIdentifierL(); //TKeyIdentifier is 20 bytes long + aCertParms.SetKeyId(keyId); + } + + + +//====================================================================================== +//====================================================================================== + +CDmAdCertReqData* CDmAdCertReqData::NewL(MDmAdCallBack* aCallBack) + { + TRACE("CDmAdCertReqData::NewL"); + + CDmAdCertReqData* self = new (ELeave) CDmAdCertReqData(aCallBack); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +void CDmAdCertReqData::ConstructL() + { + TRACE("CDmAdCertReqData::ConstructL"); + iCertReqParms = CDmAdCertReqParms::NewL(); + } + +CDmAdCertReqData::CDmAdCertReqData(MDmAdCallBack* aCallBack) : iCallBack(aCallBack) + { + } + +CDmAdCertReqData::~CDmAdCertReqData() + { + TRACE("CDmAdCertReqData::~CDmAdCertReqData"); + delete iCertReqParms; + } + +void CDmAdCertReqData::SetDefaultSettings() + { + TRACE("CDmAdCertReqData::SetDefaultSettings"); + iCertReqParms->SetKeyLength(1024); + } + +//-------------------------------------------------------------------------- + +void CDmAdCertReqData::SetSubjectNameL(const TDesC8& aSubjectName) + { + TRACE("CDmAdCertReqData::SetSubjectNameL"); + iCertReqParms->SetSubjectNameL(aSubjectName); + } + +TPtrC8 CDmAdCertReqData::SubjectName() + { + TRACE("CDmAdCertReqData::SubjectName"); + return iCertReqParms->SubjectName(); + } + +void CDmAdCertReqData::SetRfc822NameL(const TDesC8& aRfc822Name) + { + TRACE("CDmAdCertReqData::SetRfc822NameL"); + iCertReqParms->SetRfc822NameL(aRfc822Name); + } + +TPtrC8 CDmAdCertReqData::Rfc822Name() + { + TRACE("CDmAdCertReqData::Rfc822Name"); + return iCertReqParms->Rfc822Name(); + } + +void CDmAdCertReqData::SetKeyUriL(const TDesC8& aKeyUri) + { + TRACE("CDmAdCertReqData::SetKeyUriL"); + + //We save key luid (which is also key id) to the data + //structure. Not the actual key uri. + + HBufC8* keyId = iCallBack->GetLuidAllocL(aKeyUri); + CleanupStack::PushL(keyId); + + if (keyId->Length() == 0) + { + User::Leave(KErrNotFound); + } + + iCertReqParms->SetKeyIdentifierByUriL(*keyId); + CleanupStack::PopAndDestroy(keyId); + } + +HBufC8* CDmAdCertReqData::KeyUriL() const + { + TRACE("CDmAdCertReqData::KeyUri"); + + TPtrC8 keyId = iCertReqParms->KeyIdentifierByUri(); + HBufC8* keyUri = iCallBack->FindChildUriL(KDmAdOwnAdUriForPrivateKeys, keyId); + CleanupStack::PushL(keyUri); + + if (keyUri->Length() == 0) + { + User::Leave(KErrNotFound); + } + + CleanupStack::Pop(keyUri); + return keyUri; + } + +void CDmAdCertReqData::SetKeyLength(const TDesC8& aKeyLength) + { + TRACE("CDmAdCertReqData::SetKeyLength"); + iCertReqParms->SetKeyLength(TDmAdUtil::DesToInt(aKeyLength)); + } + +HBufC8* CDmAdCertReqData::KeyLengthLC() + { + return TDmAdUtil::IntToDes8LC(iCertReqParms->KeyLength()); + } + +//------------ + + +TPtrC8 CDmAdCertReqData::Content() + { + TRACE("CDmAdCertReqData::Content"); + return iCertReqParms->Content(); + } + +//-------------------------------------------------------------------------- + +void CDmAdCertReqData::RestoreL(const CDmAdCertReqParms& aCertReqParms) + { + TRACE("CDmAdCertReqData::RestoreL"); + iCertReqParms->SetSubjectNameL(aCertReqParms.SubjectName()); + iCertReqParms->SetRfc822NameL(aCertReqParms.Rfc822Name()); + iCertReqParms->SetKeyLength(aCertReqParms.KeyLength()); + iCertReqParms->SetKeyIdentifierByUriL(aCertReqParms.KeyIdentifierByUri()); + iCertReqParms->SetContentL(aCertReqParms.Content()); + } + +void CDmAdCertReqData::ToStoreL(CDmAdCertReqParms& aCertReqParms) + { + TRACE("CDmAdCertReqData::ToStoreL"); + + aCertReqParms.SetSubjectNameL(iCertReqParms->SubjectName()); + aCertReqParms.SetRfc822NameL(iCertReqParms->Rfc822Name()); + aCertReqParms.SetKeyLength(iCertReqParms->KeyLength()); + aCertReqParms.SetKeyIdentifierByUriL(iCertReqParms->KeyIdentifierByUri()); + aCertReqParms.SetContentL(iCertReqParms->Content()); + } + +//====================================================================================== +//====================================================================================== + +CDmAdPrivKeyData* CDmAdPrivKeyData::NewL() + { + TRACE("CDmAdPrivKeyData::NewL"); + CDmAdPrivKeyData *self = new (ELeave) CDmAdPrivKeyData(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +void CDmAdPrivKeyData::ConstructL() + { + TRACE("CDmAdPrivKeyData::ConstructL"); + iPrivKeyParms = CDmAdPrivKeyParms::NewL(); + } + +CDmAdPrivKeyData::CDmAdPrivKeyData() + { + } + +CDmAdPrivKeyData::~CDmAdPrivKeyData() + { + TRACE("CDmAdPrivKeyData::~CDmAdPrivKeyData"); + delete iPrivKeyParms; + } + +void CDmAdPrivKeyData::SetDefaultSettingsL() + { + TRACE("CDmAdPrivKeyData::SetDefaultSettings"); + iPrivKeyParms->SetKeyTypeL(EPKIRSA); + iPrivKeyParms->SetKeyLength(2048); + } + +//-------------------------------------------------------------------------- + +void CDmAdPrivKeyData::SetKeyTypeL(const TDesC8& aKeyType) + { + TRACE("CDmAdPrivKeyData::SetKeyType"); + TInt value = TDmAdUtil::DesToInt(aKeyType); + + TPKIKeyAlgorithm keyType = EPKIRSA; + switch(value) + { + case 1: + keyType = EPKIRSA; + break; + case 2: + keyType = EPKIDSA; + break; + default: + User::Leave(KErrCorrupt); + break; + } + + iPrivKeyParms->SetKeyTypeL(keyType); + } + +HBufC8* CDmAdPrivKeyData::KeyTypeLC() + { + TInt keyType = 1; + switch(iPrivKeyParms->KeyType()) + { + case EPKIRSA: + keyType = 1; + break; + case EPKIDSA: + keyType = 2; + break; + default: + User::Invariant(); + break; + } + return TDmAdUtil::IntToDes8LC(keyType); + } + +void CDmAdPrivKeyData::SetKeyLength(const TDesC8& aKeyLength) + { + TRACE("CDmAdPrivKeyData::SetKeyLength"); + iPrivKeyParms->SetKeyLength(TDmAdUtil::DesToInt(aKeyLength)); + } + +HBufC8* CDmAdPrivKeyData::KeyLengthLC() + { + return TDmAdUtil::IntToDes8LC(iPrivKeyParms->KeyLength()); + } + +//------------ + +TPtrC8 CDmAdPrivKeyData::KeyId() + { + TRACE("CDmAdPrivKeyData::KeyId"); + return iPrivKeyParms->KeyId(); + } + +//-------------------------------------------------------------------------- + +void CDmAdPrivKeyData::RestoreL(const CDmAdPrivKeyParms& aPrivKeyParms) + { + TRACE("CDmAdPrivKeyData::RestoreL"); + iPrivKeyParms->SetKeyTypeL(aPrivKeyParms.KeyType()); + iPrivKeyParms->SetKeyIdL(aPrivKeyParms.KeyId()); + iPrivKeyParms->SetKeyLength(aPrivKeyParms.KeyLength()); + } + +void CDmAdPrivKeyData::ToStoreL(CDmAdPrivKeyParms& aPrivKeyParms) + { + TRACE("CDmAdPrivKeyData::ToStoreL"); + aPrivKeyParms.SetKeyTypeL(iPrivKeyParms->KeyType()); + aPrivKeyParms.SetKeyIdL(iPrivKeyParms->KeyId()); + aPrivKeyParms.SetKeyLength(iPrivKeyParms->KeyLength()); + } + + + +//====================================================================================== +//====================================================================================== + +CDmAdPKCS12Data* CDmAdPKCS12Data::NewL(/*MDmAdCallBack* aCallBack*/) + { + TRACE("CDmAdPKCS12Data::NewL"); + +// CDmAdPKCS12Data* self = new (ELeave) CDmAdPKCS12Data(aCallBack); + CDmAdPKCS12Data* self = new (ELeave) CDmAdPKCS12Data(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +void CDmAdPKCS12Data::ConstructL() + { + TRACE("CDmAdPKCS12Data::ConstructL"); + + iPKCS12Parms = CDmAdPKCS12Parms::NewL(); + } + +CDmAdPKCS12Data::CDmAdPKCS12Data(/*MDmAdCallBack* aCallBack*/) +// : iCallBack(aCallBack) + { + } + +CDmAdPKCS12Data::~CDmAdPKCS12Data() + { + TRACE("CDmAdPKCS12Data::~CDmAdPKCS12Data"); + + delete iPKCS12Parms; + } + +void CDmAdPKCS12Data::SetDefaultSettings() + { + TRACE("CDmAdPKCS12Data::SetDefaultSettings"); + + TPtrC8 emptyPwd(KNullDesC8); + iPKCS12Parms->SetDeletable(ETrue); + TRAP_IGNORE(iPKCS12Parms->SetPasswordL(emptyPwd)); + } + +//-------------------------------------------------------------------------- + +void CDmAdPKCS12Data::SetDeletableL(const TDesC8& aDeletable) + { + TRACE("CDmAdPKCS12Data::SetDeletableL"); + + if (aDeletable.Compare(KDmAdDfFormatBoolTrue) == 0) + { + iPKCS12Parms->SetDeletable(ETrue); + } + else if (aDeletable.Compare(KDmAdDfFormatBoolFalse) == 0) + { + iPKCS12Parms->SetDeletable(EFalse); + } + else + { + DEBUG_LOG(_L("Comparization failed")); + User::Leave(KErrGeneral); + } + } + +HBufC8* CDmAdPKCS12Data::DeletableLC() + { + if (iPKCS12Parms->Deletable()) + { + return KDmAdDfFormatBoolTrue().AllocLC(); + } + else + { + return KDmAdDfFormatBoolFalse().AllocLC(); + } + } + +void CDmAdPKCS12Data::SetApplicabilityL(const RArray& aApplicability) + { + TRACE("CDmAdPKCS12Data::SetApplicabilityL"); + + iPKCS12Parms->SetApplicabilityL(aApplicability); + } + +const RArray& CDmAdPKCS12Data::Applicability() const + { + TRACE("CDmAdPKCS12Data::Applicability"); + + return iPKCS12Parms->Applicability(); + } + +void CDmAdPKCS12Data::SetContentL(const TDesC8& aContent) + { + TRACE("CDmAdPKCS12Data::SetContentL"); + + iPKCS12Parms->SetContentL(aContent); + } + +TPtrC8 CDmAdPKCS12Data::Content() + { + TRACE("CDmAdPKCS12Data::Content"); + + return iPKCS12Parms->Content(); + } + +void CDmAdPKCS12Data::SetPasswordL(const TDesC8& aPassword) + { + TRACE("CDmAdPKCS12Data::SetPasswordL"); + + iPKCS12Parms->SetPasswordL(aPassword); + } + +TPtrC8 CDmAdPKCS12Data::Password() + { + TRACE("CDmAdPKCS12Data::Password"); + + return iPKCS12Parms->Password(); + } + +//----------------- + + + +//-------------------------------------------------------------------------- + +void CDmAdPKCS12Data::RestoreL(const CDmAdPKCS12Parms& aPKCS12Parms) + { + TRACE("CDmAdPKCS12Data::RestoreL"); + iPKCS12Parms->SetDeletable(aPKCS12Parms.Deletable()); + iPKCS12Parms->SetApplicabilityL(aPKCS12Parms.Applicability()); + iPKCS12Parms->SetContentL(aPKCS12Parms.Content()); + iPKCS12Parms->SetPasswordL(aPKCS12Parms.Content()); + } + +void CDmAdPKCS12Data::ToStoreL(CDmAdPKCS12Parms& aPKCS12Parms) + { + TRACE("CDmAdPKCS12Data::ToStoreL"); + + aPKCS12Parms.SetDeletable(iPKCS12Parms->Deletable()); + aPKCS12Parms.SetApplicabilityL(iPKCS12Parms->Applicability()); + aPKCS12Parms.SetContentL(iPKCS12Parms->Content()); + aPKCS12Parms.SetPasswordL(iPKCS12Parms->Password()); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/src/DmAdStore.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/src/DmAdStore.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,561 @@ +/* +* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: implementation of DmAdStore +* +*/ + + + +#include "DmAdStore.h" +#include "DmAdRtNodeData.h" +#include "dmadutil.h" +#include "vpnlogger.h" + +#include "pkcs12vpn.h" + +CDmAdStore* CDmAdStore::NewL(MDmAdCallBack* aDmAdCallBack) + { + TRACE("CDmAdStore::NewL"); + + CDmAdStore *self = new (ELeave) CDmAdStore(); + CleanupStack::PushL(self); + self->ConstructL(aDmAdCallBack); + CleanupStack::Pop(self); + return self; + } + +void CDmAdStore::ConstructL(MDmAdCallBack* aDmAdCallBack) + { + TRACE("CDmAdStore::ConstructL"); + + TInt status = iPkiServiceApi.Connect(); + DEBUG_LOG1(_L("Connect status: %d"), status); + User::LeaveIfError(status); + iCert = CDmAdCert::NewL(iPkiServiceApi); + iCertReq = CDmAdCertReq::NewL(iPkiServiceApi, aDmAdCallBack); + iPrivKey = CDmAdPrivKey::NewL(iPkiServiceApi); + iPKCS12Obj = CDmAdPKCS12::NewL(iPkiServiceApi); + } + +CDmAdStore::CDmAdStore() + { + TRACE("CDmAdStore::CDmAdStore"); + } + +CDmAdStore::~CDmAdStore() + { + TRACE("CDmAdStore::~CDmAdStore"); + + iPkiServiceApi.Close(); + delete iCert; + delete iCertReq; + delete iPrivKey; + delete iPKCS12Obj; + } + +TBool CDmAdStore::FindRtNodeL(const TDesC8& aLuid, const TDesC8& aUri) + { + TRACE("CDmAdStore::FindRtNodeL"); + + TDmAdUriType uriType = CDmAdRtNodeData::UriTypeL(aUri); + switch (uriType) + { + case EDmAdUriTypeCert: + return CertFindRtNodeL(aLuid, aUri); + case EDmAdUriTypeCertReq: + return CertReqFindRtNodeL(aLuid, aUri); + case EDmAdUriTypePrivKey: + return PrivKeyFindRtNodeL(aLuid, aUri); + case EDmAdUriTypePKCS12: + // For PKCS#12, a special case + return EFalse; + default: + DEBUG_LOG(_L("Unexcepted URI type")); + User::Leave(KErrGeneral); + return EFalse; + } + } + +void CDmAdStore::LuidListL(const TDesC8& aUri, const TDesC8& aLuid, RPointerArray& aLuidList) + { + TRACE("CDmAdStore::LuidListL"); + + TDmAdUriType uriType = CDmAdRtNodeData::UriTypeL(aUri); + switch (uriType) + { + case EDmAdUriTypeCert: + CertLuidListL(aUri, aLuid, aLuidList); + break; + case EDmAdUriTypeCertReq: + CertReqLuidListL(aUri, aLuid, aLuidList); + break; + case EDmAdUriTypePrivKey: + PrivKeyLuidListL(aUri, aLuid, aLuidList); + break; + case EDmAdUriTypePKCS12: + // For PKCS#12, a special case + break; + default: + DEBUG_LOG(_L("CDmAdStore::LuidListLC: Unexcepted URI type")); + User::Leave(KErrGeneral); + break; + } + } + +void CDmAdStore::FetchRtNodeL(CDmAdRtNode& aRtNode) + { + TRACE("CDmAdStore::FetchRtNodeL"); + + TDmAdUriType uriType = aRtNode.Data()->UriType(); + switch (uriType) + { + case EDmAdUriTypeCert: + CertFetchRtNodeL(aRtNode); + break; + case EDmAdUriTypeCertReq: + CertReqFetchRtNodeL(aRtNode); + break; + case EDmAdUriTypePrivKey: + PrivKeyFetchRtNodeL(aRtNode); + break; + case EDmAdUriTypePKCS12: + // For PKCS#12, a special case + break; + default: + DEBUG_LOG(_L("Unexcepted URI type")); + User::Leave(KErrGeneral); + break; + } + } + +void CDmAdStore::SaveTopLevelRtNodeL(CDmAdRtNode& aRtNode, CArrayPtr& aChildRtNodes) + { + TRACE("CDmAdStore::SaveTopLevelRtNodeL"); + + TDmAdUriType uriType = aRtNode.Data()->UriType(); + switch (uriType) + { + case EDmAdUriTypeCert: + CertSaveTopLevelRtNodeL(aRtNode, aChildRtNodes); + break; + case EDmAdUriTypeCertReq: + CertReqSaveTopLevelRtNodeL(aRtNode, aChildRtNodes); + break; + case EDmAdUriTypePKCS12: + PKCS12SaveTopLevelRtNodeL(aRtNode, aChildRtNodes); + break; + default: + DEBUG_LOG(_L("Unexcepted URI type")); + User::Leave(KErrGeneral); + break; + } + } + +void CDmAdStore::SaveChildLevelRtNodeL(CDmAdRtNode& aRtNode) + { + TRACE("CDmAdStore::SaveChildLevelRtNodeL"); + + TDmAdUriType uriType = aRtNode.Data()->UriType(); + switch (uriType) + { + case EDmAdUriTypeCert: + CertSaveChildLevelRtNodeL(aRtNode); + break; + case EDmAdUriTypeCertReq: + CertReqSaveChildLevelRtNodeL(aRtNode); + break; + case EDmAdUriTypePKCS12: + // For PKCS#12, a special case + break; + default: + DEBUG_LOG(_L("Unexcepted URI type")); + User::Leave(KErrGeneral); + break; + } + } + +void CDmAdStore::DeleteRtNodeL(const TDesC8& aLuid, const TDesC8& aUri) + { + TRACE("CDmAdStore::DeleteRtNodeL"); + + TDmAdUriType uriType = CDmAdRtNodeData::UriTypeL(aUri); + switch (uriType) + { + case EDmAdUriTypeCert: + CertDeleteRtNodeL(aLuid, aUri); + break; + case EDmAdUriTypeCertReq: + CertReqDeleteRtNodeL(aLuid, aUri); + break; + case EDmAdUriTypePrivKey: + PrivKeyDeleteRtNodeL(aLuid, aUri); + break; + case EDmAdUriTypePKCS12: + // For PKCS#12, a special case + break; + default: + DEBUG_LOG(_L("Unexcepted URI type")); + User::Leave(KErrGeneral); + break; + } + } + +//========================================================================= +//========================================================================= + +TBool CDmAdStore::CertFindRtNodeL(const TDesC8& aLuid, const TDesC8& /*aUri*/) + { + TRACE("CDmAdStore::CertFindRtNodeL"); + + TBool ret = EFalse; + if (aLuid.Length() > 0) + { + if (iCert->FindL(aLuid)) + { + ret = ETrue; + } + } + return ret; + } + +void CDmAdStore::CertLuidListL(const TDesC8& /*aUri*/, const TDesC8& /*aLuid*/, RPointerArray& aLuidList) + { + TRACE("CDmAdStore::CertLuidListL"); + + iCert->ListL(aLuidList); + } + +void CDmAdStore::CertFetchRtNodeL(CDmAdRtNode& aRtNode) + { + TRACE("CDmAdStore::CertFetchRtNodeL"); + + TPtrC8 luid(aRtNode.Luid()); + if (luid.Length() == 0) + { + DEBUG_LOG(_L("Zero length luid")); + User::Leave(KErrNotFound); + } + + CDmAdCertData* data = aRtNode.Data()->CertData(); + CDmAdCertParms* certParms = CDmAdCertParms::NewL(); + CleanupStack::PushL(certParms); + iCert->FetchL(luid, *certParms); + data->RestoreL(*certParms); + CleanupStack::PopAndDestroy(certParms); + } + +void CDmAdStore::CertSaveTopLevelRtNodeL(CDmAdRtNode& aRtNode, CArrayPtr& aChildRtNodes) + { + TRACE("CDmAdStore::CertSaveTopLevelRtNodeL"); + + if (aChildRtNodes.Count() > 0) + { + DEBUG_LOG(_L("ChildRtNode count > 0")); + User::Leave(KErrGeneral); + } + + if (aRtNode.IsJustFetched()) + { + return; + } + + CDmAdCertData* data = aRtNode.Data()->CertData(); + + CDmAdCertParms* certParms = CDmAdCertParms::NewL(); + CleanupStack::PushL(certParms); + + data->ToStoreL(*certParms); + + if (aRtNode.IsSomeLeafAddedToRtNode()) + { + HBufC8* luid = iCert->AddL(*certParms); + CleanupStack::PushL(luid); + aRtNode.SetLuidL(*luid); + CleanupStack::PopAndDestroy(luid); + } + else + { + iCert->UpdateL(aRtNode.Luid(), *certParms); + } + + CleanupStack::PopAndDestroy(certParms); + } + +void CDmAdStore::CertSaveChildLevelRtNodeL(CDmAdRtNode& /*aRtNode*/) + { + TRACE("CDmAdStore::CertSaveChildLevelRtNodeL"); + + DEBUG_LOG(_L("Method not implemented")); + User::Leave(KErrGeneral); + } + +void CDmAdStore::CertDeleteRtNodeL(const TDesC8& aLuid, const TDesC8& /*aUri*/) + { + TRACE("CDmAdStore::CertDeleteRtNodeL"); + + if (aLuid.Length() == 0) + { + DEBUG_LOG(_L("aLuid length is 0")); + User::Leave(KErrNotFound); + } + + iCert->DeleteL(aLuid); + } + +//========================================================================= +//========================================================================= + +TBool CDmAdStore::CertReqFindRtNodeL(const TDesC8& aLuid, const TDesC8& /*aUri*/) + { + TRACE("CDmAdStore::CertReqFindRtNodeL"); + + TBool ret = EFalse; + if (aLuid.Length() > 0) + { + if (iCertReq->FindL(aLuid)) + { + ret = ETrue; + } + } + return ret; + } + +void CDmAdStore::CertReqLuidListL(const TDesC8& /*aUri*/, const TDesC8& /*aLuid*/,RPointerArray& aLuidList) + { + TRACE("CDmAdStore::CertReqLuidListL"); + + iCertReq->ListL(aLuidList); + } + +void CDmAdStore::CertReqFetchRtNodeL(CDmAdRtNode& aRtNode) + { + TRACE("CDmAdStore::CertReqFetchRtNodeL"); + + TPtrC8 luid(aRtNode.Luid()); + if (luid.Length() == 0) + { + DEBUG_LOG(_L("luid length is 0")); + User::Leave(KErrNotFound); + } + + CDmAdCertReqData* data = aRtNode.Data()->CertReqData(); + CDmAdCertReqParms* CertReqParms = CDmAdCertReqParms::NewL(); + CleanupStack::PushL(CertReqParms); + iCertReq->FetchL(luid, *CertReqParms); + data->RestoreL(*CertReqParms); + CleanupStack::PopAndDestroy(CertReqParms); + } + +void CDmAdStore::CertReqSaveTopLevelRtNodeL(CDmAdRtNode& aRtNode, CArrayPtr& aChildRtNodes) + { + TRACE("CDmAdStore::CertReqSaveTopLevelRtNodeL"); + + if (aChildRtNodes.Count() > 0) + { + DEBUG_LOG(_L("aChildRtNodes count > 0")); + User::Leave(KErrGeneral); + } + + if (aRtNode.IsJustFetched()) + { + return; + } + + CDmAdCertReqData* data = aRtNode.Data()->CertReqData(); + + CDmAdCertReqParms* CertReqParms = CDmAdCertReqParms::NewL(); + CleanupStack::PushL(CertReqParms); + + data->ToStoreL(*CertReqParms); + + if (aRtNode.IsSomeLeafAddedToRtNode()) + { + HBufC8* luid = iCertReq->AddL(*CertReqParms); + CleanupStack::PushL(luid); + aRtNode.SetLuidL(*luid); + CleanupStack::PopAndDestroy(luid); + } + else + { + DEBUG_LOG(_L("aRtNode.IsSomeLeafAddedToRtNode() returned false")); + User::Leave(KErrGeneral); + /* + //iCertReq->UpdateL(aRtNode.Luid(), *CertReqParms); + CertReqDeleteRtNodeL(aRtNode.Luid(), aRtNode.Uri()); + + HBufC8* luid = iCertReq->AddL(*CertReqParms); + CleanupStack::PushL(luid); + aRtNode.SetLuidL(*luid); + iCallBack->SetMappingL(aRtNode.Uri(), aRtNode.Luid()); + CleanupStack::PopAndDestroy(); //luid + */ + } + + CleanupStack::PopAndDestroy(CertReqParms); + } + +void CDmAdStore::CertReqSaveChildLevelRtNodeL(CDmAdRtNode& /*aRtNode*/) + { + TRACE("CDmAdStore::CertReqSaveChildLevelRtNodeL"); + + DEBUG_LOG(_L("Method not implemented")); + User::Leave(KErrGeneral); + } + +void CDmAdStore::CertReqDeleteRtNodeL(const TDesC8& aLuid, const TDesC8& /*aUri*/) + { + TRACE("CDmAdStore::CertReqDeleteRtNodeL"); + + if (aLuid.Length() == 0) + { + DEBUG_LOG(_L("aLuid length is 0")); + User::Leave(KErrNotFound); + } + + iCertReq->DeleteL(aLuid); + } + +//========================================================================= +//========================================================================= + +TBool CDmAdStore::PrivKeyFindRtNodeL(const TDesC8& aLuid, const TDesC8& /*aUri*/) + { + TRACE("CDmAdStore::PrivKeyFindRtNodeL"); + + TBool ret = EFalse; + if (aLuid.Length() > 0) + { + if (iPrivKey->FindL(aLuid)) + { + ret = ETrue; + } + } + return ret; + } + +void CDmAdStore::PrivKeyLuidListL(const TDesC8& /*aUri*/, const TDesC8& /*aLuid*/, RPointerArray& aLuidList) + { + TRACE("CDmAdStore::PrivKeyLuidListL"); + iPrivKey->ListL(aLuidList); + } + +void CDmAdStore::PrivKeyFetchRtNodeL(CDmAdRtNode& aRtNode) + { + TRACE("CDmAdStore::PrivKeyFetchRtNodeL"); + + TPtrC8 luid(aRtNode.Luid()); + if (luid.Length() == 0) + { + DEBUG_LOG(_L("aLuid length is 0")); + User::Leave(KErrNotFound); + } + + CDmAdPrivKeyData* data = aRtNode.Data()->PrivKeyData(); + CDmAdPrivKeyParms* PrivKeyParms = CDmAdPrivKeyParms::NewL(); + CleanupStack::PushL(PrivKeyParms); + iPrivKey->FetchL(luid, *PrivKeyParms); + data->RestoreL(*PrivKeyParms); + CleanupStack::PopAndDestroy(PrivKeyParms); + } + + +void CDmAdStore::PrivKeyDeleteRtNodeL(const TDesC8& aLuid, const TDesC8& /*aUri*/) + { + TRACE("CDmAdStore::PrivKeyDeleteRtNodeL"); + + if (aLuid.Length() == 0) + { + DEBUG_LOG(_L("aLuid length is 0")); + User::Leave(KErrNotFound); + } + + iPrivKey->DeleteL(aLuid); + } + +//========================================================================= +//========================================================================= + +// PKCS#12 handling +void CDmAdStore::PKCS12SaveTopLevelRtNodeL(CDmAdRtNode& aRtNode, + CArrayPtr& aChildRtNodes) + { + TRACE("CDmAdStore::PKCS12SaveTopLevelRtNodeL"); + + if (aChildRtNodes.Count() > 0) + { + DEBUG_LOG(_L("ChildRtNode count > 0")); + User::Leave(KErrGeneral); + } + + CDmAdPKCS12Data* data = aRtNode.Data()->PKCS12Data(); + + CDmAdPKCS12Parms* pkcs12Parms = CDmAdPKCS12Parms::NewL(); + CleanupStack::PushL(pkcs12Parms); + + // Extract parameters from data + data->ToStoreL(*pkcs12Parms); + + // Store PKCS#12 object contents to PKI + iPKCS12Obj->AddL(*pkcs12Parms); + + TPtrC8 uri = aRtNode.Uri(); + DEBUG_LOG1(_L8(" Setting LUID to '%S'"), &uri); + aRtNode.SetLuidL(uri); + + CleanupStack::PopAndDestroy(pkcs12Parms); + } + +//========================================================================= +//========================================================================= +void CDmAdStore::PkiLogonL() + { + TRACE("CDmAdStore::PkiLogonL"); + + TRequestStatus requestStatus; + iPkiServiceApi.Logon(requestStatus); + User::WaitForRequest(requestStatus); + TInt status = requestStatus.Int(); + if (status != KErrNone && status != KPKIErrKeyStoreEmpty) + { + DEBUG_LOG1(_L("status = %d"), status); + User::Leave(status); + } + } + +void CDmAdStore::PkiLogoffL() + { + TRACE("CDmAdStore::PkiLogoffL"); + + TRequestStatus requestStatus; + iPkiServiceApi.Logoff(requestStatus); + User::WaitForRequest(requestStatus); + TInt status = requestStatus.Int(); + if (status != KErrNone && status != KPKIErrKeyStoreEmpty) + { + DEBUG_LOG1(_L("status = %d"), status); + User::Leave(status); + } + } + +void CDmAdStore::SetStoreTypeL(TInt aStore, TPkiServiceStoreType aStoreType) + { + TRACE("CDmAdStore::SetStoreTypeL"); + + TInt status = iPkiServiceApi.SetStoreType(aStore, aStoreType); + if (status != KErrNone) + { + DEBUG_LOG1(_L("status = %d"), status); + User::Leave(status); + } + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/src/dmadadapter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/src/dmadadapter.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,334 @@ +/* +* Copyright (c) 2000-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: PKI OMA DM Adapter +* +*/ + + + +#include +#include + +#include "dmadadapter.h" +#include "dmadadapterimplconst.h" +#include "dmadengine.h" +#include "DmAdStore.h" +#include "dmadddf.h" +#include "dmadrtnodedataapic.h" +#include "vpnlogger.h" + +#if defined(_DEBUG) +_LIT(KDmAdLogFolder,"vpn"); +_LIT(KDmAdLogFile,"dmadpki.log"); +#endif + +//=================================================================================================== + + +#ifndef IMPLEMENTATION_PROXY_ENTRY +#define IMPLEMENTATION_PROXY_ENTRY(aUid, aFuncPtr) {{aUid},(aFuncPtr)} +#endif + +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY(KDmAdImplUid, CDmAdAdapter::NewL) + }; + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) + { + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); + return ImplementationTable; + } + + +//=================================================================================================== + +CDmAdAdapter* CDmAdAdapter::NewL(MSmlDmCallback* aDmCallback) + { + CDmAdAdapter* self = NewLC(aDmCallback); + CleanupStack::Pop(self); + return self; + } + +CDmAdAdapter* CDmAdAdapter::NewLC(MSmlDmCallback* aDmCallback) + { + INITIALIZE_DEBUG_LOG_L(KDmAdLogFolder, KDmAdLogFile); + DEBUG_LOG(_L("LOGGING INITIALIZED")); + + CDmAdAdapter* self = new (ELeave) CDmAdAdapter(aDmCallback); + CleanupStack::PushL(self); + self->ConstructL(aDmCallback); + return self; + } + +void CDmAdAdapter::ConstructL(MSmlDmCallback* aDmCallback) + { + TRACE("CDmAdAdapter::ConstructL"); + + DEBUG_LOG(_L("ConstructL - CallBack (PKI)")); + iCallBack = CDmAdCallBack::NewL(aDmCallback, KDmAdOwnAdUriForGetLuidAllocLFix); + + iStore = CDmAdStore::NewL(iCallBack); + iDdf = CDmAdDdf::NewL(iCallBack, iStore); + + DEBUG_LOG(_L("ConstructL - RtNodeDataApi")); + iRtNodeDataApi = CDmAdRtNodeDataApi::NewL(); + DEBUG_LOG(_L("ConstructL - Engine")); + iEngine = CDmAdEngine::NewL(iCallBack, iStore, iDdf, iRtNodeDataApi); + + } + +CDmAdAdapter::CDmAdAdapter(MSmlDmCallback* aDmCallback) : + CSmlDmAdapter(aDmCallback) + { + } + +CDmAdAdapter::~CDmAdAdapter() + { + DEBUG_LOG(_L("~CDmAdAdapter (PKI)")); + + delete iEngine; + delete iRtNodeDataApi; + delete iDdf; + delete iStore; + delete iCallBack; + + DEBUG_LOG(_L("FINALIZING LOGGING")); + FINALIZE_DEBUG_LOG; + } + +//=================================================================================================== + +void CDmAdAdapter::DDFVersionL(CBufBase& aDDFVersion) + { + TRACE("CDmAdAdapter::DDFVersionL"); + iDdf->BuildDDFVersionL(aDDFVersion); + } + +void CDmAdAdapter::DDFStructureL(MSmlDmDDFObject& aDDF) + { + TRACE("CDmAdAdapter::DDFStructureL"); + iDdf->BuildDDFStructureL(aDDF); + } + + +void CDmAdAdapter::ChildURIListL(const TDesC8& aUri, const TDesC8& aParentLuid, const CArrayFix& aPreviousUriSegmentList, TInt aResultsRef, TInt aStatusRef) + { + TRACE("CDmAdAdapter::ChildURIListL"); + iEngine->ChildURIListL(aUri, aParentLuid, aPreviousUriSegmentList, aResultsRef, aStatusRef); + } + +void CDmAdAdapter::AddNodeObjectL(const TDesC8& aUri, const TDesC8& aParentLuid, TInt aStatusRef) + { + TRACE("CDmAdAdapter::AddNodeObjectL"); + + DEBUG_LOG1(_L8("aUri = %S"), &aUri); + DEBUG_LOG1(_L8("aParentLuid = %S"), &aParentLuid); + DEBUG_LOG1(_L("aStatusRef = %d"), aStatusRef); + + // PKCS#12 check here + TInt status = CheckNodeStatus(aUri); + + if (status == KErrNone) + { + iEngine->AddNodeObjectL(aUri, aParentLuid, aStatusRef); + } + else + { + // Most probable reason for error code is that the + // PKCS#12 node already exists in the LUID mapping + DEBUG_LOG2(_L("Setting status ref %d to %d"), aStatusRef, status); + iCallBack->SetStatusL(aStatusRef, status); + } + } + +TInt CDmAdAdapter::CheckNodeStatus(const TDesC8& aUri) + { + TRACE("CDmAdAdapter::CheckNodeStatusL"); + + // Check whether the object is a PKCS#12 one + TInt ret = aUri.Find(KDmAdOwnAdUriForPKCS12); + + // If ret is >= 0, pkcs12 uri was identified + if (ret >= 0) + { + // See whether the given PKCS#12 object + // already exists + TRAP(ret, CheckPKCS12ExistenceL(aUri)); + } + else + { + // Wasn't a PKCS#12 node, no further checks needed + ret = KErrNone; + } + + DEBUG_LOG1(_L(" Returning with value %d"), ret); + + return ret; + } + +void CDmAdAdapter::CheckPKCS12ExistenceL(const TDesC8& aUri) + { + TRACE("CDmAdAdapter::CheckPKCS12Existence"); + DEBUG_LOG1(_L8(" Testing with URI: '%S'"), &aUri); + + HBufC8* foundUri(NULL); + + // Check whether the "LUID" (actually, just the full URI) + // already exists... + DEBUG_LOG(_L(" Comparing LUID/URI to see whether PKCS#12 node exists")); + foundUri = iCallBack->GetLuidAllocL(aUri); + CleanupStack::PushL(foundUri); + + if (foundUri->Length() > 0) + { + DEBUG_LOG1(_L8(" Found URI: '%S'"), foundUri); + DEBUG_LOG(_L(" PKCS#12 node already exists, no need to add, leaving")); + User::Leave(KErrAlreadyExists); + } + else + { + DEBUG_LOG(_L8(" Found URI: (empty)")); + DEBUG_LOG(_L(" PKCS#12 node is a new one, proceeding with add")); + } + + CleanupStack::PopAndDestroy(foundUri); + } + + +void CDmAdAdapter::UpdateLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, + const TDesC8& aObject, const TDesC8& aType, + TInt aStatusRef) + { + TRACE("CDmAdAdapter::UpdateLeafObjectL"); + + DEBUG_LOG1(_L8("aUri = %S"), &aUri); + DEBUG_LOG1(_L8("aLuid = %S"), &aLuid); + DEBUG_LOG(_L8("aObject:")); + DEBUG_LOG_HEX(aObject); + DEBUG_LOG1(_L8("aType = %S"), &aType); + DEBUG_LOG1(_L("aStatusRef = %d"), aStatusRef); + + TInt err = CheckNodeStatus(aUri); + + if (err == KErrNone) + { + iEngine->UpdateLeafObjectL(aUri, aLuid, aObject, aType, aStatusRef); + } + else + { + // If this PKCS#12 object already existed, do nothing + iCallBack->SetStatusL(aStatusRef, err); + } + } + +void CDmAdAdapter::FetchLeafObjectL(const TDesC8& aUri, const TDesC8& aLuid, const TDesC8& aType, TInt aResultsRef, TInt aStatusRef) + { + TRACE("CDmAdAdapter::FetchLeafObjectL"); + iEngine->FetchLeafObjectL(aUri, aLuid, aType, aResultsRef, aStatusRef); + } + +void CDmAdAdapter::DeleteObjectL(const TDesC8& aUri, const TDesC8& aLuid, TInt aStatusRef) + { + TRACE("CDmAdAdapter::DeleteObjectL"); + iEngine->DeleteObjectL(aUri, aLuid, aStatusRef); + } + +void CDmAdAdapter::CompleteOutstandingCmdsL() + { + TRACE("CDmAdAdapter::CompleteOutstandingCmdsL"); + iEngine->CompleteOutstandingCmdsL(); + } + +void CDmAdAdapter::UpdateLeafObjectL(const TDesC8& aUri, + const TDesC8& aLuid, + RWriteStream*& aStream, + const TDesC8& aType, + TInt aStatusRef) + { + TRACE("CDmAdAdapter::UpdateLeafObjectL"); + iEngine->UpdateLeafObjectL(aUri, aLuid, aStream, aType, aStatusRef); + } + +void CDmAdAdapter::FetchLeafObjectSizeL(const TDesC8& aUri, + const TDesC8& aLuid, + const TDesC8& aType, + TInt aResultsRef, + TInt aStatusRef) + { + TRACE("CDmAdAdapter::FetchLeafObjectSizeL"); + iEngine->FetchLeafObjectSizeL(aUri, aLuid, aType, aResultsRef, aStatusRef); + } + +void CDmAdAdapter::ExecuteCommandL(const TDesC8& aUri, + const TDesC8& aLuid, + const TDesC8& aArgument, + const TDesC8& aType, + TInt aStatusRef) + { + TRACE("CDmAdAdapter::ExecuteCommandL"); + iEngine->ExecuteCommandL(aUri, aLuid, aArgument, aType, aStatusRef); + } + +void CDmAdAdapter::ExecuteCommandL(const TDesC8& aUri, + const TDesC8& aLuid, + RWriteStream*& aStream, + const TDesC8& aType, + TInt aStatusRef) + { + TRACE("CDmAdAdapter::ExecuteCommandL"); + iEngine->ExecuteCommandL(aUri, aLuid, aStream, aType, aStatusRef); + } + +void CDmAdAdapter::CopyCommandL(const TDesC8& aTargetUri, + const TDesC8& aTargetLuid, + const TDesC8& aSourceUri, + const TDesC8& aSourceLuid, + const TDesC8& aType, + TInt aStatusRef) + { + TRACE("CDmAdAdapter::CopyCommandL"); + iEngine->CopyCommandL(aTargetUri, aTargetLuid, aSourceUri, aSourceLuid, aType, aStatusRef); + } + +void CDmAdAdapter::StartAtomicL() + { + TRACE("CDmAdAdapter::StartAtomicL"); + iEngine->StartAtomicL(); + } + +void CDmAdAdapter::CommitAtomicL() + { + TRACE("CDmAdAdapter::CommitAtomicL"); + iEngine->CommitAtomicL(); + } + +void CDmAdAdapter::RollbackAtomicL() + { + TRACE("CDmAdAdapter::RollbackAtomicL"); + iEngine->RollbackAtomicL(); + } + +TBool CDmAdAdapter::StreamingSupport(TInt& aItemSize) + { + TRACE("CDmAdAdapter::StreamingSupport"); + return iEngine->StreamingSupport(aItemSize); + } + +void CDmAdAdapter::StreamCommittedL() + { + TRACE("CDmAdAdapter::StreamCommittedL"); + iEngine->StreamCommittedL(); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/src/dmadcertluidmappingelem.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/src/dmadcertluidmappingelem.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,138 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CDmAdCertLuidMappingElem. +* +*/ + + +//#include + +#include "dmadcertluidmappingelem.h" +#include "utlcrypto.h" +#include "base64.h" +#include "vpnlogger.h" + +CDmAdCertLuidMappingElem* CDmAdCertLuidMappingElem::NewL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber) + { + TRACE("CDmAdCertLuidMappingElem::NewL"); + + CDmAdCertLuidMappingElem* self = NewLC(aIssuerName, aSerialNumber); + CleanupStack::Pop(self); + return self; + } + +CDmAdCertLuidMappingElem* CDmAdCertLuidMappingElem::NewLC(const TDesC8& aIssuerName, const TDesC8& aSerialNumber) + { + CDmAdCertLuidMappingElem* self = new (ELeave) CDmAdCertLuidMappingElem(); + CleanupStack::PushL(self); + self->ConstructL(aIssuerName, aSerialNumber); + return self; + } + +void CDmAdCertLuidMappingElem::ConstructL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber) + { + TRACE("CDmAdCertLuidMappingElem::ConstructL"); + + iIssuerName = aIssuerName.AllocL(); + iSerialNumber = aSerialNumber.AllocL(); + iLuid = BuildLuidL(aIssuerName, aSerialNumber); + } + +CDmAdCertLuidMappingElem::CDmAdCertLuidMappingElem() + { + } + +CDmAdCertLuidMappingElem::~CDmAdCertLuidMappingElem() + { + TRACE("CDmAdCertLuidMappingElem::~CDmAdCertLuidMappingElem"); + + delete iLuid; + delete iIssuerName; + delete iSerialNumber; + } + +void CDmAdCertLuidMappingElem::CleanupOperationDeleteCArrayPtr(TAny* aPtr) + { + TRACE("CDmAdCertLuidMappingElem::CleanupOperationDeleteCArrayPtr"); + + if (!aPtr) + { + return; + } + CArrayPtr* array = reinterpret_cast*>(aPtr); + array->ResetAndDestroy(); + delete array; + } + +TPtrC8 CDmAdCertLuidMappingElem::Luid() const + { + TRACE("CDmAdCertLuidMappingElem::Luid"); + + TPtrC8 ret(KNullDesC8); + if (iLuid != 0) + { + ret.Set(*iLuid); + } + return ret; + } + +TPtrC8 CDmAdCertLuidMappingElem::IssuerName() const + { + TRACE("CDmAdCertLuidMappingElem::IssuerName"); + + TPtrC8 ret(KNullDesC8); + if (iIssuerName != 0) + { + ret.Set(*iIssuerName); + } + return ret; + } + +TPtrC8 CDmAdCertLuidMappingElem::SerialNumber() const + { + TRACE("CDmAdCertLuidMappingElem::SerialNumber"); + + TPtrC8 ret(KNullDesC8); + if (iSerialNumber != 0) + { + ret.Set(*iSerialNumber); + } + return ret; + } + +HBufC8* CDmAdCertLuidMappingElem::BuildLuidL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber) + { + TRACE("CDmAdCertLuidMappingElem::BuildLuidL"); + + CUtlMessageDigest* digester = TUtlCrypto::MakeMessageDigesterL(TUtlCrypto::EUtlMessageDigestSha1); + CleanupStack::PushL(digester); + + HBufC8* hashBuf = HBufC8::NewLC(digester->HashSize()); + TPtr8 hashBufDesc(hashBuf->Des()); + + digester->Update(aIssuerName); + hashBufDesc.Copy(digester->Final(aSerialNumber)); + + TBase64Codec base64Codec; + HBufC8* luidB64; + if ((luidB64 = base64Codec.Base64EncodeLC(*hashBuf)) == NULL) + { + DEBUG_LOG(_L("No memory")); + User::Leave(KErrNoMemory); + } + + CleanupStack::Pop(luidB64); + CleanupStack::PopAndDestroy(2); //hashBuf, digester + return luidB64; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/src/dmadcertparms.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/src/dmadcertparms.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,140 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CDmAdCertParms. +* +*/ + + +#include + +#include "dmadcertparms.h" +#include "vpnlogger.h" + +CDmAdCertParms* CDmAdCertParms::NewL() + { + TRACE("CDmAdCertParms::NewL"); + + CDmAdCertParms* self = NewLC(); + CleanupStack::Pop(self); + return self; + } + +CDmAdCertParms* CDmAdCertParms::NewLC() + { + CDmAdCertParms* self = new (ELeave) CDmAdCertParms(); + CleanupStack::PushL(self); + return self; + } + +CDmAdCertParms::CDmAdCertParms() + { + } + +CDmAdCertParms::~CDmAdCertParms() + { + TRACE("CDmAdCertParms::~CDmAdCertParms"); + + iApplicability.Reset(); + iApplicability.Close(); + delete iContent; + } + +TPKICertificateOwnerType CDmAdCertParms::Type() const + { + TRACE("CDmAdCertParms::Type"); + return iType; + } + +void CDmAdCertParms::SetType(TPKICertificateOwnerType aType) + { + TRACE("CDmAdCertParms::SetType"); + + iType = aType; + } + + +TBool CDmAdCertParms::Deletable() const + { + return iDeletable; + } + +void CDmAdCertParms::SetDeletable(TBool aDeletable) + { + TRACE("CDmAdCertParms::SetDeletable"); + + iDeletable = aDeletable; + } + +TBool CDmAdCertParms::Trusted() const + { + return iTrusted; + } + +void CDmAdCertParms::SetTrusted(TBool aTrusted) + { + TRACE("CDmAdCertParms::SetTrusted"); + iTrusted = aTrusted; + } + +const RArray& CDmAdCertParms::Applicability() const + { + return iApplicability; + } + +void CDmAdCertParms::SetApplicabilityL(const RArray& aApplicability) + { + TRACE("CDmAdCertParms::SetApplicabilityL"); + + iApplicability.Reset(); + + for (TInt i = 0; i < aApplicability.Count(); ++i) + { + User::LeaveIfError(iApplicability.Append(aApplicability[i])); + } + } + +TPtrC8 CDmAdCertParms::Content() const + { + TPtrC8 ret(KNullDesC8); + if (iContent != 0) + { + ret.Set(*iContent); + } + return ret; + } + +void CDmAdCertParms::SetContentL(const TDesC8& aContent) + { + TRACE("CDmAdCertParms::SetContentL"); + + delete iContent; + iContent = 0; + if (aContent.Length() > 0) + { + iContent = aContent.AllocL(); + } + } + +TPtrC8 CDmAdCertParms::KeyId() const + { + return iKeyId; + } + +void CDmAdCertParms::SetKeyId(const TDesC8& aKeyLuid) + { + TRACE("CDmAdCertParms::SetKeyId"); + + __ASSERT_ALWAYS(aKeyLuid.Length() <= iKeyId.MaxLength(), User::Invariant()); + iKeyId = aKeyLuid; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/src/dmadcertreqparms.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/src/dmadcertreqparms.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,136 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CDmAdCertParms. +* +*/ + + +#include "dmadcertreqparms.h" +#include "dmadstoreprivkey.h" + +CDmAdCertReqParms* CDmAdCertReqParms::NewL() + { + CDmAdCertReqParms* self = NewLC(); + CleanupStack::Pop(self); + return self; + } + +CDmAdCertReqParms* CDmAdCertReqParms::NewLC() + { + CDmAdCertReqParms* self = new (ELeave) CDmAdCertReqParms(); + CleanupStack::PushL(self); + return self; + } + +CDmAdCertReqParms::CDmAdCertReqParms() + { + } + +CDmAdCertReqParms::~CDmAdCertReqParms() + { + delete iSubjectName; + delete iRfc822Name; + delete iContent; + delete iKeyIdentifierByUri; // key luid + } + +TPtrC8 CDmAdCertReqParms::SubjectName() const + { + TPtrC8 ret(KNullDesC8); + if (iSubjectName != 0) + { + ret.Set(*iSubjectName); + } + return ret; + } + +void CDmAdCertReqParms::SetSubjectNameL(const TDesC8& aSubjectName) + { + delete iSubjectName; + iSubjectName = 0; + if (aSubjectName.Length() > 0) + { + iSubjectName = aSubjectName.AllocL(); + } + } + +TPtrC8 CDmAdCertReqParms::Rfc822Name() const + { + TPtrC8 ret(KNullDesC8); + if (iRfc822Name != 0) + { + ret.Set(*iRfc822Name); + } + return ret; + } + +void CDmAdCertReqParms::SetRfc822NameL(const TDesC8& aRfc822Name) + { + delete iRfc822Name; + iRfc822Name = 0; + if (aRfc822Name.Length() > 0) + { + iRfc822Name = aRfc822Name.AllocL(); + } + } + +TInt CDmAdCertReqParms::KeyLength() const + { + return iKeyLength; + } + +void CDmAdCertReqParms::SetKeyLength(TInt aKeyLength) + { + iKeyLength = aKeyLength; + } + +TPtrC8 CDmAdCertReqParms::Content() const + { + TPtrC8 ret(KNullDesC8); + if (iContent != 0) + { + ret.Set(*iContent); + } + return ret; + } + +void CDmAdCertReqParms::SetContentL(const TDesC8& aContent) + { + delete iContent; + iContent = 0; + if (aContent.Length() > 0) + { + iContent = aContent.AllocL(); + } + } + +TPtrC8 CDmAdCertReqParms::KeyIdentifierByUri() const + { + TPtrC8 ret(KNullDesC8); + if (iKeyIdentifierByUri != 0) + { + ret.Set(*iKeyIdentifierByUri); + } + return ret; + } + +void CDmAdCertReqParms::SetKeyIdentifierByUriL(const TDesC8& aKeyIdentifierByUri) + { + delete iKeyIdentifierByUri; + iKeyIdentifierByUri = 0; + if (aKeyIdentifierByUri.Length() > 0) + { + iKeyIdentifierByUri = aKeyIdentifierByUri.AllocL(); + } + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/src/dmadcertutil.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/src/dmadcertutil.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,90 @@ +/* +* Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of TDmAdCertUtil. +* +*/ + + + +#include +#include +#include + +#include "dmadcertutil.h" +#include "pkcs10.h" +#include "utlcrypto.h" + + +void TDmAdCertUtil::ParseAvaL(const CX520AttributeTypeAndValue& aAva, TDes8& aOut) + { + TPtrC8 attr = CPkcs10Req::AttributeTypeOidToText(aAva.Type()); + TBuf8<32> tempOidBuf; + HBufC* val = NULL; + TRAPD(ret, val = aAva.ValueL()); + if(ret == KErrNone) + { + CleanupStack::PushL(val); + if(attr.Length() == 0) + { + // Dotted oid representation + tempOidBuf.Copy(aAva.Type()); + aOut.Append(tempOidBuf); + } + else + { + aOut.Append(attr); + } + aOut.Append(_L("=")); + aOut.Append(val->Des()); + CleanupStack::PopAndDestroy(val); + } + } + +void TDmAdCertUtil::CertDnL(const CX500DistinguishedName& aName, TDes8& aOut) + { + TInt count = aName.Count(); + for (TInt i = 0; i < count; i++) + { + if(i > 0) + aOut.Append(_L(",")); + const CX520AttributeTypeAndValue& ava = aName.Element(i); + ParseAvaL(ava, aOut); + } + } + +HBufC8* TDmAdCertUtil::Sha1DigestL(const TDesC8& aData) + { + CUtlMessageDigest* digester = TUtlCrypto::MakeMessageDigesterL(TUtlCrypto::EUtlMessageDigestSha1); + CleanupStack::PushL(digester); + + HBufC8* hashBuf = HBufC8::NewLC(digester->HashSize()); + TPtr8 hashBufDesc(hashBuf->Des()); + + hashBufDesc.Copy(digester->Final(aData)); + CleanupStack::Pop(hashBuf); + CleanupStack::PopAndDestroy(digester); + return hashBuf; + } + +HBufC8* TDmAdCertUtil::RSAKeyIdentifierLC(const TDesC8& aKeyData) + { + TX509KeyFactory keyFactory; + CRSAPublicKey* rsaKey = keyFactory.RSAPublicKeyL(aKeyData); + CleanupStack::PushL(rsaKey); + HBufC8* modulusBuffer = rsaKey->N().BufferLC(); + HBufC8* hash = TDmAdCertUtil::Sha1DigestL(*modulusBuffer); + CleanupStack::PopAndDestroy(2); // modulusBuffer, rsaKey + CleanupStack::PushL(hash); + return hash; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/src/dmadddf.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/src/dmadddf.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,882 @@ +/* +* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: ddf tree implementation of DmAdPKI +* +*/ + + + +#include +#include + +#include "dmadddf.h" +#include "dmadutil.h" +#include "vpnlogger.h" +#include "dmadcertxmldefs.h" +#include "XwImpl.h" + +static const TInt KUserStore = 1; +static const TInt KDeviceStore = 2; + +CDmAdDdf* CDmAdDdf::NewL(MDmAdCallBack* aDmAdCallBack, CDmAdStore* aStore) + { + TRACE("CDmAdDdf::NewL"); + + CDmAdDdf* self = NewLC(aDmAdCallBack, aStore); + CleanupStack::Pop(self); + return self; + } + +CDmAdDdf* CDmAdDdf::NewLC(MDmAdCallBack* aDmAdCallBack, CDmAdStore* aStore) + { + CDmAdDdf* self = new (ELeave) CDmAdDdf(aDmAdCallBack, aStore); + CleanupStack::PushL(self); + return self; + } + +CDmAdDdf::CDmAdDdf(MDmAdCallBack* aDmAdCallBack, CDmAdStore* aStore) : + iCallBack(aDmAdCallBack), iStore(aStore) + { + TRACE("CDmAdDdf::CDmAdDdf"); + } + +CDmAdDdf::~CDmAdDdf() + { + TRACE("CDmAdDdf::~CDmAdDdf"); + } + +//=================================================================================================== + +void CDmAdDdf::BuildDDFVersionL(CBufBase& aDDFVersion) + { + TRACE("CDmAdDdf::BuildDDFVersionL"); + aDDFVersion.InsertL(0, KDmAdDdfVersion); + } + +void CDmAdDdf::BuildDDFStructureL(MSmlDmDDFObject& aDDF) + { + TRACE("CDmAdDdf::BuildDDFStructureL"); + + TSmlDmAccessTypes accessTypesExec; + accessTypesExec.SetReplace(); // accessTypesExec.SetExec(); + + TSmlDmAccessTypes accessTypesGet; + accessTypesGet.SetGet(); + + TSmlDmAccessTypes accessTypesAdd; + accessTypesAdd.SetAdd(); + + TSmlDmAccessTypes accessTypesGetAdd; + accessTypesGetAdd.SetGet(); + accessTypesGetAdd.SetAdd(); + + TSmlDmAccessTypes accessTypesAll; + accessTypesAll.SetGet(); + accessTypesAll.SetAdd(); + accessTypesAll.SetDelete(); + accessTypesAll.SetReplace(); + + TSmlDmAccessTypes accessTypesNoDelete; + accessTypesNoDelete.SetGet(); + accessTypesNoDelete.SetAdd(); + accessTypesNoDelete.SetReplace(); + + MSmlDmDDFObject* obj; + MSmlDmDDFObject* objNokiaPki; + MSmlDmDDFObject* objPkiGeneral; + MSmlDmDDFObject* objCert; + MSmlDmDDFObject* objCertX; + MSmlDmDDFObject* objCertReq; + MSmlDmDDFObject* objCertReqX; + MSmlDmDDFObject* objPrivKey; + MSmlDmDDFObject* objPrivKeyX; + MSmlDmDDFObject* objPKCS12; + MSmlDmDDFObject* objPKCS12X; + + +//---------------------------------------------------------------- + + objNokiaPki = &TDmAdUtil::AddChildObjectL(aDDF, KDmAdNodeNokiaPki); + TDmAdUtil::FillNodeInfoL(*objNokiaPki, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EPermanent, + MSmlDmDDFObject::ENode, + KDmAdDescNodeNokiaPki, + ETrue, + KDmAdNokiaPkiRootTypeProperty); + +//---------------------------------------------------------------- + + + obj = &TDmAdUtil::AddChildObjectL(*objNokiaPki, KDmAdLeafLogon); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesExec, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::ENull, + KDmAdDescLeafLogon, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objNokiaPki, KDmAdLeafLogoff); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesExec, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::ENull, + KDmAdDescLeafLogoff, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objNokiaPki, KDmAdLeafKeyStore); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesExec, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EInt, + KDmAdDescLeafKeyStore, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objNokiaPki, KDmAdLeafCertStore); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesExec, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EInt, + KDmAdDescLeafCertStore, + EFalse); + + objPkiGeneral = &TDmAdUtil::AddChildObjectL(*objNokiaPki, KDmAdNodeGeneral); + TDmAdUtil::FillNodeInfoL(*objPkiGeneral, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EPermanent, + MSmlDmDDFObject::ENode, + KDmAdDescNodeGeneral, + EFalse, + KNullDesC8); + + obj = &TDmAdUtil::AddChildObjectL(*objPkiGeneral, KDmAdLeafCertApplications); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EXml, + KDmAdDescLeafCertApplications, + EFalse); + +//---------------------------------------------------------------- + + objCert = &TDmAdUtil::AddChildObjectL(*objNokiaPki, KDmAdNodeCert); + TDmAdUtil::FillNodeInfoL(*objCert, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EPermanent, + MSmlDmDDFObject::ENode, + KDmAdDescNodeCert, + EFalse, + KNullDesC8); + + objCertX = &TDmAdUtil::AddChildObjectL(*objCert, KDmAdNodeRt); + TDmAdUtil::FillNodeInfoL(*objCertX, + accessTypesAll, + MSmlDmDDFObject::EZeroOrMore, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::ENode, + KDmAdDescNodeRt, + EFalse, + KNullDesC8); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafType); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGetAdd, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EInt, + KDmAdDescLeafType, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafFormat); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGetAdd, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EInt, + KDmAdDescLeafFormat, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafSerialNumber); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBin, + KDmAdDescLeafSerialNumber, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafIssuerName); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBin, + KDmAdDescLeafIssuerName, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafFingerprintAlg); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EInt, + KDmAdDescLeafFingerprintAlg, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafFingerprintValue); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBin, + KDmAdDescLeafFingerprintAlg, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafValidityBegin); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafValidityBegin, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafValidityEnd); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafValidityEnd, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafSubjectName); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBin, + KDmAdDescLeafSubjectName, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafSubjectAltName); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBin, + KDmAdDescLeafSubjectAltName, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafKeyURI); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafKeyUri, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafKeyId); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBin, + KDmAdDescLeafKeyId, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafKeyUsage); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafKeyUsage, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafDeletable); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGetAdd, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBool, + KDmAdDescLeafDeletable, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafTrusted); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesNoDelete, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBool, + KDmAdDescLeafTrusted, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafApplicability); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesNoDelete, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EXml, + KDmAdDescLeafApplicability, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertX, KDmAdLeafContent); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGetAdd, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBin, + KDmAdDescLeafContent, + EFalse); + + +//---------------------------------------------------------------- + + objCertReq = &TDmAdUtil::AddChildObjectL(*objNokiaPki, KDmAdNodeCertReq); + TDmAdUtil::FillNodeInfoL(*objCertReq, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EPermanent, + MSmlDmDDFObject::ENode, + KDmAdDescNodeCertReq, + EFalse, + KNullDesC8); + + + objCertReqX = &TDmAdUtil::AddChildObjectL(*objCertReq, KDmAdNodeRt); + TDmAdUtil::FillNodeInfoL(*objCertReqX, + accessTypesAll, + MSmlDmDDFObject::EZeroOrMore, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::ENode, + KDmAdDescNodeRt, + EFalse, + KNullDesC8); + + obj = &TDmAdUtil::AddChildObjectL(*objCertReqX, KDmAdLeafSubjectName); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesAdd, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBin, + KDmAdDescLeafSubjectName, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertReqX, KDmAdLeafRfc822Name); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesAdd, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBin, + KDmAdDescLeafRfc822Name, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertReqX, KDmAdLeafKeyURI); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesAdd, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafKeyUri, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertReqX, KDmAdLeafKeyLength); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesAdd, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EInt, + KDmAdDescLeafKeyLength, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objCertReqX, KDmAdLeafContent); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBin, + KDmAdDescLeafContent, + EFalse); + +//---------------------------------------------------------------- + + objPrivKey = &TDmAdUtil::AddChildObjectL(*objNokiaPki, KDmAdNodePrivKey); + TDmAdUtil::FillNodeInfoL(*objPrivKey, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EPermanent, + MSmlDmDDFObject::ENode, + KDmAdDescNodePrivKey, + EFalse, + KNullDesC8); + + + objPrivKeyX = &TDmAdUtil::AddChildObjectL(*objPrivKey, KDmAdNodeRt); + TDmAdUtil::FillNodeInfoL(*objPrivKeyX, + accessTypesAll, + MSmlDmDDFObject::EZeroOrMore, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::ENode, + KDmAdDescNodeRt, + EFalse, + KNullDesC8); + + obj = &TDmAdUtil::AddChildObjectL(*objPrivKeyX, KDmAdLeafKeyType); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGetAdd, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EInt, + KDmAdDescLeafKeyType, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objPrivKeyX, KDmAdLeafKeyId); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafKeyId, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objPrivKeyX, KDmAdLeafKeyLength); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesGetAdd, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EInt, + KDmAdDescLeafKeyLength, + EFalse); + + obj = &TDmAdUtil::AddChildObjectL(*objPrivKeyX, KDmAdLeafContent); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesAdd, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBin, + KDmAdDescLeafContent, + EFalse); + + //------- PKCS#12 Node definitions ----------------- + + DEBUG_LOG(_L("Adding PKCS#12 definitions")); + + // PKCS12 root node + objPKCS12 = &TDmAdUtil::AddChildObjectL(*objNokiaPki, KDmAdNodePKCS12); + TDmAdUtil::FillNodeInfoL(*objPKCS12, + accessTypesGet, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EPermanent, + MSmlDmDDFObject::ENode, + KDmAdDescNodePKCS12, + EFalse, + KNullDesC8); + + // PKCS#12/X node + objPKCS12X = &TDmAdUtil::AddChildObjectL(*objPKCS12, KDmAdNodeRt); + TDmAdUtil::FillNodeInfoL(*objPKCS12X, + accessTypesAdd, + MSmlDmDDFObject::EZeroOrMore, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::ENode, + KDmAdDescNodeRt, + EFalse, + KNullDesC8); + + // PKCS#12/X/Password leaf node + obj = &TDmAdUtil::AddChildObjectL(*objPKCS12X, KDmAdLeafPKCS12Password); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesAdd, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EChr, + KDmAdDescLeafPKCS12Password, + EFalse); + + // PKCS#12/X/Deletable leaf node + obj = &TDmAdUtil::AddChildObjectL(*objPKCS12X, KDmAdLeafDeletable); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesAdd, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBool, + KDmAdDescLeafDeletable, + EFalse); + + // PKCS#12/X/Applicability leaf node + obj = &TDmAdUtil::AddChildObjectL(*objPKCS12X, KDmAdLeafApplicability); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesAdd, + MSmlDmDDFObject::EZeroOrOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EXml, + KDmAdDescLeafApplicability, + EFalse); + + // PKCS#12/X/Content leaf node + obj = &TDmAdUtil::AddChildObjectL(*objPKCS12X, KDmAdLeafContent); + TDmAdUtil::FillNodeInfoL(*obj, + accessTypesAdd, + MSmlDmDDFObject::EOne, + MSmlDmDDFObject::EDynamic, + MSmlDmDDFObject::EBin, + KDmAdDescLeafContent, + EFalse); + + DEBUG_LOG(_L("Adding PKCS#12 definitions - COMPLETE")); + + } + +//--------------------------------------------------------------------------------------- + +void CDmAdDdf::NotRtNodeAddNodeObjectL(const TDesC8& /*aUri*/, const TDesC8& /*aParentLuid*/, TInt aStatusRef) + { + TRACE("CDmAdDdf::NotRtNodeAddNodeObjectL"); + + iCallBack->SetStatusL(aStatusRef, KErrNone); + } + +void CDmAdDdf::NotRtNodeUpdateLeafObjectL(const TDesC8& aUri, const TDesC8& /*aLuid*/, const TDesC8& aObject, const TDesC8& /*aType*/, TInt aStatusRef) + { + TRACE("CDmAdDdf::NotRtNodeUpdateLeafObjectL"); + + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdLeafLogon) == 0) + { + iStore->PkiLogonL(); + } + else if (lastSeg.Compare(KDmAdLeafLogoff) == 0) + { + iStore->PkiLogoffL(); + } + else if (lastSeg.Compare(KDmAdLeafKeyStore) == 0) + { + TInt storeFromDm = TDmAdUtil::DesToInt(aObject); + TPkiServiceStoreType pkiStoreType = EPkiStoreTypeAny; + switch(storeFromDm) + { + case KUserStore: + pkiStoreType = EPkiStoreTypeUser; + break; + case KDeviceStore: + pkiStoreType = EPkiStoreTypeDevice; + break; + default: + User::Leave(KPKIErrNotSupported); + break; + } + iStore->SetStoreTypeL(STORE_KEYSTORE, pkiStoreType); + } + else if (lastSeg.Compare(KDmAdLeafCertStore) == 0) + { + TInt storeFromDm = TDmAdUtil::DesToInt(aObject); + TPkiServiceStoreType pkiStoreType = EPkiStoreTypeAny; + switch(storeFromDm) + { + case KUserStore: + pkiStoreType = EPkiStoreTypeUser; + break; + case KDeviceStore: + pkiStoreType = EPkiStoreTypeDevice; + break; + default: + User::Leave(KPKIErrNotSupported); + break; + } + + iStore->SetStoreTypeL(STORE_CERTSTORE, pkiStoreType); + } + + iCallBack->SetStatusL(aStatusRef, KErrNone); + } + +TInt CDmAdDdf::NotRtNodeFetchLeafObjectLC(const TDesC8& aUri, const TDesC8& /*aLuid*/, const TDesC8& /*aType*/, CBufBase*& aObject) + { + TInt status = KErrNotFound; + CBufBase* object = CBufFlat::NewL(32); + CleanupStack::PushL(object); + + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdLeafCertApplications) == 0) + { + + CCertificateAppInfoManager* appsMan = CCertificateAppInfoManager::NewLC(); + + const RArray& apps = appsMan->Applications(); + TInt count = apps.Count(); + CXmlWriter* writer = CXmlWriter::NewL(); + CleanupStack::PushL(static_cast(writer)); + + writer->AddStartTagL(KXmlElemCertApps); + for (TInt i=0; iOpenStartTagL(KXmlElemApp); + writer->AddAttributeL(KXmlAttrId, *idInt); + writer->AddAttributeL(KXmlAttrName, *name8); + writer->CloseStartTagL(ETrue); + CleanupStack::PopAndDestroy(2); //name8, idInt + } + writer->AddEndTagL(KXmlElemCertApps); + TPtrC8 docDataPtr(writer->DocPart(0, writer->Length()-1)); + object->InsertL(object->Size(), docDataPtr); + + DEBUG_LOG(_L("popping writer")); + CleanupStack::PopAndDestroy(static_cast(writer)); + DEBUG_LOG(_L("writer popped")); + + CleanupStack::PopAndDestroy(appsMan); + status = KErrNone; + } + aObject = object; + return status; + } + +void CDmAdDdf::NotRtNodeDeleteObjectL(const TDesC8& /*aUri*/, const TDesC8& /*aLuid*/, TInt aStatusRef) + { + TRACE("CDmAdDdf::NotRtNodeDeleteObjectL"); + + iCallBack->SetStatusL(aStatusRef, KErrNone); + } + +//--------------------------------------------------------------------------------------- + +TBool CDmAdDdf::IsNodeRtNodeL(const TDesC8& aUri) + { + TRACE("CDmAdDdf::IsNodeRtNodeL"); + + TBool ret = EFalse; + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdNodeNokiaPki) == 0 || + lastSeg.Compare(KDmAdNodeGeneral) == 0 || + lastSeg.Compare(KDmAdNodeCert) == 0 || + lastSeg.Compare(KDmAdNodeCertReq) == 0 || + lastSeg.Compare(KDmAdNodePrivKey) == 0 || + lastSeg.Compare(KDmAdNodePKCS12) == 0) // Added + { + if(lastSeg.Compare(KDmAdNodePKCS12) == 0) // Added + { + DEBUG_LOG(_L("LastSeg == KDmAdNodePKCS12, ret = FALSE")); + } + ret = EFalse; + } + else + { + if (TDmAdUtil::NumOfURISegs(aUri) < 2) + { + DEBUG_LOG(_L("Number of URI segments is < 2")); + User::Leave(KErrNotFound); + } + TPtrC8 prevSeg = TDmAdUtil::LastUriSeg(TDmAdUtil::RemoveLastUriSeg(aUri)); + if (prevSeg.Compare(KDmAdNodeCert) == 0 || + prevSeg.Compare(KDmAdNodeCertReq) == 0 || + prevSeg.Compare(KDmAdNodePrivKey) == 0 || + prevSeg.Compare(KDmAdNodePKCS12) == 0) // Added + { + if(prevSeg.Compare(KDmAdNodePKCS12) == 0) // Added + { + DEBUG_LOG(_L("prevSeg == KDmAdNodePKCS12, ret = TRUE")); + } + ret = ETrue; + } + else + { + DEBUG_LOG(_L("URI segment not found")); + User::Leave(KErrNotFound); + } + } + return ret; + } + +TBool CDmAdDdf::IsLeafUnderRtNodeL(const TDesC8& aUri) + { + TRACE("CDmAdDdf::IsLeafUnderRtNodeL"); + + TBool ret = EFalse; + TPtrC8 nodeUri(TDmAdUtil::RemoveLastUriSeg(aUri)); + ret = IsNodeRtNodeL(nodeUri); + return ret; + } + + +TPtrC8 CDmAdDdf::RtNodeUriForLeafL(const TDesC8& aLeafUri) + { + TRACE("CDmAdDdf::RtNodeUriForLeafL"); + + TPtrC8 ret; + TPtrC8 nodeUri(TDmAdUtil::RemoveLastUriSeg(aLeafUri)); + TPtrC8 prevNodeUri(TDmAdUtil::RemoveLastUriSeg(nodeUri)); + TPtrC8 prevNodeUriSeg(TDmAdUtil::LastUriSeg(prevNodeUri)); + + if (prevNodeUriSeg.Compare(KDmAdNodeCert) == 0 || + prevNodeUriSeg.Compare(KDmAdNodeCertReq) == 0 || + prevNodeUriSeg.Compare(KDmAdNodePrivKey) == 0 || + prevNodeUriSeg.Compare(KDmAdNodePKCS12) == 0) // Added + { + if (prevNodeUriSeg.Compare(KDmAdNodePKCS12) == 0) + { + DEBUG_LOG(_L("prevNodeUriSeg == KDmAdNodePKCS12")); + } + ret.Set(nodeUri); + } + else + { + DEBUG_LOG(_L("Unknown URI")); + User::Leave(KErrNotFound); + } + return ret; + } + +TBool CDmAdDdf::IsTopLevelRtNode(const TDesC8& /*aUri*/) + { + TRACE("CDmAdDdf::IsTopLevelRtNode"); + return ETrue; + } + +HBufC8* CDmAdDdf::ParentRtNodeUriForRtNodeLC(const TDesC8& /*aUri*/) + { + DEBUG_LOG(_L("Method CDmAdDdf::ParentRtNodeUriForRtNodeLC not implemented")); + User::Leave(KErrGeneral); + return 0; + } + +//--------------------------------------------------------------------------------------- + +void CDmAdDdf::BuildChildUriListLC(const TDesC8& aUri, const TDesC8& aParentLuid, const CArrayFix& aPreviousUriSegmentList, CBufBase*& aCurrentList) + { + CBufBase *currentList = CBufFlat::NewL(128); + CleanupStack::PushL(currentList); + + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + if (lastSeg.Compare(KDmAdNodeNokiaPki) == 0) + { + currentList->InsertL(0, KDmAdListOfNokiaPkiChildren); + } + else if (lastSeg.Compare(KDmAdNodeGeneral) == 0) + { + currentList->InsertL(0, KDmAdListOfPkiGeneralChildren); + } + else if (lastSeg.Compare(KDmAdNodeCert) == 0 || + lastSeg.Compare(KDmAdNodeCertReq) == 0 || + lastSeg.Compare(KDmAdNodePrivKey) == 0 || + lastSeg.Compare(KDmAdNodePKCS12) == 0) // Added + { + if (lastSeg.Compare(KDmAdNodePKCS12) == 0) + { + // Special treatment for PKCS12 nodes + DEBUG_LOG(_L("lastSeg == KDmAdNodePKCS12")); + TPtrC8 lastSeg = TDmAdUtil::LastUriSeg(aUri); + TInt slashcount = 0; + TInt urisegcount = aPreviousUriSegmentList.Count(); + + DEBUG_LOG1(_L(" URI segment count: %d:"), urisegcount); + + for (TInt i=0; i < urisegcount; i++) + { + const TSmlDmMappingInfo& mappingInfo = aPreviousUriSegmentList.At(i); + + DEBUG_LOG1(_L(" SetResult URI seg entry %d:"), i); + DEBUG_LOG1(_L8(" Uri seg: '%S'"), &(mappingInfo.iURISeg)); + DEBUG_LOG_HEX(mappingInfo.iURISegLUID); + + // Add slash to separate between URIs (no slash after the last one or + // before the first one) + if ((slashcount > 0) && (slashcount <= urisegcount)) + { + currentList->InsertL(currentList->Size(), KDmAdSeparator); + } + + currentList->InsertL(currentList->Size(), mappingInfo.iURISeg); + slashcount++; + } + } + else + { + TDmAdUtil::BuildRtNodeChildUriListL(iCallBack, iStore, aUri, aParentLuid, aPreviousUriSegmentList, *currentList); + } + +#if 0 + if (currentList->Size() > 0) + { + currentList->InsertL(currentList->Size(), KDmAdAppendChildSlashExt); + } + else + { + currentList->InsertL(currentList->Size(), KDmAdAppendChildExt); + } +#endif + } + else + { + TPtrC8 prevSeg = TDmAdUtil::LastUriSeg(TDmAdUtil::RemoveLastUriSeg(aUri)); + if (prevSeg.Compare(KDmAdNodeCert) == 0 || + prevSeg.Compare(KDmAdNodeCertReq) == 0 || + prevSeg.Compare(KDmAdNodePrivKey) == 0 || + prevSeg.Compare(KDmAdNodePKCS12) == 0) // Added + { + if (prevSeg.Compare(KDmAdNodePKCS12) == 0) + { + DEBUG_LOG(_L("prevSeg == KDmAdNodePKCS12")); + } + if (!iStore->FindRtNodeL(aParentLuid, aUri)) + { + DEBUG_LOG(_L("Node not found")); + User::Leave(KErrNotFound); + } + + if (prevSeg.Compare(KDmAdNodeCert) == 0) + { + currentList->InsertL(0, KDmAdListOfCertXChildren); + } + else if (prevSeg.Compare(KDmAdNodeCertReq) == 0) + { + currentList->InsertL(0, KDmAdListOfCertReqXChildren); + } + else if (prevSeg.Compare(KDmAdNodePrivKey) == 0) + { + currentList->InsertL(0, KDmAdListOfPrivKeyXChildren); + } + else if (prevSeg.Compare(KDmAdNodePKCS12) == 0) + { + DEBUG_LOG(_L("inserting KDmAdListOfPKCS12XChildren to currentList")); + + // Added handler for pkcs#12 + currentList->InsertL(0, KDmAdListOfPKCS12XChildren); + } + } + else + { + DEBUG_LOG(_L("Unknown URI")); + User::Leave(KErrNotFound); + } + } + + aCurrentList = currentList; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/src/dmadpkcs12parms.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/src/dmadpkcs12parms.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,135 @@ +/* +* Copyright (c) 2000-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CDmAdPKCS12Parms +* +*/ + + + + + +#include + +#include "dmadpkcs12parms.h" +#include "vpnlogger.h" + +CDmAdPKCS12Parms* CDmAdPKCS12Parms::NewL() + { + TRACE("CDmAdCertParms::NewL"); + + CDmAdPKCS12Parms* self = NewLC(); + CleanupStack::Pop(self); + return self; + } + +CDmAdPKCS12Parms* CDmAdPKCS12Parms::NewLC() + { + CDmAdPKCS12Parms* self = new (ELeave) CDmAdPKCS12Parms(); + CleanupStack::PushL(self); + return self; + } + +CDmAdPKCS12Parms::CDmAdPKCS12Parms() + { + } + +CDmAdPKCS12Parms::~CDmAdPKCS12Parms() + { + TRACE("CDmAdCertParms::~CDmAdCertParms"); + + iApplicability.Reset(); + iApplicability.Close(); + delete iContent; + delete iPassword; + } + +TBool CDmAdPKCS12Parms::Deletable() const + { + return iDeletable; + } + +void CDmAdPKCS12Parms::SetDeletable(TBool aDeletable) + { + TRACE("CDmAdCertParms::SetDeletable"); + + iDeletable = aDeletable; + } + +const RArray& CDmAdPKCS12Parms::Applicability() const + { + return iApplicability; + } + +void CDmAdPKCS12Parms::SetApplicabilityL(const RArray& aApplicability) + { + TRACE("CDmAdPKCS12Parms::SetApplicabilityL"); + + iApplicability.Reset(); + + for (TInt i = 0; i < aApplicability.Count(); ++i) + { + User::LeaveIfError(iApplicability.Append(aApplicability[i])); + } + } + +TPtrC8 CDmAdPKCS12Parms::Content() const + { + TPtrC8 ret(KNullDesC8); + if (iContent != 0) + { + ret.Set(*iContent); + } + return ret; + } + +void CDmAdPKCS12Parms::SetContentL(const TDesC8& aContent) + { + TRACE("CDmAdPKCS12Parms::SetContentL"); + + delete iContent; + iContent = 0; + if (aContent.Length() > 0) + { + iContent = aContent.AllocL(); + } + } + +TPtrC8 CDmAdPKCS12Parms::Password() const + { + TPtrC8 ret(KNullDesC8); + if (iPassword) + { + ret.Set(*iPassword); + } + return ret; + } + +void CDmAdPKCS12Parms::SetPasswordL(const TDesC8& aPassword) + { + TRACE("CDmAdPKCS12Parms::SetPasswordL"); + + delete iPassword; + iPassword = NULL; + if (aPassword.Length() > 0) + { + iPassword = aPassword.AllocL(); + } + else + { + iPassword = HBufC8::NewL(0); + } + } + + + diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/src/dmadprivkeyparms.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/src/dmadprivkeyparms.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,93 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CDmAdPrivKeyParms. +* +*/ + + +#include + +#include "dmadprivkeyparms.h" + +CDmAdPrivKeyParms* CDmAdPrivKeyParms::NewL() + { + CDmAdPrivKeyParms* self = NewLC(); + CleanupStack::Pop(self); + return self; + } + +CDmAdPrivKeyParms* CDmAdPrivKeyParms::NewLC() + { + CDmAdPrivKeyParms* self = new (ELeave) CDmAdPrivKeyParms(); + CleanupStack::PushL(self); + return self; + } + +CDmAdPrivKeyParms::CDmAdPrivKeyParms() + { + iKeyType = EPKIRSA; + } + +CDmAdPrivKeyParms::~CDmAdPrivKeyParms() + { + delete iKeyId; + } + +TPKIKeyAlgorithm CDmAdPrivKeyParms::KeyType() const + { + return iKeyType; + } + +void CDmAdPrivKeyParms::SetKeyTypeL(TPKIKeyAlgorithm aKeyType) + { + + if (aKeyType != EPKIRSA && + aKeyType != EPKIDSA) + { + User::Leave(KErrCorrupt); + } + + iKeyType = aKeyType; + } + +TPtrC8 CDmAdPrivKeyParms::KeyId() const + { + TPtrC8 ret(KNullDesC8); + if (iKeyId != 0) + { + ret.Set(*iKeyId); + } + return ret; + } + +void CDmAdPrivKeyParms::SetKeyIdL(const TDesC8& aKeyId) + { + delete iKeyId; + iKeyId = 0; + if (aKeyId.Length() > 0) + { + iKeyId = aKeyId.AllocL(); + } + } + +TInt CDmAdPrivKeyParms::KeyLength() const + { + return iKeyLength; + } + +void CDmAdPrivKeyParms::SetKeyLength(TInt aKeyLength) + { + iKeyLength = aKeyLength; + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/src/dmadrtnodedataapi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/src/dmadrtnodedataapi.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,92 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CDmAdRtNodeDataApi. +* +*/ + + +#include "dmadrtnodedataapic.h" +#include "DmAdRtNodeData.h" +#include "dmadcallback.h" + +CDmAdRtNodeDataApi* CDmAdRtNodeDataApi::NewL() + { + CDmAdRtNodeDataApi* self = NewLC(); + CleanupStack::Pop(self); + return self; + } + +CDmAdRtNodeDataApi* CDmAdRtNodeDataApi::NewLC() + { + CDmAdRtNodeDataApi* self = new (ELeave) CDmAdRtNodeDataApi(); + CleanupStack::PushL(self); + return self; + } + +CDmAdRtNodeDataApi::CDmAdRtNodeDataApi() + { + } + +CDmAdRtNodeDataApi::~CDmAdRtNodeDataApi() + { + } + +//--------------------------------------------------------------------------------------- + +CDmAdRtNodeData* CDmAdRtNodeDataApi::CreateDmAdRtNodeDataL(const TDesC8& aUri, MDmAdCallBack* aCallBack) + { + return CDmAdRtNodeData::NewL(aUri, aCallBack); + } + +void CDmAdRtNodeDataApi::DeleteDmAdRtNodeData(CDmAdRtNodeData* aDmAdRtNodeData) + { + delete aDmAdRtNodeData; + } + +void CDmAdRtNodeDataApi::UpdateLeafDataL(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri, const TDesC8& aObject) + { + ASSERT(aDmAdRtNodeData); + aDmAdRtNodeData->UpdateLeafDataL(aUri, aObject); + } + +void CDmAdRtNodeDataApi::FetchLeafObjectLC(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri, const TDesC8& aLuid, CBufBase*& aObject) + { + ASSERT(aDmAdRtNodeData); + aDmAdRtNodeData->FetchLeafObjectLC(aUri, aLuid, aObject); + } + +void CDmAdRtNodeDataApi::SetDefaultSettingsL(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri) + { + ASSERT(aDmAdRtNodeData); + aDmAdRtNodeData->SetDefaultSettingsL(aUri); + } + +TBool CDmAdRtNodeDataApi::AreUriTypesSame(CDmAdRtNodeData* aDmAdRtNodeData, const TDesC8& aUri) + { + ASSERT(aDmAdRtNodeData); + + TDmAdUriType uriType1 = EDmAdUriTypeCert; + //CDmAdRtNodeData::UriTypeL leaves if the URI type is unknown + TRAPD(err, uriType1 = CDmAdRtNodeData::UriTypeL(aUri)); + TDmAdUriType uriType2 = aDmAdRtNodeData->UriType(); + + if (err == KErrNone && uriType1 == uriType2) + { + return ETrue; + } + else + { + return EFalse; + } + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/src/dmadstorecert.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/src/dmadstorecert.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,425 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CDmAdCert. +* +*/ + + +#include "dmadutil.h" +#include "dmadstorecert.h" +#include "vpnlogger.h" +#include "dmadcertxmldefs.h" +#include "XppImpl.h" +#include "XwImpl.h" +#include + +CDmAdCert* CDmAdCert::NewL(RPKIServiceAPI& aPkiServiceApi) + { + TRACE("CDmAdCert::NewL"); + + CDmAdCert* self = NewLC(aPkiServiceApi); + CleanupStack::Pop(self); + return self; + } + +CDmAdCert* CDmAdCert::NewLC(RPKIServiceAPI& aPkiServiceApi) + { + CDmAdCert* self = new (ELeave) CDmAdCert(aPkiServiceApi); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +void CDmAdCert::ConstructL() + { + TRACE("CDmAdCert::ConstructL"); + iCertLuidMapping = new (ELeave) CArrayPtrFlat(4); + BuildCertLuidMappingTableL(); + } + +CDmAdCert::CDmAdCert(RPKIServiceAPI& aPkiServiceApi) : iPkiServiceApi(&aPkiServiceApi) + { + } + +CDmAdCert::~CDmAdCert() + { + TRACE("CDmAdCert::~CDmAdCert"); + CDmAdCertLuidMappingElem::CleanupOperationDeleteCArrayPtr(iCertLuidMapping); + } + +TBool CDmAdCert::FindL(const TDesC8& aLuid) + { + TRACE("CDmAdCert::FindL"); + if (!FindCertLuidMappingElemL(aLuid)) + { + return EFalse; + } + else + { + return ETrue; + } + } + +HBufC8* CDmAdCert::AddL(const CDmAdCertParms& aParms) + { + TRACE("CDmAdCert::AddL"); + + TPKICertificateOwnerType ownerType = aParms.Type(); + + HBufC8* certRef = BuildCertRefL(aParms.Content(), EFalse); + CleanupStack::PushL(certRef); + CDmAdCertLuidMappingElem* certLuidMappingElem = FindCertLuidMappingElemL(*certRef); + if (certLuidMappingElem) + { + DEBUG_LOG(_L("Element already exists")); + User::Leave(KErrAlreadyExists); + } + CleanupStack::PopAndDestroy(certRef); + + + TInt status = KErrNone; + if (ownerType == EPKIUserCertificate) + { + DEBUG_LOG(_L("Attaching user certificate")); + + TKeyListEntry* keyListEntry = new (ELeave) TKeyListEntry; + CleanupStack::PushL(keyListEntry); + + TPKIKeyIdentifier keyId = aParms.KeyId(); + DEBUG_LOG(_L("Key id:")); + DEBUG_LOG_HEX(keyId); + + + User::LeaveIfError(iPkiServiceApi->KeyDetails(keyId, + *keyListEntry)); + + TInt keyLength = keyListEntry->iKeySize; + + DEBUG_LOG(_L("Key info:")); + DEBUG_LOG1(_L("Object name: %S"), &(keyListEntry->iObjectName)); + DEBUG_LOG_HEX(keyListEntry->iSubjectKeyId); + DEBUG_LOG1(_L("Key size: %d"), keyListEntry->iKeySize); + DEBUG_LOG1(_L("Algorithm: %d"), keyListEntry->iKeyAlgorithm); + + + + CleanupStack::PopAndDestroy(); //keyListEntry + + status = iPkiServiceApi->AttachCertificate(keyId, + aParms.Deletable(), + keyLength, + EPKIRSA, + aParms.Content()); + } + else + { + status = iPkiServiceApi->StoreCertificate(ownerType, + aParms.Deletable(), + 0, //Key length is undefined + EPKIRSA, + aParms.Content()); + } + + if (status != KErrNone) + { + DEBUG_LOG1(_L("Operation failed with %d"), status); + User::Leave(status); + } + + certRef = BuildCertRefL(aParms.Content(), ETrue); + CleanupStack::PushL(certRef); + UpdateL(*certRef, aParms); + CleanupStack::Pop(certRef); + return certRef; + } + +void CDmAdCert::UpdateL(const TDesC8& aLuid, const CDmAdCertParms& aParms) + { + TRACE("CDmAdCert::UpdateL"); + HBufC8* issuerName; + HBufC8* serialNumber; + GetIssuerAndSerialFromCertRefLC(aLuid, issuerName, serialNumber); + + if (aParms.Type() == EPKICACertificate) // CA cert + { + UpdateTrustedL(*issuerName, *serialNumber, aParms); + UpdateApplicabilityL(*issuerName, *serialNumber, aParms); + } + + CleanupStack::PopAndDestroy(2); //serialNumber, issuerName + } + +void CDmAdCert::FetchL(const TDesC8& aLuid, CDmAdCertParms& aParms) + { + TRACE("CDmAdCert::FetchL"); + HBufC8* issuerName; + HBufC8* serialNumber; + GetIssuerAndSerialFromCertRefLC(aLuid, issuerName, serialNumber); + + //TInt certSize = 1024; + TInt certSize = 4096; + HBufC8* certBuf = NULL; + TPtr8 certBufDesc(NULL, 0); + TBool errBufferTooShortOccurred = EFalse; + for (;;) + { + if (certBuf) + { + CleanupStack::PopAndDestroy(certBuf); + } + certBuf = HBufC8::NewLC(certSize); + certBufDesc.Set(certBuf->Des()); + + // Both user and device certificate stores needs to be used for + // certificate reading. Set certificate store type to STORETYPE_ANY. + TPkiServiceStoreType certStoreType(EPkiStoreTypeAny); + User::LeaveIfError(iPkiServiceApi->CertStoreType(certStoreType)); + User::LeaveIfError(iPkiServiceApi->SetStoreType(STORE_CERTSTORE, EPkiStoreTypeAny)); + TInt err = iPkiServiceApi->ReadCertificate(*issuerName, + *serialNumber, + certBufDesc); + + // Set previous store type back + User::LeaveIfError(iPkiServiceApi->SetStoreType(STORE_CERTSTORE, certStoreType)); + + if (err == KErrNone) + { + break; + } + else if (err == KPKIErrBufferTooShort) + { + if (errBufferTooShortOccurred) + { + DEBUG_LOG(_L("Buffer too short")); + User::Leave(KErrGeneral); + } + errBufferTooShortOccurred = ETrue; + User::LeaveIfError(iPkiServiceApi->GetRequiredBufferSize(certSize)); + } + else + { + DEBUG_LOG1(_L("Fetch failed with %d"), err); + User::Leave(err); + } + } + + aParms.SetContentL(*certBuf); + ReadCertDetailsL(*issuerName, *serialNumber, aParms); + + CleanupStack::PopAndDestroy(3); //certBuf, serialNumber, issuerName + } + +void CDmAdCert::DeleteL(const TDesC8& aLuid) + { + TRACE("CDmAdCert::DeleteL"); + HBufC8* issuerName; + HBufC8* serialNumber; + GetIssuerAndSerialFromCertRefLC(aLuid, issuerName, serialNumber); + while (FindCertLuidMappingElemL(aLuid)) + { + User::LeaveIfError(iPkiServiceApi->RemoveCertificate(*issuerName, + *serialNumber)); + + RemoveCertLuidMappingElem(aLuid); + } + CleanupStack::PopAndDestroy(2); //serialNumber, issuerName + } + +void CDmAdCert::ListL(RPointerArray& aLuidList) + { + TRACE("CDmAdCert::ListL"); + for (TInt i=0; iCount(); ++i) + { + CDmAdCertLuidMappingElem* certLuidMappingElem = iCertLuidMapping->At(i); + + HBufC8* luidElem = certLuidMappingElem->Luid().AllocLC(); + aLuidList.AppendL(luidElem); + CleanupStack::Pop(luidElem); + } + } + +//------------------------------------------------------------------------ + +void CDmAdCert::ReadCertDetailsL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber, CDmAdCertParms& aParms) + { + TRACE("CDmAdCert::ReadCertDetailsL"); + TCertificateListEntry* entry = new (ELeave) TCertificateListEntry(); + CleanupStack::PushL(entry); + + User::LeaveIfError(iPkiServiceApi->CertificateDetails(aIssuerName, + aSerialNumber, + *entry)); + + aParms.SetType(entry->iOwnerType); + aParms.SetDeletable(entry->iIsDeletable); + + TBool trusted = ETrue; + if (entry->iOwnerType == EPKICACertificate) // CA cert + { + User::LeaveIfError(iPkiServiceApi->Trusted(aIssuerName, + aSerialNumber, + trusted)); + } + aParms.SetTrusted(trusted); + + if (entry->iOwnerType == EPKICACertificate) // CA cert + { + RArray applications; + CleanupClosePushL(applications); + + iPkiServiceApi->ApplicationsL(aIssuerName, + aSerialNumber, + applications); + aParms.SetApplicabilityL(applications); + CleanupStack::PopAndDestroy(); //applications + } + + CleanupStack::PopAndDestroy(); // entry + } + +void CDmAdCert::UpdateTrustedL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber, const CDmAdCertParms& aParms) + { + TRACE("CDmAdCert::UpdateTrustedL"); + + User::LeaveIfError(iPkiServiceApi->SetTrust(aIssuerName, + aSerialNumber, + aParms.Trusted())); + } + +void CDmAdCert::UpdateApplicabilityL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber, const CDmAdCertParms& aParms) + { + TRACE("CDmAdCert::UpdateApplicabilityL"); + + const RArray& applications = aParms.Applicability(); + if (applications.Count() > 0) + { + iPkiServiceApi->SetApplicabilityL(aIssuerName, + aSerialNumber, + applications); + } + } + +TPtrC8 CDmAdCert::AppendCertLuidMappingElemL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber) + { + TRACE("CDmAdCert::AppendCertLuidMappingElemL"); + TPtrC8 luid(KNullDesC8); + + CDmAdCertLuidMappingElem* certLuidMappingElem = CDmAdCertLuidMappingElem::NewLC(aIssuerName, aSerialNumber); + luid.Set(certLuidMappingElem->Luid()); + + iCertLuidMapping->AppendL(certLuidMappingElem); + CleanupStack::Pop(certLuidMappingElem); + + return luid; + } + +void CDmAdCert::RemoveCertLuidMappingElem(const TDesC8& aLuid) + { + TRACE("CDmAdCert::RemoveCertLuidMappingElem"); + for (TInt i=0; iCount(); ++i) + { + CDmAdCertLuidMappingElem* certLuidMappingElem = iCertLuidMapping->At(i); + if (certLuidMappingElem->Luid().Compare(aLuid) == 0) + { + iCertLuidMapping->Delete(i); + i--; + delete certLuidMappingElem; + break; + } + } + } + +CDmAdCertLuidMappingElem* CDmAdCert::FindCertLuidMappingElemL(const TDesC8& aLuid) + { + TRACE("CDmAdCert::FindCertLuidMappingElemL"); + for (TInt i=0; iCount(); ++i) + { + CDmAdCertLuidMappingElem* certLuidMappingElem = iCertLuidMapping->At(i); + if (certLuidMappingElem->Luid().Compare(aLuid) == 0) + { + return certLuidMappingElem; + } + } + return NULL; + } + +void CDmAdCert::BuildCertLuidMappingTableL() + { + TRACE("CDmAdCert::BuildCertLuidMappingTableL"); + CArrayFix* certList; + iPkiServiceApi->ListCertificatesL(certList); + CleanupStack::PushL(certList); + + for (TInt i=0; iCount(); ++i) + { + TCertificateListEntry& entry = certList->At(i); + AppendCertLuidMappingElemL(entry.iTrustedAuthority, entry.iSerialNumber); + } + + CleanupStack::PopAndDestroy(certList); + } + +HBufC8* CDmAdCert::BuildCertRefL(const TDesC8& aCertificateDer, TBool aAppend) + { + TRACE("CDmAdCert::BuildCertRefL"); + + CX509Certificate* certCx509 = CX509Certificate::NewL(aCertificateDer); + CleanupStack::PushL(certCx509); + + const TPtrC8 issuerName(*(certCx509->DataElementEncoding(CX509Certificate::EIssuerName))); + const TPtrC8 serialNumber(*(certCx509->DataElementEncoding(CX509Certificate::ESerialNumber))); + + HBufC8* certRef = 0; + if (aAppend) + { + TPtrC8 luid(AppendCertLuidMappingElemL(issuerName, serialNumber)); + certRef = luid.AllocL(); + } + else + { + certRef = CDmAdCertLuidMappingElem::BuildLuidL(issuerName, serialNumber); + } + + CleanupStack::PopAndDestroy(certCx509); + return certRef; + } + +void CDmAdCert::GetIssuerAndSerialFromCertRefLC(const TDesC8& aCertRef, + HBufC8*& aIssuerName, + HBufC8*& aSerialNumber) + { + CDmAdCertLuidMappingElem* certLuidMappingElem = FindCertLuidMappingElemL(aCertRef); + if (!certLuidMappingElem) + { + DEBUG_LOG(_L("Mapping not found")); + User::Leave(KErrNotFound); + } + + HBufC8* issuerNameHBuf = certLuidMappingElem->IssuerName().AllocLC(); + HBufC8* serialNumberHBuf = certLuidMappingElem->SerialNumber().AllocLC(); + + aIssuerName = issuerNameHBuf; + aSerialNumber = serialNumberHBuf; + } + +HBufC8* CDmAdCert::CertSubjectNameL(const TDesC8& aCertificateDer) + { + CX509Certificate* certCx509 = CX509Certificate::NewLC(aCertificateDer); + HBufC16* subjectName16 = certCx509->SubjectName().DisplayNameL(); + CleanupStack::PushL(subjectName16); + HBufC8* subjectName8 = HBufC8::NewL(subjectName16->Length()); + subjectName8->Des().Copy(*subjectName16); + CleanupStack::PopAndDestroy(2, certCx509); + return subjectName8; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/src/dmadstorecertreq.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/src/dmadstorecertreq.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,241 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CDmAdCertReq. +* +*/ + + +#include "dmadstorecertreq.h" +#include "vpnlogger.h" +#include "base64.h" +#include "dmadutil.h" + +CDmAdCertReq* CDmAdCertReq::NewL(RPKIServiceAPI& aPkiServiceApi, MDmAdCallBack* aDmAdCallBack) + { + TRACE("CDmAdCertReq::NewL"); + + CDmAdCertReq* self = NewLC(aPkiServiceApi, aDmAdCallBack); + CleanupStack::Pop(self); + return self; + } + +CDmAdCertReq* CDmAdCertReq::NewLC(RPKIServiceAPI& aPkiServiceApi, MDmAdCallBack* aDmAdCallBack) + { + CDmAdCertReq* self = new (ELeave) CDmAdCertReq(aPkiServiceApi, aDmAdCallBack); + CleanupStack::PushL(self); + return self; + } + +CDmAdCertReq::CDmAdCertReq(RPKIServiceAPI& aPkiServiceApi, MDmAdCallBack* aDmAdCallBack) : + iPkiServiceApi(&aPkiServiceApi), + iDmAdCallBack(aDmAdCallBack) + { + TRACE("CDmAdCertReq::CDmAdCertReq"); + } + +CDmAdCertReq::~CDmAdCertReq() + { + TRACE("CDmAdCertReq::~CDmAdCertReq"); + } + +TBool CDmAdCertReq::FindL(const TDesC8& aLuid) + { + TRACE("CDmAdCertReq::FindL"); + + TBool found = EFalse; + HBufC* certReqRef = LuidToCertReqRefL(aLuid); + CleanupStack::PushL(certReqRef); + + const TInt KDmAdMaxCertReqSize = 4096; // ???????? + HBufC8* certRequest = HBufC8::NewLC(KDmAdMaxCertReqSize); + TPtr8 certRequestPtr(certRequest->Des()); + + + TInt status = iPkiServiceApi->ReadCertificateRequest(*certReqRef, + certRequestPtr); + if (status == KErrNone) + { + found = ETrue; + } + CleanupStack::PopAndDestroy(2); //certRequest, certReqRef + return found; + } + + +HBufC8* CDmAdCertReq::AddL(const CDmAdCertReqParms& aParms) + { + TRACE("CDmAdCertReq::AddL"); + + const TInt KDmAdMaxCertReqRefLth = KMaxFileName; + HBufC* certReqRef = HBufC::NewLC(KDmAdMaxCertReqRefLth); + TPtr certReqRefPtr(certReqRef->Des()); + + TPKIKeyIdentifier keyIdentifier(aParms.KeyIdentifierByUri()); + if (keyIdentifier.Length() == 0) + { + CreateKeypairL(EPKIRSA, + aParms.KeyLength(), + keyIdentifier); + } + + DEBUG_LOG(_L("Key ID:")); + DEBUG_LOG_HEX(keyIdentifier); + + SetKeyIDMappingL(keyIdentifier); + + TInt certReqSize; + iPkiServiceApi->CreateAndSaveCertificateRequestL(keyIdentifier, + aParms.SubjectName(), //aDistinguishedName, + aParms.Rfc822Name(), //aSubjectAltNameRfc822, + KNullDesC8, //aChallengePassword, + KNullDesC8, //aDnsName, + certReqRefPtr, + certReqSize); + + HBufC8* luid = CertReqRefToLuidL(*certReqRef); + CleanupStack::PopAndDestroy(certReqRef); + return luid; + } + +void CDmAdCertReq::SetKeyIDMappingL(const TPKIKeyIdentifier& keyIdentifier) + { + TRACE("CDmAdCertReq::SetKeyIDMapping"); + + // First fetch all private key URIs + CBufBase* uriList = CBufFlat::NewL(16); + CleanupStack::PushL(uriList); + _LIT8(KKeyUri, "NokiaPKI/PrivKey"); + MSmlDmAdapter::TError status; + iDmAdCallBack->FetchLinkL(KKeyUri, *uriList, status); + User::LeaveIfError(status); + + // Find out key URI (cli) for the newly created private key + CArrayFix* uriSegList; + TDmAdUtil::ParseUriLC(uriList->Ptr(0), uriSegList); + // New key URI (cli) is now in uriSegList->At(0) + HBufC8* wholeUri = TDmAdUtil::BuildUriLC(KKeyUri, uriSegList->At(0)); + + iDmAdCallBack->SetMappingL(*wholeUri, keyIdentifier); + + CleanupStack::PopAndDestroy(wholeUri); + CleanupStack::PopAndDestroy(uriSegList); + CleanupStack::PopAndDestroy(uriList); + } + +void CDmAdCertReq::UpdateL(const TDesC8& /*aLuid*/, const CDmAdCertReqParms& /*aParms*/) + { + TRACE("CDmAdCertReq::UpdateL"); + DEBUG_LOG(_L("Method not implemented")); + + User::Leave(KErrGeneral); + } + +void CDmAdCertReq::FetchL(const TDesC8& aLuid, CDmAdCertReqParms& aParms) + { + TRACE("CDmAdCertReq::FetchL"); + + HBufC* certReqRef = LuidToCertReqRefL(aLuid); + CleanupStack::PushL(certReqRef); + + const TInt KDmAdMaxCertReqSize = 4096; // ???????? + HBufC8* certRequest = HBufC8::NewLC(KDmAdMaxCertReqSize); + TPtr8 certRequestPtr(certRequest->Des()); + + User::LeaveIfError(iPkiServiceApi->ReadCertificateRequest(*certReqRef, + certRequestPtr)); + + TBase64Codec base64Codec; + HBufC8* certRequestB64Decoded; + if ((certRequestB64Decoded = base64Codec.Base64DecodeLC(*certRequest)) == NULL) + { + DEBUG_LOG(_L("base64Codec.Base64DecodeLC returned NULL")); + User::Leave(KErrNoMemory); + } + + aParms.SetContentL(*certRequestB64Decoded); + //ReadCertReqDetailsL(*certReqRef, aParms); // ??????????? + CleanupStack::PopAndDestroy(3); // certRequestB64Decoded, certRequest, certReqRef + } + + +void CDmAdCertReq::DeleteL(const TDesC8& aLuid) + { + TRACE("CDmAdCertReq::DeleteL"); + + HBufC* certReqRef = LuidToCertReqRefL(aLuid); + CleanupStack::PushL(certReqRef); + + User::LeaveIfError(iPkiServiceApi->DeleteCertificateRequest(*certReqRef)); + + CleanupStack::PopAndDestroy(certReqRef); + } + + +void CDmAdCertReq::ListL(RPointerArray& aLuidList) + { + TRACE("CDmAdCertReq::ListL"); + + CArrayFix* certReqList; + iPkiServiceApi->ListCertificateRequestsL(certReqList); + CleanupStack::PushL(certReqList); + + for (TInt i=0; iCount(); ++i) + { + TCertificateRequestListEntry& entry = certReqList->At(i); + HBufC8* luid = CertReqRefToLuidL(entry.iObjectName); + CleanupStack::PushL(luid); + aLuidList.AppendL(luid); + CleanupStack::Pop(luid); + } + + CleanupStack::PopAndDestroy(certReqList); + } + +void CDmAdCertReq::CreateKeypairL(TPKIKeyAlgorithm aKeyAlgorithm, + TInt aKeyLength, + TPKIKeyIdentifier& aKeyIdentifier) + { + TRACE("CDmAdCertReq::CreateKeypairL"); + + TRequestStatus requestStatus; + iPkiServiceApi->GenerateKeypair(aKeyIdentifier, + (TUint)aKeyLength, + aKeyAlgorithm, + requestStatus); + User::WaitForRequest(requestStatus); + TInt status = requestStatus.Int(); + if (status != KErrNone) + { + DEBUG_LOG1(_L("GenerateKeypairL returned %d"), status); + User::Leave(status); + } + } + +HBufC8* CDmAdCertReq::CertReqRefToLuidL(const TDesC& aCertReqRef) + { + TRACE("CDmAdCertReq::CertReqRefToLuidL"); + + HBufC8* luid = HBufC8::NewL(aCertReqRef.Length() * 2); + luid->Des().Copy((const TUint8*)aCertReqRef.Ptr(), aCertReqRef.Length() * 2); + return luid; + } + +HBufC* CDmAdCertReq::LuidToCertReqRefL(const TDesC8& aLuid) + { + TRACE("CDmAdCertReq::LuidToCertReqRefL"); + + HBufC* certReqRef = HBufC::NewL(aLuid.Length() / 2); + certReqRef->Des().Copy((const TUint16*)aLuid.Ptr(), aLuid.Length() / 2); + return certReqRef; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/src/dmadstorepkcs12.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/src/dmadstorepkcs12.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,96 @@ +/* +* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: implementation of CDmAdPKCS12 +* +*/ + + + +#include "dmadutil.h" +#include "dmadstorepkcs12.h" +#include "vpnlogger.h" +#include "dmadcertxmldefs.h" +#include "XppImpl.h" +#include "XwImpl.h" +#include "pkcs12vpn.h" + +#include + +CDmAdPKCS12* CDmAdPKCS12::NewL(RPKIServiceAPI& aPkiServiceApi) + { + TRACE("CDmAdPKCS12::NewL"); + + CDmAdPKCS12* self = NewLC(aPkiServiceApi); + CleanupStack::Pop(self); + return self; + } + +CDmAdPKCS12* CDmAdPKCS12::NewLC(RPKIServiceAPI& aPkiServiceApi) + { + CDmAdPKCS12* self = new (ELeave) CDmAdPKCS12(aPkiServiceApi); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +void CDmAdPKCS12::ConstructL() + { + TRACE("CDmAdPKCS12::ConstructL"); + } + +CDmAdPKCS12::CDmAdPKCS12(RPKIServiceAPI& aPkiServiceApi) : iPkiServiceApi(&aPkiServiceApi) + { + } + +CDmAdPKCS12::~CDmAdPKCS12() + { + TRACE("CDmAdPKCS12::~CDmAdPKCS12"); + } + +HBufC8* CDmAdPKCS12::AddL(const CDmAdPKCS12Parms& aParms) + { + TRACE("CDmAdPKCS12::AddL"); + + DEBUG_LOG(_L("Instantiating pkcs12handler")); + CPKCS12Handler* pkcs12handler = CPKCS12Handler::NewLC(*iPkiServiceApi); + + DEBUG_LOG(_L("Setting deletable")); + pkcs12handler->SetDeletable(aParms.Deletable()); + + DEBUG_LOG(_L("Setting applicability")); + pkcs12handler->SetApplicability(aParms.Applicability()); + + HBufC* pwd(NULL); + if (aParms.Password().Length() == 0) + { + DEBUG_LOG(_L("Password length is zero, no password given")); + pwd = HBufC::NewLC(0); + } + else + { + DEBUG_LOG(_L("Converting password to 16bit base")); + pwd = HBufC::NewLC(aParms.Password().Length()); + pwd->Des().Copy(aParms.Password()); + } + + DEBUG_LOG(_L("Storing pkcs12 object")); + pkcs12handler->StorePKCS12ObjectL(aParms.Content(), *pwd); + + DEBUG_LOG(_L("Freeing handler resources")); + + CleanupStack::PopAndDestroy(2, pkcs12handler); + + return NULL; + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/dmadpki/src/dmadstoreprivkey.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/dmadpki/src/dmadstoreprivkey.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,123 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CDmAdPrivKey. +* +*/ + + +#include + +#include "dmadstoreprivkey.h" +#include "vpnlogger.h" + +CDmAdPrivKey* CDmAdPrivKey::NewL(RPKIServiceAPI& aPkiServiceApi) + { + TRACE("CDmAdPrivKey::NewL"); + + CDmAdPrivKey* self = NewLC(aPkiServiceApi); + CleanupStack::Pop(self); + return self; + } + +CDmAdPrivKey* CDmAdPrivKey::NewLC(RPKIServiceAPI& aPkiServiceApi) + { + CDmAdPrivKey* self = new (ELeave) CDmAdPrivKey(aPkiServiceApi); + CleanupStack::PushL(self); + return self; + } + +CDmAdPrivKey::CDmAdPrivKey(RPKIServiceAPI& aPkiServiceApi) : iPkiServiceApi(&aPkiServiceApi) + { + TRACE("CDmAdPrivKey::CDmAdPrivKey"); + } + +CDmAdPrivKey::~CDmAdPrivKey() + { + TRACE("CDmAdPrivKey::~CDmAdPrivKey"); + } + +TBool CDmAdPrivKey::FindL(const TDesC8& aLuid) + { + TRACE("CDmAdPrivKey::FindL"); + + TBool found = EFalse; + + const TInt KMaxPublicKeyLth = 512; + HBufC8* privKeyData = HBufC8::NewLC(KMaxPublicKeyLth); + TPtr8 privKeyDataPtr(privKeyData->Des()); + + TInt status = iPkiServiceApi->ReadPublicKey(aLuid, + privKeyDataPtr); + if (status == KErrNone) + { + found = ETrue; + } + + CleanupStack::PopAndDestroy(privKeyData); + return found; + } + +void CDmAdPrivKey::FetchL(const TDesC8& aLuid, CDmAdPrivKeyParms& aParms) + { + TRACE("CDmAdPrivKey::FetchL"); + + TPkiServiceStoreType currentKeyStore; + User::LeaveIfError(iPkiServiceApi->KeyStoreType(currentKeyStore)); + User::LeaveIfError(iPkiServiceApi->SetStoreType(STORE_KEYSTORE, EPkiStoreTypeAny)); + + TKeyListEntry* entry = new (ELeave) TKeyListEntry(); + CleanupStack::PushL(entry); + User::LeaveIfError(iPkiServiceApi->KeyDetails(aLuid, *entry)); + + User::LeaveIfError(iPkiServiceApi->SetStoreType(STORE_KEYSTORE, currentKeyStore)); + + aParms.SetKeyTypeL(entry->iKeyAlgorithm); + aParms.SetKeyIdL(entry->iSubjectKeyId); + aParms.SetKeyLength(entry->iKeySize); + + CleanupStack::PopAndDestroy(); // entry + } + +void CDmAdPrivKey::DeleteL(const TDesC8& aLuid) + { + TRACE("CDmAdPrivKey::DeleteL"); + + User::LeaveIfError(iPkiServiceApi->RemoveKeypair(aLuid)); + } + +void CDmAdPrivKey::ListL(RPointerArray& aLuidList) + { + TRACE("CDmAdPrivKey::ListL"); + + TPkiServiceStoreType currentKeyStore; + User::LeaveIfError(iPkiServiceApi->KeyStoreType(currentKeyStore)); + User::LeaveIfError(iPkiServiceApi->SetStoreType(STORE_KEYSTORE, EPkiStoreTypeAny)); + + CArrayFix* keyList; + iPkiServiceApi->ListKeysL(keyList); + CleanupStack::PushL(keyList); + + User::LeaveIfError(iPkiServiceApi->SetStoreType(STORE_KEYSTORE, currentKeyStore)); + + for (TInt i=0; iCount(); ++i) + { + TKeyListEntry& entry = keyList->At(i); + HBufC8* luidElem = entry.iSubjectKeyId.AllocLC(); + aLuidList.AppendL(luidElem); + CleanupStack::Pop(luidElem); + } + + CleanupStack::PopAndDestroy(keyList); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediator/BWINS/EVENTMEDU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediator/BWINS/EVENTMEDU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?WinsMain@@YAHXZ @ 1 NONAME ; int __cdecl WinsMain(void) + diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediator/data/backup_registration.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediator/data/backup_registration.xml Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,8 @@ + + + + + + + + diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediator/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediator/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file provides the information required for building the module. +* +*/ + + + +#include + +PRJ_PLATFORMS + +PRJ_EXPORTS + + +PRJ_MMPFILES + +eventmediator.mmp + +PRJ_TESTMMPFILES diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediator/group/eventmediator.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediator/group/eventmediator.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project eventmed +* +*/ + + + +#include + + +TARGET eventmed.exe +TARGETTYPE exe +UID 0x1000008d 0x101FD288 + +CAPABILITY ProtServ NetworkControl NetworkServices +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE eventmediator.cpp +SOURCE eventlogger.cpp +SOURCE eventmediatorstarter.cpp + +SOURCEPATH ../../vpncommon/src +SOURCE srvstatic.cpp + +USERINCLUDE ../inc +USERINCLUDE ../../eventmediatorapi/inc +USERINCLUDE ../../vpncommon/inc +USERINCLUDE ../../sit/inc +USERINCLUDE ../../vpnmanager/inc +USERINCLUDE ../../../vpnapiimpl/inc + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY euser.lib +LIBRARY efsrv.lib +LIBRARY eventmedsit.lib +DEBUGLIBRARY flogger.lib diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediator/inc/eventlogger.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediator/inc/eventlogger.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,278 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This module defines event logger. +* +*/ + + + +#ifndef _EVENTLOGGER_H_ +#define _EVENTLOGGER_H_ + +// INCLUDES +#include +#include +#include "eventmediatorapi.h" +#include "eventmediator.h" + +_LIT(KEventLogFile, "eventlog.bin"); + + +// CLASS DECLARATION + +/** +* Contains general information about a log event. When reporting a log event an object of this class +* Should be in the begining of the data descriptor. +*/ +class TLogEvent +{ +/* public: + enum TLogCategory + { EInfo, + EWarning, + EError, + EDebug + }; +*/ + public: // Methods + /** + * Standard constructors + */ + TLogEvent(){}; + TLogEvent(TUid aSource, TLogCategory aCategory, TUint aMsgId, TInt aDesCount):iSource(aSource), iCategory(aCategory),iMsgId(aMsgId),iDesCount(aDesCount){}; + + public: // Data + // enumeration of log event categories + + // source of the log event + TUid iSource; + // category of the log event + TLogCategory iCategory; + // id of the log message + TUint iMsgId; + // number of data descriptors related to this iMsgId + TInt iDesCount; + }; + + + + + + +#define LOGFILE_MAX_LTH 20 // 20 kb +#define KBYTES_TO_BYTES 1024 +#define ELEM_HEADER_LTH 16 +#define ELEM_TRAILER_LTH 12 +//#define FILE_HEADER_LTH 16 NOTE! moved to eventmediatorapi.h +#define FILE_BEGIN 0 +#define END_MARK_1 0xefbeadde +#define END_MARK_2 0xeeabedfe +#define FILE_ID 0x474f4c45 // ELOG + + +// CLASS DECLARATION + +/** +* Class used to write the log file. +*/ +class CEventLogger : public CBase +{ + public: //Methods + + // Constructors and destructor + + /** + * Default constructor, maximum length of log file set to LOGFILE_MAX_LTH + */ + static CEventLogger* NewL(CEventMediatorServer* aServer); + + /** + * Constructor + * @param aFileMaxLength: maximum length of log file in kbytes + */ + CEventLogger(TInt aFileMaxLength, CEventMediatorServer* aServer); + + /** + * Destructor + */ + ~CEventLogger(); + + /** + * Writes new event to the log file. + * @param aEvent: descriptor containing instance of class TLogEvent + * and data descriptor of the event appended to it + */ + void LogEvent(const TDesC8& aEvent); + + private: //Methods + + /** + * Writes new event to the log file. + * @param aInfo: general info on the event. + * @param aData: event data. + */ +// void LogEvent(const TLogEvent& aInfo, const TDesC8& aData); + + /** + * Opens the log file for reading and writing. + * @return: Etrue if Successfull, EFalse if not + */ + TBool OpenLogFile(); + + /** + * Closes the log file. + */ + void CloseLogFile(); + + /** + * Reads the file header from the log file to a descriptor. + * @param aFileHdr: descriptor to which the header is read. + * @return: Etrue if Successfull, EFalse if not + */ + TBool GetFileHeader(TDes8 &aFileHdr); + + /** + * Returns the position in the file to which a new element can be written. + * @param aFileHdr: log file header. + * @param aLength: length of the element about to be written. + * @return: position to write the element to. + */ + TInt GetElemDataPosition(TDes8 &aFileHdr, TInt aLength); + + /** + * Saves the log file header to the log file. + * @param aPosition: the position to which new elements can be written. + * @param aFileHdr: log file header. + * @return: Etrue if Successfull, EFalse if not + */ + TBool SaveFileHeader(TInt aPosition, TDes8 &aFileHdr); + + /** + * Stores the log file header to a descriptor. + * @param aPosition: the position to which new elements can be written. + * @param aFirstOffset: wrapping offset + * @param aBuf: log file header. + */ + void StoreFileHeaderInfo(TInt aPosition, TInt aFirstOffset, TDes8 &aBuf); + + /** + * Writes new event to the log file. + * @param aPosition: the position to write the element to. + * @param aEvent: descriptor containning the element + * @return: the total length of the written element. + */ + TInt WriteLogElem(TInt aPosition, const TDesC8& aEvent); + + /** + * Gets the time and formats it into a TUint32 object. + * @return: the time stamp as an unsigned integer. + */ +// TUint32 GetTimeStamp(); + + private: + /** + * Default constructor. + */ + CEventLogger(CEventMediatorServer* aServer); + private: //Data + // file server + RFs iFS; + + // log file + RFile iLogFile; + + // log file max length + TInt iFileMaxLength; + + // event number, starting from 1 + TUint32 iEventNumber; + + CEventMediatorServer* iServer; +}; + + +// CLASS DECLARATION + +/** +* Contains log file header, basically two integers position and wrapping offset. +*/ +class TFileHeader + { + public: // Methods + inline TInt32 GetPosition() const {return ((TInt32)(u.iData32[1]));}; + inline TInt32 GetWrappingOffset() const {return ((TInt32)(u.iData32[2]));}; + inline TInt32 GetEventNumber() const {return ((TInt32)(u.iData32[3]));}; + inline void SetFileId() {u.iData32[0] = FILE_ID; }; + inline void SetPosition(TInt32 aPosition) {u.iData32[1] = (TUint32)aPosition;}; + inline void SetWrappingOffset(TInt32 aWO) {u.iData32[2] = (TUint32)aWO;}; + inline void SetEventNumber(TInt32 aEventNumber) {u.iData32[3] = (TUint32)aEventNumber;}; + + private: // Data + union // Currently union is not needed, only iData32 is used + { + TUint32 iData32[4]; + TUint8 iData8[8]; + } u; + }; + + + +// CLASS DECLARATION + +/** +* Contains log element header, consisting of four integer values: +* length: length of the data beloging to the element +* timestamp: the time the element was written. +* source: Uid of the reporter of the element. +* aCategory: the gategory of the log event. +*/ +class TElemHeader + { + public: // Methods + + inline void SetEventLength(TUint32 aLength) {u.iData32[0] = (TUint32)aLength;}; + inline void SetEventNumber(TUint32 aEventNumber) {u.iData32[1] = (TUint32)aEventNumber;}; +// inline void SetTime(TUint32 aTimeStamp) {u.iData32[2] = (TUint32)aTimeStamp;}; + inline void SetTime(const TInt64& aTimeStamp) {u.iData32[2] = I64LOW(aTimeStamp); u.iData32[3] = I64HIGH(aTimeStamp);}; + + private: // Data + union + { + TUint32 iData32[4]; + TUint8 iData8[8]; + } u; + }; + + +// CLASS DECLARATION + +/** +* Contains a constant log element trailer, consisting of two integer values. +*/ +class TElemTrailer + { + public: // Methods + inline void SetLogEndMark() {u.iData32[0] = END_MARK_1; + u.iData32[1] = END_MARK_2;}; + inline void SetEventLength(TUint32 aLength) {u.iData32[2] = (TUint32)aLength;}; + private: // Data + union + { + TUint32 iData32[3]; + TUint8 iData8[8]; + } u; + }; + + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediator/inc/eventmediator.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediator/inc/eventmediator.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,579 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This module defines event mediator and the services of it. +* +*/ + + + +/** + * @file eventmediator.h + * + * This module defines event mediator and the services of it. + * + */ + +#ifndef __EVENTMEDIATOR_H__ +#define __EVENTMEDIATOR_H__ + +// INCLUDES +#include +#include +#include "eventmediatorapi.h" +#include "eventmediatordefs.h" + +#include "sitdeathobserver.h" + +// FORWARD DECLARATIONS +class CEventMediatorSession; +class TEventContainer; +class CEventLogger; + +class CSit; + +class CListenerContainer; + +// CLASS DECLARATION + +/** +* Defines the event mediator server. +*/ +class CEventMediatorServer : public CPolicyServer, public MSitDeathListener + { + friend class CEventMediatorSession; // Friend class + + public: //Methods + + // Constructors and destructor + + /** + * Static constructor + */ + static CEventMediatorServer* NewL(void); + + /** + * Static constructor + */ + static CEventMediatorServer* NewLC(void); + + /** + * Destructor + */ + ~CEventMediatorServer(void); + + /** + * Creates a new session. + */ + CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const; + + // Other methods + + /** + * Reports new envent to the eventmediator server. + * @param aType: type of the event. + * @param aSpec: additional info on event. + * @param aData: a descriptor containing event data. + */ + void ReportEventL(const TEventType aType, TDesC8* aSpec, + TDesC8* aData, TInt aStatus = KErrNone); + + /** + * Completes the last message in error case. + * @param aError: Cause of the call of this function. + */ + void CompleteLastMessage(TInt aError); + + /** + * Finds out whether the specified client thread is a SIT + * thread or not + */ + TBool IsClientTheSitL(const RMessage2& aMessage); + + /** + * Starts the SIT thread if it is not running + */ + void MakeSureSitIsRunningL(); + + /** + * Saves a pointer to the listening request that represents the + * task arrival observation request + */ + void SetTaskArrivalListenerL(CListenerContainer* aListener); + + /** + * Clears the pointer to the listening request that represents the + * task arrival observation request + */ + void ClearTaskArrivalListener(); + + /** + * Returns the pointer to the task arrival observation request + */ + CListenerContainer* TaskArrivalListener(); + + /** + * Notifies the server about a new task request that has arrived + */ + void TaskRequestArrivedL(CListenerContainer* aTaskRequest); + + /** + * Notifies the server about a new task arrival + * observation request that has arrived from the SIT + */ + void TaskArrivalObservationRequestArrivedL(); + + /** + * Notifies the server about a new task request event + * specification fetching request that has arrived from + * the SIT. + */ + void TaskRequestEventSpecFetchingRequestArrivedL(CListenerContainer* aFetchingRequest); + + /** + * Notifies the server about a new task cancellation + * observation request that has arrived from the SIT. + */ + void TaskCancellationObservationRequestArrivedL(CListenerContainer* aRequest); + + /** + * Completes a pending task arrival observation + * request when a new task request has arrived. + */ + void CompleteTaskArrivalObservationRequestL(TEventType aEventType, TDesC8* aSpec); + + /** + * Completes a pending task request event + * specification fetching request. + */ + void CompleteTaskRequestEventSpecFetchingRequestL(TInt aStatus, TDesC8* aEventSpec, + TDesC8* aTaskRequestEventSpec); + + /** + * Tries to find a task request that is not yet + * being fulfilled by the SIT. + */ + CListenerContainer* FindWaitingTaskRequest(); + + /** + * Retrieves the event listener object, if any, that has the + * specified event type and event specification ID. + */ + CListenerContainer* FindListener(TEventType aEventType, TInt aEventSpecId); + + /** + * Retrieves the event listener object, if any, that is using + * the SIT that has the specified thread ID and is fulfilling + * the specified event. + */ + CListenerContainer* FindListener(TEventType aEventType, const TDesC8* aEventSpec); + + /** + * Completes the listener that matches the specified search + * criteria. + */ + void CompleteListener(TEventType aEventType, const TDesC8* aEventSpec, TInt aStatus); + + /** + * Completes the listener that matches the specified search + * criteria. + */ + void CompleteListener(CListenerContainer* aListenerPtr, TInt aStatus); + + /** + * Returns the number of "normal" (non-sit) + * sessions that are present + */ + TInt NormalSessionCount(); + + /** + * Completes all task requests with the specified status + */ + void CompleteTaskRequests(TInt aStatus); + + /** + * Returns a new event specification ID. + */ + TInt NewEventSpecId(); + + TPtrC EventLogFileName(void); + + public: // From MSitDeathListener + void SitDied(); + + protected: + /** + * Process any errors + * + * @param aError the leave code reported + */ + TInt RunError(TInt aError); + + private: // Methods + + // Constructors and destructor + + /** + * Default constructor + */ + CEventMediatorServer(void); + + /** + * Perform the second phase construction of a CVpnManagerServer + * object. + * @param aServer Pointer to the server itself. + */ + void ConstructL(CEventMediatorServer* aServer); + + // Other methods + + /** + * Stops the server if the session count is zero. + */ + void StopEventMediator(void); + + /** + * Copies data describing an event to the client. + * @param aMessge: a message from client side sent by RConnection::FetchData + * @return error code, KErrNone if successfull + */ + TInt CopyEventDataL(const RMessage2& aMessage); + + /** + * Reduces listener count of a stored event by one and destroys it if count becomes zero. + * @param aIndex: the index of the stored event in the list. + */ + void MarkStoredEventListened(TInt aIndex); + + /** + * Sets the iShuttingDown flag. + */ + void SetShuttingDown(TBool aShuttingDown); + + private: //Data + // List of Events that have been reported but not handled by all listeners. + CArrayFixFlat iStoredEvents; + // Number of currently existing sessions. + TInt iSessionCount; + // Log writer + CEventLogger* iLogger; + // The next event specification ID + // (used with SIT event listening requests) + TInt iNextEventSpecId; + // The single SIT instance + CSit* iSit; + // The single task arrival listener + CListenerContainer* iTaskArrivalListener; + + // A flag that is set to true when + // the server starts going down + TBool iShuttingDown; + + TFileName iEventLogFileName; + + static const TUint iRangeCount; + static const TInt iRanges[]; + static const TUint8 iElementIndex[]; + + static const CPolicyServer::TPolicyElement iElements[]; + static const CPolicyServer::TPolicy iPolicy; + + }; + +// CLASS DECLARATION + +/** +* Defines the session to the VPN manager server. +*/ +class CEventMediatorSession : public CSession2 + { + public: //Message types + enum + { + KEventMediatorListen, + KEventMediatorListenWithSpec, + KEventMediatorCancel, + KEventMediatorCancelWithSpec, + KEventMediatorCancelAll, + KEventMediatorReportEvent, + KEventMediatorReportEventWithSpec, + KEventMediatorFetchData, + KEventMediatorReportLogEvent, + KEventMediatorNewEventSpecId, + KEventMediatorDeletePrivateFiles, + KEventMediatorGetEventLogSize, + KEventMediatorGetEventLogHeader, + KEventMediatorGetEventLogData, + KEventMediatorClearEventLog + }; + + public: // Methods + + // Constructors and destructor + + /** + * Static constructor + */ + static CEventMediatorSession* NewL(CEventMediatorServer* aServer, const RMessage2& aMessage); + + /** + * Default destructor + */ + ~CEventMediatorSession(void); + + /** + * Wrapper function which Dispatches and executes the client's service calls + * (See Message type definition). + */ + void ServiceL(const RMessage2& aMessage); + + /** + * Checks if client is listening events of the given type and completes message + * sent by clients ListenToEvent function. The length of the event data and + * the pointer to that data are written to the message. + * @param aType: type of the event. + * @param aSpec: additional info on event. + * @param aData: event data. + * @return number of listeners for the event was listened. + */ + TInt CheckEventL(const TEventType aType, const TDesC8* aSpec, const TDesC8* aData, TInt aStatus); + + /** + * Tries to find a task request that is not being fulfilled + * already + */ + CListenerContainer* FindWaitingTaskRequest(); + + /** + * Retrieves the event listener object, if any, that is using + * the SIT that is fulfilling the specified event. + */ + CListenerContainer* FindListener(TEventType aEventType, TInt aEventSpecId); + + /** + * Retrieves the event listener object, if any, that is using + * the SIT that is fulfilling the specified event. + */ + CListenerContainer* FindListener(TEventType aEventType, const TDesC8* aEventSpec); + + /** + * Completes the specified listener if it is owned by the + * session. Returns ETrue is the listener was found and + * completed, EFalse otherwise. + */ + void CompleteListener(TEventType aEventType, const TDesC8* aEventSpec, TInt aStatus); + + void CompleteTaskRequests(TInt aStatus); + + TBool IsASitSession(); + + private: //Methods + // Constructors and destructor + + /** + * Constructor + */ + CEventMediatorSession(CEventMediatorServer* aServer); + + /** + * Starts listening events of requesteed type by coping the message to iListenedEvents. + * @param aMessage: aMessage sent by clients ListenToEvent function. + * @return: error code, KErrNone if successfull. + */ + TInt ListenToEventWithSpecL(const RMessage2& aMessage); + + /** + * Starts listening events of requesteed type by coping the message to iListenedEvents. + * @param aMessage: aMessage sent by clients ListenToEvent function. + * @return: error code, KErrNone if successfull. + */ + TInt ListenToEventL(const RMessage2& aMessage); + + /** + * Reports the event contained in the message to the event mediator server. + * @param aMessage: aMessage sent by clients ReportEvent function. + * @return: error code, KErrNone if successfull. + */ + void ReportEventL(const RMessage2& aMessage); + + /** + * Reports a log event contained in the message to the event mediator server. + * @param aMessage: aMessage sent by clients ReportLogEvent function. + * @return: error code, KErrNone if successfull. + */ + void ReportLogEventL(const RMessage2& aMessage); + + /** + * Reports the event contained in the message to the event mediator server. + * @param aMessage: aMessage sent by clients ReportEvent function. + * @return: error code, KErrNone if successfull. + */ + void ReportEventWithSpecL(const RMessage2& aMessage); + + /** + * Cancels listning of one event type. + * @param aMessage: aMessage sent by clients CancelListenToEvent function. + */ + void CancelListening(const RMessage2& aMessage); + + /** + * Cancels listning of one event type. + * @param aMessage: aMessage sent by clients CancelListenToEvent function. + */ + void CancelListeningWithSpecL(const RMessage2& aMessage); + + /** + * Cancels all listening. + * @param aMessage: aMessage sent by clients CancelAllListening function. + */ + void CancelAll(); + + /** + * Copies event data from the server to the client. + * @param aMessage: aMessage sent by clients FetchData function. + * @return: error code, KErrNone if successfull. + */ + TInt FetchDataL(const RMessage2& aMessage); + + /** + * Looks up a message from iListenedEvents. + * @param aType: type of the event the message is listening to. + * @param aIndex: the position of the message in iListenedEvents. + * @return ETrue if message exists, EFalse if not. + */ + TBool FindListenerMsg(const TEventType aType,TInt& index); + + /** + * Looks up a message from iListenedEvents. + * @param aType: type of the event the message is listening to. + * @param aIndex: the position of the message in iListenedEvents. + * @return ETrue if message exists, EFalse if not. + */ + TBool FindListenerMsg(const TEventType aType,const TDesC8* aSpec,TInt& index); + + /** + * Searches for a task request type event listening request + */ + TBool FindTaskRequestListenerMsg(TInt& index); + + /** + * Reads data that was reported with the event from client. Allocates a buffer + * for data and gives ownership of that buffer to caller. + * @param aMessage: aMessage sent by clients ReportEvent function. + * @return pointer to the newly created buffer containig data. + */ + HBufC8* ReadEventDataFromClientL(const RMessage2& aMessage); + + /** + * Reads specification describing the event from client. Allocates a buffer + * for secification and gives ownership of that buffer to caller. + * @param aMessage: aMessage sent with event specification. + * @return pointer to the newly created buffer containig data. + */ + HBufC8* ReadSpecificationFromClientL(const RMessage2& aMessage); + + /** + * Completes the specified listener and deletes it from the + * listener list + */ + void CompleteListener(TInt aIndex, TInt aStatus); + + /** + * Returns to the client a new event specification ID + */ + void NewEventSpecIdL(const RMessage2& aMessage); + + TInt DeletePrivateFiles(); + void DeletePrivateFilesL(); + + TInt GetEventLogSize(const RMessage2& aMessage); + TInt GetEventLogHeader(const RMessage2& aMessage); + TInt GetEventLogData(const RMessage2& aMessage); + TInt ClearEventLog(); + + private: //Data + // List of messages listening to events + CArrayFixFlat iListenedEvents; + // Event mediator server + CEventMediatorServer* iServer; + + RFs iFs; + RFile iEventLogFile; + TBool iEventLogFileOpen; + // Is this session from a SIT or not + + public: + TBool iIsSitSession; + }; + +// CLASS DECLARATION + +/** +* Container for one reported event from witch it can be read by all listening sessions. +*/ +class TEventContainer + { + public: //Methods + // Constructors and destructor + + /** + * Inline constructor + */ + inline TEventContainer(TInt aCount, TDesC8* aData) : iData(aData), iListenerCount(aCount){}; + + public: //Data + // Data descriptor reported with the event. + TDesC8* iData; + // number of listeners that need this event + TInt iListenerCount; + }; + + +// CLASS DECLARATION + +/** +* Container for one reported event from which it can be read by all listening sessions +*/ +class CListenerContainer : public CBase + { + public: //Methods + // Constructors and destructor + CListenerContainer(const RMessage2& aMessage, TDesC8* aSpec, + CEventMediatorServer* aServer); + ~CListenerContainer(); + + inline TEventType Type() {return (TEventType) iMessage.Int0();} + inline RMessage2& Message() {return iMessage;} + inline TDesC8* Specification() {return iSpec;} + void Complete(TInt status); + + void AnalyzeRequestL(); + TBool WaitingForFulfilling(); + void MarkAsBeingFulfilled(); + TBool BeingFulfilled(); + + TBool HandlesEvent(TEventType aEventType, const TDesC8* aEventSpec); + + private: //Data + // Data descriptor reported with the event. + TDesC8* iSpec; + RMessage2 iMessage; + TEventType iEventType; + // Pointer to the event mediator server + CEventMediatorServer* iServer; + // A flag that tells whether the request + // is being fulfilled by the SIT or not + TBool iBeingFulfilledBySit; + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediator/inc/eventmediatordefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediator/inc/eventmediatordefs.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2003-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Defines constants +* +*/ + + + +#ifndef __EVENTMEDIATORDEFS_H__ +#define __EVENTMEDIATORDEFS_H__ + +#include + +static const TUid KEventMediatorUid3 = {0x101FD288}; + +_LIT(KEventMediatorFile, "eventmed"); +_LIT(KEventMediatorServer, "!EventMediatorServer"); + +// The server version. A version must be specified when +// creating a session with the server +const TUint KEventMediatorMajorVersionNumber = 0; +const TUint KEventMediatorMinorVersionNumber = 1; +const TUint KEventMediatorBuildVersionNumber = 1; + +/*// Panic codes +enum TEventMediatorPanic + { + ECreateTrapCleanup = 1, + ECreateServer, + EBadDescriptor, + EBadRequest, + }; +*/ +#endif // __EVENTMEDIATORDEFS_H__ diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediator/inc/log_em.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediator/inc/log_em.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Logging utility. +* +*/ + + + +#if !defined(__LOG_EM_H__) +#define __LOG_EM_H__ + +_LIT(KLogFile, "eventmed.txt"); + +#include "logcommon.h" + +#endif // __LOG_EM_H__ diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediator/rom/eventmediator.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediator/rom/eventmediator.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Image description file for project eventmediator +* +*/ + + + +#ifndef __EVENTMEDIATOR_IBY__ +#define __EVENTMEDIATOR_IBY__ + +#ifdef SYMBIAN_EXCLUDE_IPSEC + +REM Feature EVENTMEDIATOR not included in this rom + +#else + +file=ABI_DIR\BUILD_DIR\eventmed.exe PROGRAMS_DIR\eventmed.exe +// data=EPOCROOT##epoc32\winscw\c\private\101FD288\backup_registration.xml Private\101FD288\backup_registration.xml + +#endif // SYMBIAN_EXCLUDE_IPSEC + +#endif // __EVENTMEDIATOR_IBY__ diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediator/src/eventlogger.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediator/src/eventlogger.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,331 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This module defines event logger. +* +*/ + + + +#include +#include +//#include "filesdef.h" +#include "eventlogger.h" + +// +//Class that writes logs events into a binary file + +CEventLogger::CEventLogger(CEventMediatorServer* aServer) +{ + iServer = aServer; + iFileMaxLength = KBYTES_TO_BYTES * LOGFILE_MAX_LTH; +} + +CEventLogger* CEventLogger::NewL(CEventMediatorServer* aServer) + { + CEventLogger* server = new (ELeave) CEventLogger(aServer); + return server; + } + +CEventLogger::CEventLogger(TInt aFileMaxLength, CEventMediatorServer* aServer) +{ + iServer = aServer; + if ( aFileMaxLength == 0 || aFileMaxLength > LOGFILE_MAX_LTH ) + iFileMaxLength = KBYTES_TO_BYTES * LOGFILE_MAX_LTH; + else iFileMaxLength = KBYTES_TO_BYTES * aFileMaxLength; +} + +CEventLogger::~CEventLogger() +{ +} + + + +void CEventLogger::LogEvent(const TDesC8& aEvent) +{ + TInt position; + TInt log_elem_lth; + TBuf8 file_hdr; + +/*------------------------------------------------------------------- + * Log an event into the binary file. File format: + * 0 3 7 CL + * +--------------------+--------------------+---------------------+ + * ! File Id (FI)! Current length (CL)! Wrapping offset (WO)! + * +--------------------+--------------------+---------------------+ + * + * +-----------------------+ + * ! Curr event number (EN) + * +-----------------------+ + * where; + * + * FI = File Id 0x474f4c45 = ELOG + * CL = Current free position in file (=offset value) + * WO = Wrapping offset + * EN = Event number; events are numbered starting from 1 + * Number of the last event to be logged + * + * Log event data format: + * + * Log event data format: + * 0 3 7 15 19 + * +-----------+----------+------------+------------------+----------------+ + * ! Length(L) ! Event ! TimeStamp) ! Source ! Catogory (EC)) ! + * ! ! number(EN) (TS) ! Component (SC) ! + * +-----------+----------+------------+------------------+----------------+ - - - - + + * 23 27 31 n n+12 + * +-----------+----------+------------+------------------+ + * ! MsgId ! Descriptor Descriptors! Trailer (TR) ! + * ! (MI) ! count (DC) (DE) ! ! + * +-----------+----------+------------+------------------+ + * * where; + * + * L = Length of log element + * EN = Event number + * TS = Time stamp (TTime in TInt64 (two TUint32) + * SC = UID of source component + * EC = Event catogory (Info, warning, error, debug) + * MI = Message Id, defines a text string in localisation file + * DC = Descriptor count, number of lth-data pairs + * DE = Descriptors: lth,lth...,data,data,... These are used to modify + * the text avaibale in localisation file + * TR = Element trailer: endmark1, endmark2, length of log element + * same value as in (L) + * + *---------------------------------------------------------------------*/ + if ( OpenLogFile() ) + { + file_hdr.SetLength(EVENTLOG_FILE_HEADER_LTH); + if ( GetFileHeader(file_hdr) ) { + position = GetElemDataPosition(file_hdr, aEvent.Length()); + if ( position ) { + log_elem_lth = WriteLogElem(position, aEvent); + if ( log_elem_lth ) { + position += log_elem_lth; + SaveFileHeader(position, file_hdr); + } + } + } + + CloseLogFile(); + } + +} + +TBool CEventLogger::OpenLogFile() +{ + TBool file_created = EFalse; + TInt position = 0; +/*-------------------------------------------------------- + * Open event log file + *--------------------------------------------------------*/ + if(iFS.Connect()!=KErrNone) + return EFalse; + if ( iLogFile.Create(iFS, iServer->EventLogFileName(), EFileWrite|EFileShareAny) != KErrNone ) + { + if (iLogFile.Open(iFS, iServer->EventLogFileName(), EFileWrite|EFileShareAny) != KErrNone) + { +// DEB(iEngine->PrintText(_L("Error opening Trace file\n"));) + iFS.Close(); + return EFalse; + } + } + else file_created = ETrue; + + if ( file_created ) { + /*-------------------------------------------------------- + * Write file header initial values to created file + * (Current_offset = First_elem_offset = 16) + *--------------------------------------------------------*/ + TBuf8 file_hdr; + file_hdr.SetLength(EVENTLOG_FILE_HEADER_LTH); + StoreFileHeaderInfo(EVENTLOG_FILE_HEADER_LTH, 0, file_hdr); + if ( SaveFileHeader(EVENTLOG_FILE_HEADER_LTH, file_hdr) == EFalse ) { +// DEB(iEngine->PrintText(_L("File header creation error\n"));) + return EFalse; + } + iLogFile.Seek(ESeekStart, position); // return file pointer to file start + } + + return ETrue; +} + +void CEventLogger::CloseLogFile() +{ +/*-------------------------------------------------------- + * Close event log file + *--------------------------------------------------------*/ + iLogFile.Close(); + iFS.Close(); +} + +TBool CEventLogger::GetFileHeader(TDes8 &aBuf) +{ +/*-------------------------------------------------------- + * Read current log file length from file start + *--------------------------------------------------------*/ + if ( iLogFile.Read(aBuf, EVENTLOG_FILE_HEADER_LTH) ) { + return EFalse; + } + + return ETrue; +} + + +TInt CEventLogger::GetElemDataPosition(TDes8 &aFileHdr, TInt aLength) +{ + TInt position; +/*--------------------------------------------------------------- + * Get log element position value from file header + * If (position + aLength) > file max length, wrap file + *---------------------------------------------------------------*/ + TFileHeader *file_hdr = (TFileHeader *)aFileHdr.Ptr(); + position = file_hdr->GetPosition(); + if ( ( position + aLength + + ELEM_HEADER_LTH + ELEM_TRAILER_LTH ) > iFileMaxLength ) + { + position = EVENTLOG_FILE_HEADER_LTH; // Wrapping occurs + } + iEventNumber = file_hdr->GetEventNumber() + 1; + + return position; +} + +/* +TUint32 CEventLogger::GetTimeStamp() +{ +TTime tmp_time; +TDateTime date; +TUint32 time_stamp = 0; +*/ +/*--------------------------------------------------------------- + * Get time stamp for log element. + * Map the year-month-day-hour-minutes-seconds information to + * 32 bits into the following way: + * 3 2 1 0 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * Y Y Y Y M M M M D D D D D D H H H H H H M M M M M M S S S S S S + * where; + * Bits 31-28 = Current Year - 2000 (0-15) + * Bits 27-24 = Current Month index (0-11)) + * Bits 23-18 = Current Day (1-31) + * Bits 17-12 = Current Hour (0-23) + * Bits 11-7 = Current Minutes (0-59) + * Bits 6-0 = Current Seconds (0-59) + * + *--------------------------------------------------------------- / + tmp_time.HomeTime(); + date = tmp_time.DateTime(); + + time_stamp |= (((TUint32)(date.Year() - 2000)) << 28); + time_stamp |= ((TUint32)date.Month() << 24); + time_stamp |= ((TUint32)date.Day() << 18); + time_stamp |= ((TUint32)date.Hour() << 12); + time_stamp |= ((TUint32)date.Minute() << 6); + time_stamp |= (TUint32)date.Second(); + + return time_stamp; +} +*/ + +TBool CEventLogger::SaveFileHeader(TInt aPosition, TDes8 &aBuf) +{ + TInt old_position; + TInt wrapping_offset; +/*--------------------------------------------------------------- + * Save event log element position value to file header + * If current position < position in file header, file has wrapped. + * Store then wrapping offset in file header, too + *---------------------------------------------------------------*/ + TFileHeader *file_hdr = (TFileHeader *)aBuf.Ptr(); + old_position = file_hdr->GetPosition(); + wrapping_offset = file_hdr->GetWrappingOffset(); + if ( old_position > aPosition ) { + wrapping_offset = old_position; /* wrapping occurred */ + } + else { + if ( wrapping_offset && ( wrapping_offset < aPosition ) ) { + wrapping_offset = 0; + } + } + + StoreFileHeaderInfo(aPosition, wrapping_offset, aBuf); + + old_position = 0; // not old position really, just integer with value 0 needed + iLogFile.Seek(ESeekStart, old_position); // return file pointer to file start + if ( iLogFile.Write(aBuf, EVENTLOG_FILE_HEADER_LTH) ) + return EFalse; + + return ETrue; +} + + +void CEventLogger::StoreFileHeaderInfo(TInt aPosition, TInt aWrappingOffset, TDes8 &aBuf) +{ + + TFileHeader *file_hdr = (TFileHeader *)aBuf.Ptr(); + file_hdr->SetFileId(); + file_hdr->SetPosition(aPosition); + file_hdr->SetWrappingOffset(aWrappingOffset); + file_hdr->SetEventNumber(iEventNumber); + +} + +TInt CEventLogger::WriteLogElem(TInt aPosition, const TDesC8& aEvent) + +//TInt CEventLogger::WriteLogElem(TInt aPosition, const TLogEvent& aEvent, const TDesC8& aData) +{ + TBuf8 header; + TBuf8 trailer; +// TUint32 time_stamp; + TInt data_lth=aEvent.Length(); + TInt eventLength = data_lth + ELEM_HEADER_LTH + ELEM_TRAILER_LTH; +/*--------------------------------------------------------------- + * Write log event data into the log file + * Build first log element header: + * log elem length + iEventNumber + time stamp + *---------------------------------------------------------------*/ +// time_stamp = GetTimeStamp(); + header.SetLength(ELEM_HEADER_LTH); + + TElemHeader *elem_hdr = (TElemHeader *)header.Ptr(); + elem_hdr->SetEventLength((TUint32) eventLength); + elem_hdr->SetEventNumber((TUint32) iEventNumber); + + TTime tmpTime; + const TInt64* currTime; + tmpTime.HomeTime(); + currTime = &tmpTime.Int64(); + elem_hdr->SetTime(*currTime); + + trailer.SetLength(ELEM_TRAILER_LTH); + TElemTrailer *elem_trailer = (TElemTrailer *)trailer.Ptr(); + elem_trailer->SetLogEndMark(); + elem_trailer->SetEventLength((TUint32) eventLength); + iLogFile.Seek(ESeekStart, aPosition); // Set file pointer +/*--------------------------------------------------------------- + * Write log event into log element + *---------------------------------------------------------------*/ + if ( iLogFile.Write(header) ) //Element header + return 0; + + if ( iLogFile.Write(aEvent)) //log event data + return 0; + + if ( iLogFile.Write(trailer) ) //Element trailer + return 0; + + return eventLength; + +} + diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediator/src/eventmediator.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediator/src/eventmediator.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,1354 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This module contains eventmediator and the services of it. +* +*/ + + + +/** + * @file eventmediator.cpp + * + * This module contains eventmediator and the services of it. + * + */ +#include +#include "eventmediator.h" +#include "eventlogger.h" +#include "eventmediatordefs.h" +#include "sit.h" +#include "log_em.h" + +#define FIRST_ARGUMENT 0 +#define SECOND_ARGUMENT 1 +#define THIRD_ARGUMENT 2 +#define FOURTH_ARGUMENT 3 + +// ============================= CEventMediatorServer ============================= + +const TUint CEventMediatorServer::iRangeCount = 2; + +const TInt CEventMediatorServer::iRanges[iRangeCount] = + { + CEventMediatorSession::KEventMediatorListen, + CEventMediatorSession::KEventMediatorClearEventLog+1 + }; + +const TUint8 CEventMediatorServer::iElementIndex[iRangeCount] = + { + 0, + CPolicyServer::ENotSupported + }; + +const CPolicyServer::TPolicyElement CEventMediatorServer::iElements[] = + { + {_INIT_SECURITY_POLICY_C1(ECapabilityNetworkControl), CPolicyServer::EFailClient}, + }; + +const CPolicyServer::TPolicy CEventMediatorServer::iPolicy = + { + 0, // All connect attempts are checked + iRangeCount, // Count of ranges + iRanges, // 0...9, 9... + iElementIndex, // Only range 1000-1008 are checked + iElements // The list of policy elements + }; + + +CEventMediatorServer::CEventMediatorServer(void) + : CPolicyServer(EPriorityNormal,iPolicy), iStoredEvents(1) + { + } + +CEventMediatorServer* CEventMediatorServer::NewL() + { + LOG(Log::Printf(_L("CEventMediatorServer::NewL - begin\n"))); + CEventMediatorServer* server = CEventMediatorServer::NewLC(); + CleanupStack::Pop(); // server + LOG(Log::Printf(_L("CEventMediatorServer::NewL - end\n"))); + return server; + } + +CEventMediatorServer* CEventMediatorServer::NewLC() + { + LOG(Log::Printf(_L("CEventMediatorServer::NewLC - begin\n"))); + CEventMediatorServer* server = new (ELeave) CEventMediatorServer(); + CleanupStack::PushL(server); + server->ConstructL(server); + LOG(Log::Printf(_L("CEventMediatorServer::NewLC - end\n"))); + return server; + } + +void CEventMediatorServer::ConstructL(CEventMediatorServer* aServer) + { + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + + fs.CreatePrivatePath(EDriveC); + + TPath privateDir; + User::LeaveIfError(fs.PrivatePath(privateDir)); + iEventLogFileName.Copy(privateDir); + iEventLogFileName.Append(KEventLogFile); + + CleanupStack::PopAndDestroy(); // fs + + aServer->iLogger = CEventLogger::NewL(this); + iSit = new (ELeave) CSit(this); + StartL(KEventMediatorServer); + } + +CEventMediatorServer::~CEventMediatorServer(void) + { + LOG(Log::Printf(_L("CEventMediatorServer::~CEventMediatorServer\n"))); + // Delete stored events + TInt nEvents = this->iStoredEvents.Count(); + for (TInt i = 0; i < nEvents; i++) + { + delete iStoredEvents.At(i)->iData; + delete iStoredEvents.At(i); + } + iStoredEvents.Delete(0, iStoredEvents.Count()); + + // Delete log writer + delete iLogger; + + delete iSit; + } + +// ---------------------------------------------------------------------------- +// CEventMediatorServer::StopEventMediator +// Stops Event Mediator service if there are no sessions left. +// ---------------------------------------------------------------------------- +// +void CEventMediatorServer::StopEventMediator(void) + { + if (iSessionCount == 0) + { + LOG(Log::Printf(_L("CEventMediatorServer::StopEventMediator - session count 0, stopping scheduler and thus the server\n"))); + CActiveScheduler::Stop(); + } + } + +TInt CEventMediatorServer::RunError(TInt aError) + { + LOG(Log::Printf(_L("CEventMediatorServer::RunError - error = %d\n"), aError)); + Message().Complete(aError); + + // The leave will result in an early return from CServer::RunL(), + // skipping the call to request another message. So we issue the + // request here in order to keep the server running. + ReStart(); + + // Handled the error fully + return KErrNone; + } + +// ---------------------------------------------------------------------------- +// CEventMediatorServer::NewSessionL +// Creates a new session and returns the handle to the session. +// ---------------------------------------------------------------------------- +// +CSession2* CEventMediatorServer::NewSessionL( + const TVersion& /*aVersion*/, + const RMessage2& aMessage) const + { + // New sessions are not accepted if the server is shutting down + // (it's just waiting for the last session (from SIT) to die) + if (iShuttingDown) + { + User::Leave(KErrServerTerminated); + } + + CSession2* session = CEventMediatorSession::NewL(CONST_CAST(CEventMediatorServer*, this), aMessage); + return session; + } + +void CEventMediatorServer::ReportEventL(const TEventType aType, TDesC8* aSpec, + TDesC8* aData, TInt aStatus) + { + LOG(Log::Printf(_L("CEventMediatorServer::ReportEventL - event type = %d\n"), aType)); + TInt listenerCount = 0; + CEventMediatorSession* session; + iSessionIter.SetToFirst(); + session = (CEventMediatorSession*) iSessionIter++; + + while (session != NULL) + { + // Some listeners listen this event with specification + listenerCount += session->CheckEventL(aType, aSpec, aData, aStatus); + // Some without specification, all events are good for them + if (aSpec != NULL) + { + listenerCount += session->CheckEventL(aType, NULL, aData, aStatus); + } + session = (CEventMediatorSession*) iSessionIter++; + } + if (listenerCount) + { + // Need to save the event data as it may/will be fetched later + TEventContainer* container = new (ELeave) TEventContainer(listenerCount, aData); + CleanupStack::PushL(container); + iStoredEvents.AppendL(container); + CleanupStack::Pop(); + } + // Write event to log + if (aType == ELogEvent && iLogger) + { + LOG(Log::Printf(_L("CEventMediatorServer::ReportEventL - calling iLogger->LogEvent\n"))); + iLogger->LogEvent(*aData); + } + + // If there are no listeners, delete data + if (listenerCount == 0) + { + delete aData; + } + } + +TInt CEventMediatorServer::CopyEventDataL(const RMessage2& aMessage) + { + TBool found = EFalse; + TInt i = 0; + TInt err = KErrNone; + while (!found && i < iStoredEvents.Count()) + { + if (iStoredEvents.At(i)->iData == aMessage.Ptr0()) + { + found = ETrue; + } + else + { + i++; + } + } + if (found) + { + aMessage.WriteL(SECOND_ARGUMENT, *(iStoredEvents.At(i)->iData)); + MarkStoredEventListened(i); + } + else + { + err = KErrNotFound; + } + return err; + } + +void CEventMediatorServer::MarkStoredEventListened(TInt aIndex) + { + iStoredEvents.At(aIndex)->iListenerCount--; + if (iStoredEvents.At(aIndex)->iListenerCount == 0) + { + delete iStoredEvents.At(aIndex)->iData; + delete iStoredEvents.At(aIndex); + iStoredEvents.Delete(aIndex); + } + } + +TBool CEventMediatorServer::IsClientTheSitL(const RMessage2& aMessage) + { + LOG(Log::Printf(_L("CEventMediatorServer::IsClientTheSitL\n"))); + TBool isClientTheSit = EFalse; + + RThread clientThread; + User::LeaveIfError(aMessage.Client(clientThread)); + + if (clientThread.Id() == iSit->ThreadId()) + { + LOG(Log::Printf(_L("CEventMediatorServer::IsClientTheSitL - YES\n"))); + isClientTheSit = ETrue; + } + + clientThread.Close(); + + return isClientTheSit; + } + +void CEventMediatorServer::MakeSureSitIsRunningL() + { + LOG(Log::Printf(_L("CEventMediatorServer::MakeSureSitIsRunningL\n"))); + // If the SIT has not yet been started + // or has died, try to start it + iSit->StartL(); + } + +void CEventMediatorServer::SetTaskArrivalListenerL(CListenerContainer* aListener) + { + LOG(Log::Printf(_L("CEventMediatorServer::SetTaskArrivalListenerL\n"))); + if (aListener) + { + // Task arrival observation requests must + // come from the SIT + if (!IsClientTheSitL(aListener->Message())) + { + User::Leave(KErrNotSupported); + } + + // Only one task arrival observation request + // is allowed to be present at the same time + if (iTaskArrivalListener && (aListener != iTaskArrivalListener)) + { + User::Leave(KErrNotSupported); + } + } + + iTaskArrivalListener = aListener; + } + +void CEventMediatorServer::ClearTaskArrivalListener() + { + LOG(Log::Printf(_L("CEventMediatorServer::ClearTaskArrivalListener\n"))); + iTaskArrivalListener = NULL; + } + +CListenerContainer* CEventMediatorServer::TaskArrivalListener() + { + return iTaskArrivalListener; + } + +void CEventMediatorServer::TaskRequestArrivedL(CListenerContainer* aTaskRequest) + { + LOG(Log::Printf(_L("CEventMediatorServer::TaskRequestArrivedL\n"))); + CompleteTaskArrivalObservationRequestL(aTaskRequest->Type(), aTaskRequest->Specification()); + } + +void CEventMediatorServer::TaskArrivalObservationRequestArrivedL() + { + LOG(Log::Printf(_L("CEventMediatorServer::TaskArrivalObservationRequestArrivedL\n"))); + // Go through all pending event listening requests to see if any + // one of those should be passed to the SIT (i.e. if the task + // arrival observation request should be completed immediately) + + CListenerContainer* taskRequest = FindWaitingTaskRequest(); + + if (taskRequest) + { + CompleteTaskArrivalObservationRequestL(taskRequest->Type(), taskRequest->Specification()); + } + } + +void CEventMediatorServer::TaskRequestEventSpecFetchingRequestArrivedL(CListenerContainer* aFetchingRequest) + { + LOG(Log::Printf(_L("CEventMediatorServer::TaskRequestEventSpecFetchingRequestArrivedL\n"))); + TFetchTaskInfoEventSpec taskRequestInfo; + TPckg taskRequestInfoDes(taskRequestInfo); + taskRequestInfoDes.Copy(*(aFetchingRequest->Specification())); + + // Find the task request whose event specification + // we should return to the SIT TH + CListenerContainer* taskRequest = FindListener(taskRequestInfo.iEventType, taskRequestInfo.iEventSpecId); + + if (taskRequest && !taskRequest->BeingFulfilled()) + { + CompleteTaskRequestEventSpecFetchingRequestL(KErrNone, aFetchingRequest->Specification(), + taskRequest->Specification()); + taskRequest->MarkAsBeingFulfilled(); + } + else + { + CompleteTaskRequestEventSpecFetchingRequestL(KErrNotFound, aFetchingRequest->Specification(), NULL); + } + } + +void CEventMediatorServer::TaskCancellationObservationRequestArrivedL(CListenerContainer* aRequest) + { + LOG(Log::Printf(_L("CEventMediatorServer::TaskCancellationObservationRequestArrivedL\n"))); + // Try to find a task request event type that corresponds to the received + // event type. This will only succeed if the received event type is + // one that is used to listen to the cancellation of a task request. + TEventType taskRequestEventType = CSit::FindTaskRequestEventType(aRequest->Type()); + + // If a corresponding task request type was found... + if (taskRequestEventType != EUnfoundEvent) + { + // Try to find the listener container of the task request + CListenerContainer* taskRequest = FindListener(taskRequestEventType, aRequest->Specification()); + + // The listener container for the task request was not found + // (i.e. the task request has been cancelled or the + // corresponding client session has been closed), so we + // complete the cancellation observation request right away + if (taskRequest == NULL) + { + ReportEventL(aRequest->Type(), aRequest->Specification(), NULL); + } + } + } + +void CEventMediatorServer::CompleteTaskArrivalObservationRequestL(TEventType aEventType, TDesC8* aSpec) + { + LOG(Log::Printf(_L("CEventMediatorServer::CompleteTaskArrivalObservationRequestL\n"))); + if (iTaskArrivalListener) + { + // In SIT events, the event specification + // begins with the event specification ID + TEventSpec* sitEventSpec = (TEventSpec*)(aSpec->Ptr()); + + TTaskArrivedEventData eventData; + eventData.iEventType = aEventType; + eventData.iEventSpecId = sitEventSpec->iId; + TPckg eventDataDes(eventData); + + HBufC8* eventDataCopy = eventDataDes.AllocL(); + CleanupStack::PushL(eventDataCopy); + + ReportEventL(ETaskArrivedEvent, NULL, eventDataCopy); + + CleanupStack::Pop(); // eventDataCopy, freed elsewhere + } + } + +void CEventMediatorServer::CompleteTaskRequestEventSpecFetchingRequestL(TInt aStatus, TDesC8* aEventSpec, + TDesC8* aTaskRequestEventSpec) + { + LOG(Log::Printf(_L("CEventMediatorServer::CompleteTaskRequestEventSpecFetchingRequestL\n"))); + // The event specification of the task request + // is returned to the SIT TH as event data + if (aTaskRequestEventSpec) + { + HBufC8* eventData = aTaskRequestEventSpec->AllocL(); + CleanupStack::PushL(eventData); + + ReportEventL(EFetchTaskInfoEvent, aEventSpec, eventData, aStatus); + + CleanupStack::Pop(); // eventData, freed elsewhere + } + else + { + ReportEventL(EFetchTaskInfoEvent, aEventSpec, NULL, aStatus); + } + } + +CListenerContainer* CEventMediatorServer::FindWaitingTaskRequest() + { + CEventMediatorSession* session; + iSessionIter.SetToFirst(); + session = (CEventMediatorSession*) iSessionIter++; + + CListenerContainer* listener = NULL; + + while (session != NULL) + { + listener = session->FindWaitingTaskRequest(); + if (listener != NULL) + { + break; + } + session = (CEventMediatorSession*) iSessionIter++; + } + + return listener; + } + +CListenerContainer* CEventMediatorServer::FindListener(TEventType aEventType, + TInt aEventSpecId) + { + CEventMediatorSession* session; + iSessionIter.SetToFirst(); + session = (CEventMediatorSession*) iSessionIter++; + + CListenerContainer* listener = NULL; + + while (session != NULL) + { + listener = session->FindListener(aEventType, aEventSpecId); + if (listener != NULL) + { + break; + } + session = (CEventMediatorSession*) iSessionIter++; + } + + return listener; + } + +CListenerContainer* CEventMediatorServer::FindListener(TEventType aEventType, + const TDesC8* aEventSpec) + { + CEventMediatorSession* session; + iSessionIter.SetToFirst(); + session = (CEventMediatorSession*) iSessionIter++; + + CListenerContainer* listener = NULL; + + while (session != NULL) + { + listener = session->FindListener(aEventType, aEventSpec); + if (listener != NULL) + { + break; + } + session = (CEventMediatorSession*) iSessionIter++; + } + + return listener; + } + +void CEventMediatorServer::CompleteListener(TEventType aEventType, const TDesC8* aEventSpec, TInt aStatus) + { + CEventMediatorSession* session; + iSessionIter.SetToFirst(); + session = (CEventMediatorSession*) iSessionIter++; + + while (session != NULL) + { + session->CompleteListener(aEventType, aEventSpec, aStatus); + session = (CEventMediatorSession*) iSessionIter++; + } + } + +TInt CEventMediatorServer::NormalSessionCount() + { + TInt normalSessionCount = 0; + + CEventMediatorSession* session; + iSessionIter.SetToFirst(); + session = (CEventMediatorSession*) iSessionIter++; + + while (session != NULL) + { + if (!(session->IsASitSession())) + { + normalSessionCount++; + } + session = (CEventMediatorSession*) iSessionIter++; + } + + return normalSessionCount; + } + +TInt CEventMediatorServer::NewEventSpecId() + { + return ++iNextEventSpecId; + } + +TPtrC CEventMediatorServer::EventLogFileName(void) + { + TPtrC name(iEventLogFileName); + return name; + } + +void CEventMediatorServer::SitDied() + { + LOG(Log::Printf(_L("CEventMediatorServer::SitDied\n"))); + CompleteTaskRequests(KErrDied); + } + +void CEventMediatorServer::CompleteTaskRequests(TInt aStatus) + { + LOG(Log::Printf(_L("CEventMediatorServer::CompleteTaskRequests\n"))); + CEventMediatorSession* session; + iSessionIter.SetToFirst(); + session = (CEventMediatorSession*) iSessionIter++; + + while (session != NULL) + { + session->CompleteTaskRequests(aStatus); + session = (CEventMediatorSession*) iSessionIter++; + } + } + +void CEventMediatorServer::SetShuttingDown(TBool aShuttingDown) + { + iShuttingDown = aShuttingDown; + } + +// ============================= CEventMediatorSession ============================= + +CEventMediatorSession* CEventMediatorSession::NewL(CEventMediatorServer* aServer, const RMessage2& aMessage) + { + LOG(Log::Printf(_L("CEventMediatorSession::NewL - begin\n"))); + CEventMediatorSession* self; + self = new (ELeave) CEventMediatorSession(aServer); + CleanupStack::PushL(self); + + // Marks the session as a "SIT session" + // if the client is the SIT thread + self->iIsSitSession = aServer->IsClientTheSitL(aMessage); + + aServer->iSessionCount++; + + if ( !self->IsASitSession() ) + { + User::LeaveIfError(self->iFs.Connect()); // For EventLog + self->iEventLogFileOpen = EFalse; + } + + CleanupStack::Pop(); // self + + LOG(Log::Printf(_L("CEventMediatorSession::NewL - end\n"))); + return self; + } + +CEventMediatorSession::CEventMediatorSession(CEventMediatorServer* aServer) + : iListenedEvents(2), iServer(aServer) + { + } + +CEventMediatorSession::~CEventMediatorSession(void) + { + LOG(Log::Printf(_L("CEventMediatorSession::~CEventMediatorSession\n"))); + CancelAll(); + if (iServer) + { + TInt normalSessionCount = iServer->NormalSessionCount(); + + // If this too is a normal session and is dying, + // decrement the normal session count by one + if (!IsASitSession()) + { + normalSessionCount--; + + if (iEventLogFileOpen) + { + iEventLogFile.Close(); + iEventLogFileOpen = EFalse; + } + iFs.Close(); // For EventLog + + } + + if (normalSessionCount == 0) + { + // If "normal" (non-sit) sessions are no longer present, + // we complete the task arrival observation request, thus + // causing the SIT to terminate and close its connection + // to this server. This should be the last connection whose + // closing will cause this server to terminate. + // NOTE. KErrCancel cannot be used here as the Event Mediator + // does not report it to the caller + LOG(Log::Printf(_L("CEventMediatorSession::~CEventMediatorSession - normal session count = 0\n"))); + iServer->CompleteListener(ETaskArrivedEvent, NULL, KErrAbort); + + // Set the server state to "shutting down". This will + // cause the server to discard any new connect requests + // with KErrServerTerminated. + iServer->SetShuttingDown(ETrue); + } + + if (iServer->iSessionCount) + { + iServer->iSessionCount--; + } + + iServer->StopEventMediator(); + } + } + +void CEventMediatorSession::ServiceL(const RMessage2& aMessage) + { + TInt status = 0; + + switch (aMessage.Function()) + { + case KEventMediatorListen: + ListenToEventL(aMessage); + break; + + case KEventMediatorListenWithSpec: + ListenToEventWithSpecL(aMessage); + break; + + case KEventMediatorCancel: + CancelListening(aMessage); + aMessage.Complete(KErrNone); + break; + + case KEventMediatorCancelWithSpec: + CancelListeningWithSpecL(aMessage); + aMessage.Complete(KErrNone); + break; + + case KEventMediatorCancelAll: + CancelAll(); + aMessage.Complete(KErrNone); + break; + + case KEventMediatorReportEvent: + ReportEventL(aMessage); + aMessage.Complete(KErrNone); + break; + + case KEventMediatorReportEventWithSpec: + ReportEventWithSpecL(aMessage); + aMessage.Complete(KErrNone); + break; + + case KEventMediatorFetchData: + status = FetchDataL(aMessage); + aMessage.Complete(status); + break; + + case KEventMediatorReportLogEvent: + ReportLogEventL(aMessage); + aMessage.Complete(KErrNone); + break; + + case KEventMediatorNewEventSpecId: + NewEventSpecIdL(aMessage); + aMessage.Complete(KErrNone); + break; + case KEventMediatorDeletePrivateFiles: + status = DeletePrivateFiles(); + aMessage.Complete(status); + break; + + case KEventMediatorGetEventLogSize: + status = GetEventLogSize(aMessage); + aMessage.Complete(status); + break; + + case KEventMediatorGetEventLogHeader: + status = GetEventLogHeader(aMessage); + aMessage.Complete(status); + break; + case KEventMediatorGetEventLogData: + status = GetEventLogData(aMessage); + aMessage.Complete(status); + break; + case KEventMediatorClearEventLog: + status = ClearEventLog(); + aMessage.Complete(status); + break; + default: + aMessage.Complete(KErrGeneral); + break; + } + } + +TInt CEventMediatorSession::ListenToEventL(const RMessage2& aMessage) + { + CListenerContainer* listener = new (ELeave) CListenerContainer(aMessage, NULL, iServer); + CleanupStack::PushL(listener); + + iListenedEvents.AppendL(listener); + CleanupStack::Pop(); // listener + + listener->AnalyzeRequestL(); + + return KErrNone; + } + +TInt CEventMediatorSession::ListenToEventWithSpecL(const RMessage2& aMessage) + { + HBufC8* specBuf = NULL; + + // Read specification + specBuf = ReadSpecificationFromClientL(aMessage); + CleanupStack::PushL(specBuf); + + // Ownership of specBuf is given to listener + CListenerContainer* listener = new (ELeave) CListenerContainer(aMessage, specBuf, iServer); + CleanupStack::Pop(); // specBuf + CleanupStack::PushL(listener); + + iListenedEvents.AppendL(listener); + CleanupStack::Pop(); // listener + + listener->AnalyzeRequestL(); + + return KErrNone; + } + +void CEventMediatorSession::CancelListening(const RMessage2& aMessage) + { + TInt index; + + while (FindListenerMsg((TEventType)aMessage.Int0(), index)) + { + CompleteListener(index, KErrCancel); + } + } + +void CEventMediatorSession::CancelListeningWithSpecL(const RMessage2& aMessage) + { + HBufC8* specBuf = NULL; + TInt index; + + // Read specification + specBuf = ReadSpecificationFromClientL(aMessage); + CleanupStack::PushL(specBuf); + + // Cancel listeners + while (FindListenerMsg((TEventType)aMessage.Int0(), specBuf, index)) + { + CompleteListener(index, KErrCancel); + } + CleanupStack::PopAndDestroy(); // specBuf + } + +void CEventMediatorSession::CancelAll() + { + TInt nEvents = iListenedEvents.Count(); + for (TInt i = 0; i < nEvents; i++) + { + iListenedEvents.At(i)->Complete(KErrCancel); + delete iListenedEvents.At(i); + iListenedEvents.At(i) = NULL; + } + iListenedEvents.Reset(); + } + +void CEventMediatorSession::ReportEventL(const RMessage2& aMessage) + { + TEventType eventType = (TEventType)aMessage.Int0(); + LOG(Log::Printf(_L("CEventMediatorSession::ReportEventL - event type = %d\n"), eventType)); + // Read data + HBufC8* dataBuf = ReadEventDataFromClientL(aMessage); + CleanupStack::PushL(dataBuf); + // Report event to server + iServer->ReportEventL(eventType, NULL, dataBuf); + CleanupStack::Pop(); + } + +void CEventMediatorSession::ReportEventWithSpecL(const RMessage2& aMessage) + { + TEventType eventType=(TEventType) aMessage.Int0(); + LOG(Log::Printf(_L("CEventMediatorSession::ReportEventWithSpecL - event type = %d\n"), eventType)); + // Read data + HBufC8* dataBuf = ReadEventDataFromClientL(aMessage); + CleanupStack::PushL(dataBuf); + // Read specification + HBufC8* specBuf = ReadSpecificationFromClientL(aMessage); + CleanupStack::PushL(specBuf); + // Report event to server + iServer->ReportEventL(eventType, specBuf, dataBuf); + CleanupStack::PopAndDestroy(); // specBuf + CleanupStack::Pop(); // dataBuf + } + +void CEventMediatorSession::ReportLogEventL(const RMessage2& aMessage) + { + LOG(Log::Printf(_L("CEventMediatorSession::ReportLogEventL\n"))); + // Read event + TLogEvent event; + TPckg eventPckg(event); + aMessage.ReadL(FIRST_ARGUMENT, eventPckg); + + // Create one buffer to contain put everything in a normal buffer and + TInt lengthsDesLth = event.iDesCount * sizeof(TInt); + TInt position = eventPckg.Length(); + TInt dataLength = position + lengthsDesLth + aMessage.Int2(); + HBufC8* dataBuf = HBufC8::NewLC(dataLength); + TPtr8 dataPtr = dataBuf->Des(); + + // Copy event to buffer + dataPtr.Append(eventPckg); + // Read lengths to buffer + TPtr8 tmpPtr(&dataPtr[position], 0, dataLength - position); + aMessage.ReadL(SECOND_ARGUMENT, tmpPtr); + // Read descriptors to the buffer + position= dataPtr.Length(); + tmpPtr.Set(&dataPtr[position], 0, dataLength - position); + aMessage.ReadL(THIRD_ARGUMENT, tmpPtr); + + // Report event to server + iServer->ReportEventL(ELogEvent, NULL, dataBuf); + CleanupStack::Pop(); + } + +TInt CEventMediatorSession::FetchDataL(const RMessage2& aMessage) + { + LOG(Log::Printf(_L("CEventMediatorSession::FetchDataL\n"))); + return iServer->CopyEventDataL(aMessage); + } + +TInt CEventMediatorSession::CheckEventL(const TEventType aType, const TDesC8* aSpec, + const TDesC8* aData, TInt aStatus) + { + TInt index; + TInt listenerCount = 0; + TInt dataLth = 0; + // Some events don't not have data + if (aData) + { + dataLth = aData->Length(); + } + TPckg lengthpckg(dataLth); + TPckgC ptrpckg(aData); + + while (FindListenerMsg(aType, aSpec, index)) + { + RMessage2& listener = iListenedEvents.At(index)->Message(); + + if (aStatus == KErrNone) + { + // Write info about data + listener.WriteL(SECOND_ARGUMENT, lengthpckg); + listener.WriteL(THIRD_ARGUMENT, ptrpckg); + + // Complete listener + listener.Complete(KErrNone); + } + else + { + listener.Complete(aStatus); + } + + delete iListenedEvents.At(index); + iListenedEvents.Delete(index); + listenerCount++; + } + + return listenerCount; + } + +TBool CEventMediatorSession::FindListenerMsg(const TEventType aType, TInt& index) + { + for (TInt i = 0; i < iListenedEvents.Count(); i++) + { + if (iListenedEvents.At(i)->Type() == aType) + { + index=i; + return ETrue; + } + } + return EFalse; + } + +TBool CEventMediatorSession::FindListenerMsg(const TEventType aType, const TDesC8* aSpec, TInt& index) + { + for (TInt i = 0; i < iListenedEvents.Count(); i++) + { + if (iListenedEvents.At(i)->HandlesEvent(aType, aSpec)) + { + index = i; + return ETrue; + } + } + return EFalse; + } + +TBool CEventMediatorSession::FindTaskRequestListenerMsg(TInt& index) + { + for (TInt i = 0; i < iListenedEvents.Count(); i++) + { + if (CSit::EventRequiresSit(iListenedEvents.At(i)->Type())) + { + index = i; + return ETrue; + } + } + return EFalse; + } + +HBufC8* CEventMediatorSession::ReadSpecificationFromClientL(const RMessage2& aMessage) + { + HBufC8* specBuf; + // Read specification descriptor length from client, create specification buffer + const TAny* desPtr = aMessage.Ptr3(); + if (desPtr == NULL) + { + return NULL; + } + TInt specLength = aMessage.GetDesLength(FOURTH_ARGUMENT); + // Create spcification buffer + specBuf = HBufC8::NewLC(specLength); + TPtr8 ptr = specBuf->Des(); + // Read specification + aMessage.ReadL(FOURTH_ARGUMENT, ptr); + CleanupStack::Pop(); // specBuf + return specBuf; + } + +HBufC8* CEventMediatorSession::ReadEventDataFromClientL(const RMessage2& aMessage) + { + HBufC8* dataBuf = NULL; + TInt desLength = aMessage.Int1(); + + if (desLength != 0) // Some events have no data + { + dataBuf = HBufC8::NewLC(desLength); + TPtr8 ptr = dataBuf->Des(); + aMessage.ReadL(THIRD_ARGUMENT, ptr); + CleanupStack::Pop(); // dataBuf + } + return dataBuf; + } + +CListenerContainer* CEventMediatorSession::FindWaitingTaskRequest() + { + CListenerContainer* listener = NULL; + + for (TInt i = 0; i < iListenedEvents.Count(); i++) + { + if (iListenedEvents.At(i)->WaitingForFulfilling()) + { + listener = iListenedEvents.At(i); + break; + } + } + + return listener; + } + +CListenerContainer* CEventMediatorSession::FindListener(TEventType aEventType, + TInt aEventSpecId) + { + CListenerContainer* listener = NULL; + + for (TInt i = 0; i < iListenedEvents.Count(); i++) + { + if (iListenedEvents.At(i)->Type() == aEventType) + { + TEventSpec* eventSpec = (TEventSpec*)(iListenedEvents.At(i)->Specification()->Ptr()); + + if (eventSpec->iId == aEventSpecId) + { + listener = iListenedEvents.At(i); + break; + } + } + } + + return listener; + } + +CListenerContainer* CEventMediatorSession::FindListener(TEventType aEventType, + const TDesC8* aEventSpec) + { + CListenerContainer* listener = NULL; + + for (TInt i = 0; i < iListenedEvents.Count(); i++) + { + if (iListenedEvents.At(i)->HandlesEvent(aEventType, aEventSpec)) + { + listener = iListenedEvents.At(i); + break; + } + } + + return listener; + } + +void CEventMediatorSession::CompleteListener(TEventType aEventType, + const TDesC8* aEventSpec, + TInt aStatus) + { + TInt index; + while (FindListenerMsg(aEventType, aEventSpec, index)) + { + CompleteListener(index, aStatus); + } + } + +void CEventMediatorSession::CompleteListener(TInt aIndex, TInt aStatus) + { + iListenedEvents.At(aIndex)->Complete(aStatus); + delete iListenedEvents.At(aIndex); + iListenedEvents.Delete(aIndex); + } + +void CEventMediatorSession::CompleteTaskRequests(TInt aStatus) + { + LOG(Log::Printf(_L("CEventMediatorSession::CompleteTaskRequests\n"))); + TInt index; + while (FindTaskRequestListenerMsg(index)) + { + CompleteListener(index, aStatus); + } + } + +TBool CEventMediatorSession::IsASitSession() + { + return iIsSitSession; + } + +void CEventMediatorSession::NewEventSpecIdL(const RMessage2& aMessage) + { + TInt newEventSpecId = iServer->NewEventSpecId(); + TPckg newEventSpecIdDes(newEventSpecId); + aMessage.WriteL(FIRST_ARGUMENT, newEventSpecIdDes); + } + +TInt CEventMediatorSession::DeletePrivateFiles() + { + TRAPD(err, DeletePrivateFilesL()); + if ( err ) + { + LOG(Log::Printf(_L("DeletePrivateFilesL() leave error %d\n"), err)); + return err; + } + + return KErrNone; + } + +void CEventMediatorSession::DeletePrivateFilesL() + { + LOG(Log::Printf(_L("DeletePrivateFilesL() called\n"))); + + CFileMan* fileMan = CFileMan::NewL(iFs); + CleanupStack::PushL(fileMan); + + TPath privateDir; + User::LeaveIfError(iFs.PrivatePath(privateDir)); + + TInt err = fileMan->RmDir(privateDir); + if (err != KErrNone && err != KErrPathNotFound && err != KErrNotFound) + { + User::Leave(err); + } + CleanupStack::PopAndDestroy(); //fileMan + } + +TInt CEventMediatorSession::GetEventLogSize( + const RMessage2& aMessage) + { + if ( iEventLogFileOpen ) + { + iEventLogFile.Close(); + iEventLogFileOpen = EFalse; + } + + TInt err = iEventLogFile.Open(iFs, iServer->EventLogFileName(), EFileRead | EFileShareAny); + if ( err ) + return err; + + TInt size(0); + err = iEventLogFile.Size(size); + if ( err ) + { + iEventLogFile.Close(); + return err; + } + + TPckg sizePckg(size); + err = aMessage.Write(FIRST_ARGUMENT, sizePckg); + if ( err ) + { + iEventLogFile.Close(); + return err; + } + + iEventLogFileOpen = ETrue; + + return KErrNone; + } + +TInt CEventMediatorSession::GetEventLogHeader( + const RMessage2& aMessage) + { + TInt err(0); + + if ( !iEventLogFileOpen ) + { + err = iEventLogFile.Open(iFs, iServer->EventLogFileName(), EFileRead | EFileShareAny); + if ( err ) + return err; + iEventLogFileOpen = ETrue; + } + + TInt position = 0; + err = iEventLogFile.Seek(ESeekStart, position); + if (err != KErrNone) + return err; + + TBuf8 fileHeaderBuf; + err = iEventLogFile.Read(fileHeaderBuf, EVENTLOG_FILE_HEADER_LTH); + if (err != KErrNone) + return err; + + TRAP(err, aMessage.WriteL(FIRST_ARGUMENT, fileHeaderBuf)); + if ( err ) + return err; + + return KErrNone; + } + +TInt CEventMediatorSession::GetEventLogData( + const RMessage2& aMessage) + { + TInt err(0); + + if ( !iEventLogFileOpen ) + { + err = iEventLogFile.Open(iFs, iServer->EventLogFileName(), EFileRead | EFileShareAny); + if ( err ) + return err; + iEventLogFileOpen = ETrue; + } + + TInt size(0); + err = iEventLogFile.Size(size); + if ( err ) + return err; + + if ( size < EVENTLOG_FILE_HEADER_LTH ) + return KErrNotFound; + + HBufC8* eventLogFileBuf = NULL; + TRAP(err, eventLogFileBuf = HBufC8::NewL(size)); + if ( err ) + { + return err; + } + + TPtr8 eventLogDataPtr(eventLogFileBuf->Des()); + TInt position(0); + err = iEventLogFile.Seek(ESeekStart, position); + if ( err ) + { + delete eventLogFileBuf; + return err; + } + err = iEventLogFile.Read(eventLogDataPtr); // iLogFileSize); + if ( err ) + { + delete eventLogFileBuf; + return err; + } + + TRAP( err, aMessage.WriteL(FIRST_ARGUMENT, eventLogDataPtr)); + if ( err ) + { + delete eventLogFileBuf; + return err; + } + + delete eventLogFileBuf; + eventLogFileBuf = NULL; + + return KErrNone; + } + +TInt CEventMediatorSession::ClearEventLog() + { + if ( iEventLogFileOpen ) + { + iEventLogFile.Close(); + iEventLogFileOpen = EFalse; + } + + TInt err = iFs.Delete(iServer->EventLogFileName()); + + return err; + } + + + +// ============================= CEventMediatorServer ============================= + +CListenerContainer::CListenerContainer(const RMessage2& aMessage, TDesC8* aSpec, + CEventMediatorServer* aServer) + : iSpec(aSpec), iMessage(aMessage), iServer(aServer) + { + iEventType = Type(); + } + +void CListenerContainer::AnalyzeRequestL() + { + LOG(Log::Printf(_L("CListenerContainer::AnalyzeRequestL\n"))); + if (CSit::EventRequiresSit(iEventType)) + { + LOG(Log::Printf(_L("CListenerContainer::AnalyzeRequestL - event type = %d, requires SIT\n"), iEventType)); + iServer->MakeSureSitIsRunningL(); + iServer->TaskRequestArrivedL(this); + } + + // If this event listening request is the one + // made by the SIT task arrival observer... + if (iEventType == ETaskArrivedEvent) + { + iServer->SetTaskArrivalListenerL(this); + iServer->TaskArrivalObservationRequestArrivedL(); + } + + // If this event listening request is one + // made by a SIT TH to fetch a task... + if (iEventType == EFetchTaskInfoEvent) + { + iServer->TaskRequestEventSpecFetchingRequestArrivedL(this); + } + + // If the event listening request is one + // made by a SIT TH to listen to the cancellation + // of the task request it is handling + if (CSit::IsTaskCancellationObservationRequest(iEventType)) + { + iServer->TaskCancellationObservationRequestArrivedL(this); + } + } + +CListenerContainer::~CListenerContainer() + { + delete iSpec; + + if (iServer->TaskArrivalListener() == this) + { + iServer->ClearTaskArrivalListener(); + } + } + +TBool CListenerContainer::HandlesEvent(TEventType aEventType, const TDesC8* aEventSpec) + { + if (iEventType == aEventType) + { + // Specs are same if both are NULL + if (iSpec == NULL && aEventSpec == NULL) + { + return ETrue; + } + // or data in buffers are identical + else if (iSpec != NULL && aEventSpec != NULL && (*iSpec) == (*aEventSpec)) + { + return ETrue; + } + } + return EFalse; + } + +void CListenerContainer::Complete(TInt status) + { + // If there's a SIT fulfilling this event listening + // request (i.e. if this is a task request) and this + // task request is being cancelled... + if (status == KErrCancel) + { + // See if we can find a task request cancellation observation + // event type that corresponds to this event type + TEventType cancelEventType = CSit::FindCancelEventType(iEventType); + + if (cancelEventType != EUnfoundEvent) + { + // Complete the task request cancellation + // observation, if found + iServer->CompleteListener(cancelEventType, iSpec, KErrNone); + } + } + + iMessage.Complete(status); + } + +TBool CListenerContainer::WaitingForFulfilling() + { + if (CSit::EventRequiresSit(iEventType) && !iBeingFulfilledBySit) + { + return ETrue; + } + else + { + return EFalse; + } + } + +void CListenerContainer::MarkAsBeingFulfilled() + { + iBeingFulfilledBySit = ETrue; + } + +TBool CListenerContainer::BeingFulfilled() + { + return iBeingFulfilledBySit; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediator/src/eventmediatorstarter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediator/src/eventmediatorstarter.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Creates and starts Event Mediator server. +* +*/ + + + +#include "srvstarter.h" +#include "eventmediator.h" + +CServer2* Starter::CreateAndStartServerL() + { + return CEventMediatorServer::NewL(); + } + +TPtrC Starter::ServerName() + { + return KEventMediatorServer().Mid(0); + } diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediatorapi/BMARM/EVENTMEDAPIU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediatorapi/BMARM/EVENTMEDAPIU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,20 @@ +EXPORTS + __14REventMediator @ 1 NONAME R3UNUSED ; REventMediator::REventMediator(void) + CancelListening__14REventMediator10TEventType @ 2 NONAME R3UNUSED ; REventMediator::CancelListening(TEventType) + CancelListening__14REventMediator10TEventTypeR6TDesC8 @ 3 NONAME R3UNUSED ; REventMediator::CancelListening(TEventType, TDesC8 &) + Close__14REventMediator @ 4 NONAME R3UNUSED ; REventMediator::Close(void) + Connect__14REventMediator @ 5 NONAME R3UNUSED ; REventMediator::Connect(void) + ListenToEvent__14REventMediator10TEventTypeR14MEventObserver @ 6 NONAME R3UNUSED ; REventMediator::ListenToEvent(TEventType, MEventObserver &) + ListenToEvent__14REventMediator10TEventTypeR6TDesC8R14MEventObserver @ 7 NONAME ; REventMediator::ListenToEvent(TEventType, TDesC8 &, MEventObserver &) + ReportEvent__14REventMediator10TEventType @ 8 NONAME R3UNUSED ; REventMediator::ReportEvent(TEventType) + ReportEvent__14REventMediator10TEventTypeR6TDesC8 @ 9 NONAME R3UNUSED ; REventMediator::ReportEvent(TEventType, TDesC8 &) + ReportEvent__14REventMediator10TEventTypeR6TDesC8T2 @ 10 NONAME ; REventMediator::ReportEvent(TEventType, TDesC8 &, TDesC8 &) + ReportLogEvent__14REventMediatorR4TUid12TLogCategoryUiie @ 11 NONAME ; REventMediator::ReportLogEvent(TUid &, TLogCategory, unsigned int, int,...) + CancelAllListening__14REventMediator @ 12 NONAME R3UNUSED ; REventMediator::CancelAllListening(void) + NewEventSpecId__14REventMediator @ 13 NONAME R3UNUSED ; REventMediator::NewEventSpecId(void) + ClearEventLog__14REventMediator @ 14 NONAME R3UNUSED ; REventMediator::ClearEventLog(void) + DeletePrivateFiles__14REventMediator @ 15 NONAME R3UNUSED ; REventMediator::DeletePrivateFiles(void) + GetEventLogData__14REventMediatorR5TDes8 @ 16 NONAME R3UNUSED ; REventMediator::GetEventLogData(TDes8 &) + GetEventLogHeader__14REventMediatorR5TDes8 @ 17 NONAME R3UNUSED ; REventMediator::GetEventLogHeader(TDes8 &) + GetEventLogSize__14REventMediatorRi @ 18 NONAME R3UNUSED ; REventMediator::GetEventLogSize(int &) + diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediatorapi/BWINS/EVENTMEDAPIU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediatorapi/BWINS/EVENTMEDAPIU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,20 @@ +EXPORTS + ??0REventMediator@@QAE@XZ @ 1 NONAME ; REventMediator::REventMediator(void) + ?CancelAllListening@REventMediator@@QAEXXZ @ 2 NONAME ; void REventMediator::CancelAllListening(void) + ?CancelListening@REventMediator@@QAEHW4TEventType@@AAVTDesC8@@@Z @ 3 NONAME ; int REventMediator::CancelListening(enum TEventType, class TDesC8 &) + ?CancelListening@REventMediator@@QAEXW4TEventType@@@Z @ 4 NONAME ; void REventMediator::CancelListening(enum TEventType) + ?Close@REventMediator@@QAEXXZ @ 5 NONAME ; void REventMediator::Close(void) + ?Connect@REventMediator@@QAEHXZ @ 6 NONAME ; int REventMediator::Connect(void) + ?ListenToEvent@REventMediator@@QAEXW4TEventType@@AAVMEventObserver@@@Z @ 7 NONAME ; void REventMediator::ListenToEvent(enum TEventType, class MEventObserver &) + ?ListenToEvent@REventMediator@@QAEXW4TEventType@@AAVTDesC8@@AAVMEventObserver@@@Z @ 8 NONAME ; void REventMediator::ListenToEvent(enum TEventType, class TDesC8 &, class MEventObserver &) + ?NewEventSpecId@REventMediator@@QAEHXZ @ 9 NONAME ; int REventMediator::NewEventSpecId(void) + ?ReportEvent@REventMediator@@QAEHW4TEventType@@@Z @ 10 NONAME ; int REventMediator::ReportEvent(enum TEventType) + ?ReportEvent@REventMediator@@QAEHW4TEventType@@AAVTDesC8@@1@Z @ 11 NONAME ; int REventMediator::ReportEvent(enum TEventType, class TDesC8 &, class TDesC8 &) + ?ReportEvent@REventMediator@@QAEHW4TEventType@@AAVTDesC8@@@Z @ 12 NONAME ; int REventMediator::ReportEvent(enum TEventType, class TDesC8 &) + ?ReportLogEvent@REventMediator@@QAAHAAVTUid@@W4TLogCategory@@IHZZ @ 13 NONAME ; int REventMediator::ReportLogEvent(class TUid &, enum TLogCategory, unsigned int, int, ...) + ?ClearEventLog@REventMediator@@QAEHXZ @ 14 NONAME ; int REventMediator::ClearEventLog(void) + ?DeletePrivateFiles@REventMediator@@QAEHXZ @ 15 NONAME ; int REventMediator::DeletePrivateFiles(void) + ?GetEventLogData@REventMediator@@QAEHAAVTDes8@@@Z @ 16 NONAME ; int REventMediator::GetEventLogData(class TDes8 &) + ?GetEventLogHeader@REventMediator@@QAEHAAVTDes8@@@Z @ 17 NONAME ; int REventMediator::GetEventLogHeader(class TDes8 &) + ?GetEventLogSize@REventMediator@@QAEHAAH@Z @ 18 NONAME ; int REventMediator::GetEventLogSize(int &) + diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediatorapi/EABI/eventmedapiU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediatorapi/EABI/eventmedapiU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,21 @@ +EXPORTS + _ZN14REventMediator11ReportEventE10TEventType @ 1 NONAME + _ZN14REventMediator11ReportEventE10TEventTypeR6TDesC8 @ 2 NONAME + _ZN14REventMediator11ReportEventE10TEventTypeR6TDesC8S2_ @ 3 NONAME + _ZN14REventMediator13ListenToEventE10TEventTypeR14MEventObserver @ 4 NONAME + _ZN14REventMediator13ListenToEventE10TEventTypeR6TDesC8R14MEventObserver @ 5 NONAME + _ZN14REventMediator14NewEventSpecIdEv @ 6 NONAME + _ZN14REventMediator14ReportLogEventER4TUid12TLogCategoryjiz @ 7 NONAME + _ZN14REventMediator15CancelListeningE10TEventType @ 8 NONAME + _ZN14REventMediator15CancelListeningE10TEventTypeR6TDesC8 @ 9 NONAME + _ZN14REventMediator18CancelAllListeningEv @ 10 NONAME + _ZN14REventMediator5CloseEv @ 11 NONAME + _ZN14REventMediator7ConnectEv @ 12 NONAME + _ZN14REventMediatorC1Ev @ 13 NONAME + _ZN14REventMediatorC2Ev @ 14 NONAME + _ZN14REventMediator13ClearEventLogEv @ 15 NONAME + _ZN14REventMediator15GetEventLogDataER5TDes8 @ 16 NONAME + _ZN14REventMediator15GetEventLogSizeERi @ 17 NONAME + _ZN14REventMediator17GetEventLogHeaderER5TDes8 @ 18 NONAME + _ZN14REventMediator18DeletePrivateFilesEv @ 19 NONAME + diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediatorapi/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediatorapi/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2003-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This file provides the information required for building the module. +* +*/ + + + +#include + +PRJ_PLATFORMS + +PRJ_EXPORTS + + +PRJ_MMPFILES + + +eventmediatorapi.mmp + +PRJ_TESTMMPFILES diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediatorapi/group/eventmediatorapi.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediatorapi/group/eventmediatorapi.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project eventmedapi +* +*/ + + + +#include + +TARGET eventmedapi.dll +TARGETTYPE DLL +UID 0x1000008d 0x101FD289 + +CAPABILITY ALL -Tcb +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE EventMediatorAPI.cpp + +SOURCEPATH ../../vpncommon/src +SOURCE clistatic.cpp + +USERINCLUDE ../inc +USERINCLUDE ../../eventmediator/inc +USERINCLUDE ../../vpncommon/inc +USERINCLUDE ../../../vpnapiimpl/inc +USERINCLUDE ../../vpnmanager/inc +USERINCLUDE ../../sit/inc + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY euser.lib +DEBUGLIBRARY flogger.lib diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediatorapi/inc/eventdefssit.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediatorapi/inc/eventdefssit.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,235 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Event definitions for SIT +* +*/ + + + +#ifndef EVENTDEFSSIT_H +#define EVENTDEFSSIT_H + +/* + * The following event types are "SIT events". When a client + * makes a SIT event listening request, the Event Mediator + * uses the SIT to fulfill the request. + * + * When the SIT completes the task that is needed to fulfill + * a certain SIT event listening request, the SIT reports an + * event to the Event Mediator. The event report contains + * event data that the Event Mediator passes further to the + * listeners of the SIT event. + * + * EGetProtocolVersionEvent + * Event specification: VPN policy ID + * Event data: Status of the task + * Protocol type enumeration + * + * EStartVpnConnEvent + * Event specification: VPN IAP ID + * VPN network ID + * Real IAP ID + * Real network ID + * VPN policy ID + * VPN NIF name + * Event data: Status of the task + * IKE policy handle + * IPSec policy handle + * VPN internal address information + * + * ECloseVpnConnEvent + * Event specification: IKE policy handle + * IPSec policy handle + * Event data: Status of the task + * + * EStartRealIapConnEvent + * Event specification: Real IAP ID + * Real network ID + * Event data: Status of the task + * + * EObserveRealIapConnEvent + * Event specification: Real IAP ID + * Real network ID + * Event data: Status of the task + * Real IAP connection event + * + * The following event types are SIT related event types that are + * used by the SIT for fetching task related information from the + * Event Mediator. These event types are meant only for internal + * use between the SIT and the Event Mediator. + * + * ETaskArrivedEvent + * Event specification: - + * Event data: Event type of the task request + * that requires fulfilling + * Event specification ID of the task + * request that requires fulfilling + * + * EFetchTaskInfoEvent + * Event specification: Event type of the task request + * that requires fulfilling + * Event specification ID of the task + * request that requires fulfilling + * Event data: One of the event specifications + * listed below (depends on the event + * type) + * + */ + +/** + * Protocol version information used with EGetProtocolVersionEvent + */ +enum TProtocolVersion + { + EVersionUnknown = 0, + EVersionIp, + EVersionIp6 + }; + +/** + * + * Enumeration of deactivation types. + * + */ +enum TDeactivateType + { + EDeactivateNormal = 0, + EDeactivateForced + }; + + +/** + * Event specification for EGetProtocolVersionEvent and + * EGetProtocolVersionCancelEvent + */ +class TGetProtocolVersionEventSpec : public TEventSpec + { +public: + inline TGetProtocolVersionEventSpec() : TEventSpec() + { + iPolicyId.Zero(); + } + TVpnPolicyId iPolicyId; + }; + +/** + * Event data for EGetProtocolVersionEvent + */ +class TGetProtocolVersionEventData : public TEventData + { +public: + inline TGetProtocolVersionEventData() : TEventData(), iProtocolVersion(EVersionUnknown) + {} + TProtocolVersion iProtocolVersion; + }; + +/** + * Event specification for EStartVpnConnEvent and EStartVpnConnCancelEvent + */ +class TStartVpnConnEventSpec : public TEventSpec + { +public: + inline TStartVpnConnEventSpec() : TEventSpec() + { + iPolicyId.Zero(); + } + TRealConfig iIfInfo; + TVpnPolicyId iPolicyId; + }; + +/** + * Event data for EStartVpnConnEvent + */ +class TStartVpnConnEventData : public TEventData + { +public: + inline TStartVpnConnEventData() : TEventData() + { + iIkePolicyHandle.iHandle = 0; + iIpsecPolicyHandle.iHandle = 0; + } + TPolicyHandle iIkePolicyHandle; + TPolicyHandle iIpsecPolicyHandle; + TVPNAddress iVpnAddressInfo; + TUint32 iIapId; + TUint32 iNetId; + }; + +/** + * Event specification for ECloseVpnConnEvent and ECloseVpnConnCancelEvent + */ +class TCloseVpnConnEventSpec : public TEventSpec + { +public: + inline TCloseVpnConnEventSpec() + :TEventSpec(), + iDeactivateType(EDeactivateNormal), + iVpnIapId(0), + iRealIapId(0) + { + iIkePolicyHandle.iHandle = 0; + iIpsecPolicyHandle.iHandle = 0; + } + TPolicyHandle iIkePolicyHandle; + TPolicyHandle iIpsecPolicyHandle; + TDeactivateType iDeactivateType; + TUint32 iVpnIapId; + TUint32 iRealIapId; + }; + +/** + * Event data for ECloseVpnConnEvent + */ +typedef TEventData TCloseVpnConnEventData; + +/** + * Event specification for EStartRealIapConnEvent and + * EStartRealIapConnCancelEvent + */ +class TStartRealIapConnEventSpec : public TEventSpec + { +public: + inline TStartRealIapConnEventSpec() + :TEventSpec(), iRealIapConnInfo(), iVpnIapId(0), iRealIapId(0) + {} + TConnectionInfo iRealIapConnInfo; + TUint32 iVpnIapId; + TUint32 iRealIapId; + }; + +/** + * Event data for EStartRealIapConnEvent + */ +typedef TEventData TStartRealIapConnEventData; + +/** + * Event specification for EObserveRealIapConnEvent and + * EObserveRealIapConnCancelEvent + */ +typedef TStartRealIapConnEventSpec TObserveRealIapConnEventSpec; + +/** + * Event data for EObserveRealIapConnEvent + */ +class TObserveRealIapConnEventData : public TEventData + { +public: + inline TObserveRealIapConnEventData() + : TEventData(), iInterfaceState(ESingleInterfaceStateUnknown) + {} + TSingleConnInterfaceState iInterfaceState; + }; + + +#endif // EVENTDEFSSIT_H diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediatorapi/inc/eventmediatorapi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediatorapi/inc/eventmediatorapi.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,447 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This module defines the API to get services from EventMediator. +* +*/ + + + +/** + * @file eventmediatorapi.h + * + * This module defines the API to get services from EventMediator. + * + */ + +#ifndef __EVENTMEDIATOR_API_H__ +#define __EVENTMEDIATOR_API_H__ + +#include +#include "vpnapidefs.h" +#include "vpnmandefs.h" + +#define EVENTLOG_FILE_HEADER_LTH 16 + +/** + * + * Enumeration of supported events types. + * + */ +enum TEventType + { + EUnfoundEvent, + ETestEvent, + ESystemEvents = 10000, + EAllInterfaceEvents, + ESingleInterfaceEvent, + ELogEvent, + EKmdAddressChangeEvent, + EKmdCertificateChangeEvent, + EKmdRealIapConnDownEvent, + // SIT events + EGetProtocolVersionEvent = 20000, + EStartVpnConnEvent, + ECloseVpnConnEvent, + EStartRealIapConnEvent, + EObserveRealIapConnEvent, + // Internal use only + ETaskArrivedEvent = 30000, + EFetchTaskInfoEvent, + EGetProtocolVersionCancelEvent, + EStartVpnConnCancelEvent, + ECloseVpnConnCancelEvent, + EStartRealIapConnCancelEvent, + EObserveRealIapConnCancelEvent, + EProgressEvent + }; + +/** + * + * Enumeration of log event categories. + * + */ +enum TLogCategory + { + EInfo, + EWarning, + EError, + EDebug + }; + +/** + * The following definitions are used with TEventType + * ESingleInterfaceEvent and EObserveRealIapConnEvent + */ + +enum TSingleConnInterfaceState + { + ESingleInterfaceStateUnknown = -1, + ESingleInterfaceUp, + ESingleInterfaceDown, + ESingleInterfaceTerminated, // Authoritative stop + }; + +class TSingleInterfaceNotification + { +public: + TConnectionInfo iConnectionInfo; + TSingleConnInterfaceState iState; + }; + +typedef TPckgBuf TSingleInterfaceNotificationBuf; + +/** + * Generic event data definition + */ +class TEventSpec + { +public: + inline TEventSpec() : iId(0) {} + TInt iId; + }; + +/** + * Generic event data definition + */ +class TEventData + { +public: + inline TEventData() : iTaskStatus(KErrNone) {} + TInt iTaskStatus; + }; + +/** + * Used by SIT to get informed about new tasks. + */ +class TTaskArrivedEventData + { +public: + inline TTaskArrivedEventData() + :iEventType(EUnfoundEvent), iEventSpecId(0) + {} + TEventType iEventType; + TInt iEventSpecId; + }; + +/** + * Used by SIT to fetch the event specification of a new task. + */ +typedef TTaskArrivedEventData TFetchTaskInfoEventSpec; + +/** + * + * MEventObserver - This class must be implemented to use ListenToEvent of EventMediatorApi + * + */ +class MEventObserver + { +public: + /** + * Called by REventMediator when a listened event has been reported. + * @param aStatus: error code, KErrNone if successfull. + * @param aType: the type of the event. + * @param aData: a pointer to a descriptor containing reported data about the event. + * aData pointer is valid only during the execution of EventOccured. + * A copy of the descriptor must be made to store the data for later use. + */ + virtual void EventOccured(TInt aStatus, TEventType aType, TDesC8* aData)=0; + }; + +class CEventListener; + +/** + * + * REventMediator - API class for EventMediator + * + */ +class REventMediator:public RSessionBase + { +/** + ** @internalComponent + */ + friend class CEventListener; +public: + /** + * Default constructor + */ + IMPORT_C REventMediator(void); + + /** + * Creates session to the EventMediator server. If server is + * not running, it is started. + */ + IMPORT_C TInt Connect(); + + /** + * Closes the session to the VPN Manager. + */ + IMPORT_C void Close(); + + /** + * Sends asynchronous event notification request. + * Called after Connect() request. + * @param aType: the type of the event. + * @param aObserver: object whose EventOccured method is called when an event + * of type aType has been reported. + */ + IMPORT_C void ListenToEvent(TEventType aType, MEventObserver& aObserver); + + /** + * Sends asynchronous event notification request. + * Called after Connect() request. + * @param aType: the type of the event. + * @param aEventSpec: specific info on listened event. + * @param aObserver: object whose EventOccured method is called when an event + * of type aType has been reported. + */ + IMPORT_C void ListenToEvent(TEventType aType, TDesC8& aEventSpec, MEventObserver& aObserver); + + /** + * Cancels all ListenToEvent requests concerning this event type. + * Called after Connect() request. + * @param aType: the type of the event. + */ + IMPORT_C void CancelListening(TEventType aType); + + /** + * Cancels ListenToEvent request geiven with a specification. + * Notice that this may fail. + * Called after Connect() request. + * @param aEventSpec: specific info on listened event. + * @param aType: the type of the event. + * @return error code, KErrNone if successfull. + */ + IMPORT_C TInt CancelListening(TEventType aType, TDesC8& aEventSpec); + + /** + * Cancels all asynchronous ListenToEvent requests. + * Called after Connect() request. + */ + IMPORT_C void CancelAllListening(); + + /** + * Sends synchronous request to report an event. + * Called after Connect() request. + * @param aType: the type of the event. + * @param aData: a descriptor containing data about the event. + * @return error code, KErrNone if successfull. + */ + IMPORT_C TInt ReportEvent(TEventType aType); + + /** + * Sends synchronous request to report an event. + * Called after Connect() request. + * @param aType: the type of the event. + * @param aData: a descriptor containing data about the event. + * @return error code, KErrNone if successfull. + */ + IMPORT_C TInt ReportEvent(TEventType aType, TDesC8& aData); + + /** + * Sends synchronous request to report an event. + * Called after Connect() request. + * @param aType: the type of the event. + * @param aEventSpec: specific info on listened event. + * @param aData: a descriptor containing data about the event. + * @return error code, KErrNone if successfull. + */ + IMPORT_C TInt ReportEvent(TEventType aType, TDesC8& aEventSpec, TDesC8& aData); + + /** + * Sends synchronous request to report an event. + * Called after Connect() request. + * @param aTSrc: source of the event. + * @param aCategory: category of the log event. + * @param aMsgId: Id of the log message. + * @param aDesCount: number of additional arguments (which must be of type TDesC8*). + * @return error code, KErrNone if successfull. + */ + IMPORT_C TInt ReportLogEvent(TUid& aSrc, TLogCategory aCategory, TUint aMsgId,TInt aDesCount,...); + + /** + * Returns a new event specification + * ID to be used with SIT related events. + */ + IMPORT_C TInt NewEventSpecId(); + + /** + * Requests the Event Mediator to delete the files it owns. + */ + IMPORT_C TInt DeletePrivateFiles(); + + IMPORT_C TInt GetEventLogSize(TInt& aEventLogSize); + + IMPORT_C TInt GetEventLogHeader(TDes8& aEventLogHeader); + + IMPORT_C TInt GetEventLogData(TDes8& aEventLogData); + + IMPORT_C TInt ClearEventLog(); + + /** + * Sends a request to cancel all ListenToEvent requests concerning this + * event type. + * @param aType: the type of the event. + */ + void CancelListenToEvent(TEventType aType); + + /** + * Sends a request to cancel all ListenToEvent requests with a given + * specification. + * @param aEventSpec: specific info on listened event. + * @param aType: the type of the event. + * @return error code, KErrNone if successfull. + */ + TInt CancelListenToEvent(TEventType aType, TDesC8& aEventSpec); + +private: + void CreateListenedEventsListL(); + + /** + * Sends synchronous request to get data repeorted with an event. + * Called after Connect() request. + * @param aSrvPtr: pointer to the data in the servers address space. + * The server checks whether this pointer is valid before using it. + * @param aData: a descriptor to which the datais written. + * @return Error status + */ + TInt FetchData(TAny* aSrvPtr, TDes8& aDataDecriptor); + + /** + * Called by ListenToEvent function. + * Creates a new instance of CEventListener to receive notification about the event. + * Adds thsi object to iListenedEvents. + * @param aType: the type of the event. + * @param aObserver: object whose EventOccured function is called when event is received. + * @return the new listener. + */ + CEventListener* NewEventListenerL(TEventType aType, MEventObserver& aObserver); + + /** + * Deletes listener created with NewEventListener + * @param aType: the type of the event. + */ + void RemoveListener(CEventListener* aListener); + + /** + * Creates EventMediator. + */ + TInt StartEventMediator(); + + /** + * Looks up a listener from iListenedEvents. + * @param aType: type of the event the listener is waiting for. + * @param aIndex: the position of the listener in iListenedEvents. + * @return ETrue if listener exists, EFalse if not. + */ + TBool FindEventListener(const TEventType aType, TInt& aIndex); + + /** + * Looks up a listener from iListenedEvents. + * @param aType: type of the event the listener is waiting for. + * @param aEventSpec event specification + * @param aIndex: the position of the listener in iListenedEvents. + * @return ETrue if listener exists, EFalse if not. + */ + TBool FindEventListener(const TEventType aType, TDesC8& aEventSpec, TInt& aIndex); + + /** + * Reads the variable arguments of ReportLogEvent. + * @param aCount: Number of arguments. + * @param aList: list of arguments. + * @param aPointers: array to be filled with argument pointers. + * @param aLengths: array to be filled with argument lengths. + * @param aOverAllLength: sum of argument lengths + * @return error code, KErrNone if successfull. + */ + TInt ReadLogArguments(TInt aCount, VA_LIST aList,TDesC8** aPointers, TInt* aLengths, TInt& aOverAllLength); + +private: //Data + // list of listeners created with function NewEventListener + CArrayFixFlat* iListenedEvents; + TInt64 iRandSeed; + }; + +/** + * + * CEventListener - A class used by REventListener to Store information about the listened events. + * + */ +NONSHARABLE_CLASS(CEventListener) : public CActive + { +/** + ** @internalComponent + */ + friend class REventMediator; + enum TListenerState { EStateListening = 0, EStateFetchingData}; +public: + /** + * standard deconstructor + */ + ~CEventListener(); +private: + /** + * Constructor. + * @param aType: type of the event that is listened. + * @param aObserver: object whose EventOccured is called when event has occured. + * @param aSession: pointer to the owning REventMediator object. + */ + CEventListener(TEventType aType, MEventObserver& aObserver, REventMediator* aSession); + + /** + * Implement RunL of class CActive. + */ + void RunL(); + + /** + * Handles the completion of event listening request + */ + void HandleListeningComplete(); + + /** + * Handles the completion of event data fetching request + * @param Error status + */ + void HandleFetchingComplete(TInt aError); + + /** + * Implements DoCancel of class CActive. + */ + void DoCancel(); + +private: //data + // buffer to receive the length of the data descriptor of an reported event. + TPckgBuf iDataLengthPckg; + // buffer to receive the pointer to the data descriptor in servers address space. + TPckgBuf iSrvDataPtrPckg; + // type of the event that is listened. + TEventType iType; + // the observer given in constructor. + MEventObserver& iObserver; + // the session given in constructor + REventMediator* iSession; + + // possible extra specifications on listened events + HBufC8* iSpecBuf; + + // Event data + HBufC8* iDataBuf; + + // Event data as a modifiable descriptor + TPtr8 iDataPtr; + + // Internal state + TListenerState iState; + }; + +#endif // __EVENTMEDIATOR_API_H__ diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediatorapi/inc/log.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediatorapi/inc/log.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Logging utility. +* +*/ + + + +#if !defined(__LOG_H__) +#define __LOG_H__ + +_LIT(KLogFile,"eventmedapi.txt"); + +#include "logcommon.h" + +#endif // __LOG_H__ diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediatorapi/rom/eventmediatorapi.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediatorapi/rom/eventmediatorapi.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Image description file for project eventmediatorapi +* +*/ + + + +#ifndef __EVENTMEDIATORAPI_IBY__ +#define __EVENTMEDIATORAPI_IBY__ + +#ifdef SYMBIAN_EXCLUDE_IPSEC + +REM Feature EVENTMEDIATORAPI not included in this rom + +#else + +file=ABI_DIR\BUILD_DIR\eventmedapi.dll SHARED_LIB_DIR\eventmedapi.dll + +#endif // SYMBIAN_EXCLUDE_IPSEC + +#endif // __EVENTMEDIATORAPI_IBY__ diff -r 000000000000 -r 33413c0669b9 vpnengine/eventmediatorapi/src/EventMediatorAPI.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventmediatorapi/src/EventMediatorAPI.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,505 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This module defines the API to EventMediator. +* +*/ + + +#include +#include "eventmediator.h" +#include "eventmediatorapi.h" +#include "eventlogger.h" +#include "clistatic.h" +#include "log.h" + +/**--------------------------------------------------------- + * + * REventMediator class constructor + * + *----------------------------------------------------------*/ +EXPORT_C REventMediator::REventMediator() : iListenedEvents(NULL) + { + } + +/**--------------------------------------------------------- + * + * Connect() + * + * Opens a session to EventMediator server and starts the server if it + * not yet started + * + * Returns: KErrNone: OK + * value: error + * + *----------------------------------------------------------*/ +EXPORT_C TInt REventMediator::Connect(void) + { + TInt ret = KErrNone; + TRAP(ret, CreateListenedEventsListL()); + if (ret != KErrNone) + { + return ret; + } + + TInt retry=2; + for (;;) + { + TInt r=CreateSession(KEventMediatorServer, + TVersion(KEventMediatorMajorVersionNumber, + KEventMediatorMinorVersionNumber, + KEventMediatorBuildVersionNumber), + 2 * KDefaultMessageSlots); + + if (r!=KErrNotFound && r!=KErrServerTerminated) + return r; + if (--retry==0) + return r; + r = Launcher::LaunchServer(KEventMediatorServer, KEventMediatorFile, + KEventMediatorUid3); + + if (r!=KErrNone && r!=KErrAlreadyExists) + return r; + } + } + +void REventMediator::CreateListenedEventsListL() + { + iListenedEvents = new (ELeave) CArrayFixFlat(1); + } + +// --------------------------------------------------------------------------- +// Closes a session to EventMediator server +// --------------------------------------------------------------------------- +// +EXPORT_C void REventMediator::Close() + { + if ( iListenedEvents ) + { + TInt nEvents( iListenedEvents->Count() ); + for (TInt i = 0; i < nEvents; i++) + delete iListenedEvents->At(i); + iListenedEvents->Delete(0,iListenedEvents->Count()); + delete iListenedEvents; + iListenedEvents = NULL; + } + RSessionBase::Close(); + } + +EXPORT_C void REventMediator::ListenToEvent(TEventType aType, MEventObserver& aObserver) + { + LOG(Log::Printf(_L("REventMediator::ListenToEvent(TEventType aType, MEventObserver& aObserver)\n"))); + + TInt status=KErrNone; + CEventListener* listener=NULL; + TRAP(status, listener=NewEventListenerL(aType,aObserver);) + + if(status==KErrNone) + { + LOG(Log::Printf(_L("REventMediator::ListenToEvent(TEventType aType, MEventObserver& aObserver) - calling SendReceive\n"))); + + SendReceive(CEventMediatorSession::KEventMediatorListen, + TIpcArgs(aType, + &(listener->iDataLengthPckg), + &(listener->iSrvDataPtrPckg)), + listener->iStatus); + + LOG(Log::Printf(_L("REventMediator::ListenToEvent(TEventType aType, MEventObserver& aObserver) - SendReceive called\n"))); + + listener->SetActive(); + } + else + aObserver.EventOccured(status, aType, NULL); + } + +EXPORT_C void REventMediator::ListenToEvent(TEventType aType, TDesC8& aEventSpec, MEventObserver& aObserver) + { + LOG(Log::Printf(_L("REventMediator::ListenToEvent(TEventType aType, TDesC8& aEventSpec, MEventObserver& aObserver)\n"))); + + TInt status=KErrNone; + CEventListener* listener=NULL; + TRAP(status, listener=NewEventListenerL(aType,aObserver);) + + if(status==KErrNone) + { + listener->iSpecBuf = aEventSpec.Alloc(); + if (listener->iSpecBuf==NULL) + status = KErrNoMemory; + } + + if(status==KErrNone) + { + LOG(Log::Printf(_L("REventMediator::ListenToEvent(TEventType aType, TDesC8& aEventSpec, MEventObserver& aObserver) - calling SendReceive\n"))); + + SendReceive(CEventMediatorSession::KEventMediatorListenWithSpec, + TIpcArgs(aType, + &(listener->iDataLengthPckg), + &(listener->iSrvDataPtrPckg), + listener->iSpecBuf), + listener->iStatus); + + LOG(Log::Printf(_L("REventMediator::ListenToEvent(TEventType aType, TDesC8& aEventSpec, MEventObserver& aObserver) - SendReceive called\n"))); + + listener->SetActive(); + } + else + aObserver.EventOccured(status, aType, NULL); + } + +EXPORT_C void REventMediator::CancelListening(TEventType aType) + { + LOG(Log::Printf(_L("REventMediator::CancelListening(TEventType aType)\n"))); + + TInt index = -1; + while ( FindEventListener( aType, index ) ) + { + CEventListener* listener = iListenedEvents->At( index ); + listener->Cancel(); + RemoveListener( listener ); + } + } + +EXPORT_C TInt REventMediator::CancelListening(TEventType aType, TDesC8& aEventSpec) + { + LOG(Log::Printf(_L("REventMediator::CancelListening(TEventType aType, TDesC8& aEventSpec)\n"))); + + TInt index = -1; + while ( FindEventListener( aType, aEventSpec, index ) ) + { + CEventListener* listener = iListenedEvents->At( index ); + listener->Cancel(); + RemoveListener( listener ); + } + + return KErrNone; + } + +EXPORT_C void REventMediator::CancelAllListening() + { + LOG(Log::Printf(_L("REventMediator::CancelAllListening()\n"))); + + while ( iListenedEvents->Count() ) + { + CEventListener* listener = iListenedEvents->At( 0 ); + listener->Cancel(); + RemoveListener( listener ); + } + } + +EXPORT_C TInt REventMediator::ReportEvent(TEventType aType) + { + return SendReceive(CEventMediatorSession::KEventMediatorReportEvent, TIpcArgs(aType, 0, NULL)); + } + +EXPORT_C TInt REventMediator::ReportEvent(TEventType aType, TDesC8& aData) + { + return SendReceive(CEventMediatorSession::KEventMediatorReportEvent, TIpcArgs(aType, aData.Length(), &aData)); + } + +EXPORT_C TInt REventMediator::ReportEvent(TEventType aType, TDesC8& aEventSpec, TDesC8& aData) + { + return SendReceive(CEventMediatorSession::KEventMediatorReportEventWithSpec, TIpcArgs(aType, aData.Length(), &aData, &aEventSpec)); + } + +EXPORT_C TInt REventMediator::ReportLogEvent(TUid& aSrc, TLogCategory aCategory, TUint aMsgId, TInt aDesCount,...) + { + VA_LIST list; + TInt err; + TLogEvent event(aSrc, aCategory, aMsgId,aDesCount); + TPckg eventPckg(event); + HBufC8* desBuf=NULL; + TInt desBufLength; + // alloc array for descripor pointers + TDesC8** pointers = new TDesC8*[aDesCount]; + TInt* lengths = new TInt[aDesCount]; + TInt lengthsDesLth = aDesCount*sizeof(TInt); // length of a descriptor containing lengths array. + + // read arguments to array + VA_START(list, aDesCount); + err = ReadLogArguments( aDesCount, list, pointers,lengths, desBufLength); + VA_END(list); + + if(err==KErrNone) + { + // Read arguments to one descriptor + desBuf = HBufC8::New(eventPckg.Length()+lengthsDesLth+desBufLength); + if(desBuf==NULL) + err=KErrNoMemory; + else + { + TPtr8 desPtr= desBuf->Des(); + desPtr.Append(eventPckg); + desPtr.Append((TUint8*)lengths,lengthsDesLth); + for(TInt i=0; i < aDesCount; i++) + { + desPtr.Append(*(pointers[i])); + TInt fillerLth = 4 -(lengths[i] % 4); + TChar filler(0); + if (fillerLth > 0 && fillerLth < 4) + { + desPtr.AppendFill(filler , fillerLth); + } + } + err=ReportEvent(ELogEvent,desPtr); + } + } + delete[] pointers; + delete[] lengths; + delete desBuf; + return err; + } + +EXPORT_C TInt REventMediator::NewEventSpecId() + { + TInt specId = 0; + TPckg specIdDes(specId); + + SendReceive(CEventMediatorSession::KEventMediatorNewEventSpecId, TIpcArgs(&specIdDes)); + + return specId; + } + +void REventMediator::CancelListenToEvent(TEventType aType) + { + LOG(Log::Printf(_L("REventMediator::CancelListenToEvent(TEventType aType)\n"))); + + SendReceive(CEventMediatorSession::KEventMediatorCancel, TIpcArgs(aType)); + } + +TInt REventMediator::CancelListenToEvent(TEventType aType, TDesC8& aEventSpec) + { + LOG(Log::Printf(_L("REventMediator::CancelListenToEvent(TEventType aType, TDesC8& aEventSpec)\n"))); + + return SendReceive(CEventMediatorSession::KEventMediatorCancelWithSpec, TIpcArgs(aType, NULL, NULL, &aEventSpec)); + } + +TInt REventMediator::FetchData(TAny* aSrvPtr, TDes8& aDataPtr) + { + LOG(Log::Printf(_L("REventMediator::FetchData()\n"))); + + TRequestStatus status; + SendReceive(CEventMediatorSession::KEventMediatorFetchData, + TIpcArgs(aSrvPtr, &aDataPtr), status); + User::WaitForRequest(status); + + LOG_1("REventMediator::FetchData() - SendReceive called, status: %d\n",status.Int()); + return status.Int(); + } + +CEventListener* REventMediator::NewEventListenerL(TEventType aType, MEventObserver& aObserver) + { + CEventListener* listener=NULL; + + listener = new (ELeave) CEventListener(aType, aObserver,this); + CleanupStack::PushL(listener); + iListenedEvents->AppendL(listener); + CleanupStack::Pop(); + return listener; + } + +void REventMediator::RemoveListener(CEventListener* aListener) + { + TInt index=-1; + for(TInt i=0; iCount(); i++) + { + if(iListenedEvents->At(i)==aListener) + { + index=i; + break; + } + } + if (index >=0) + { + delete iListenedEvents->At(index); + iListenedEvents->Delete(index); + } + } + +TBool REventMediator::FindEventListener(const TEventType aType, TInt& aIndex) + { + for( TInt i=0; iCount(); i++ ) + { + if( iListenedEvents->At(i)->iType == aType ) + { + aIndex = i; + return ETrue; + } + } + return EFalse; + } + +TBool REventMediator::FindEventListener(const TEventType aType, TDesC8& aEventSpec, TInt& aIndex) + { + for( TInt i=0; iCount(); i++ ) + { + if( iListenedEvents->At(i)->iType == aType && + iListenedEvents->At(i)->iSpecBuf && + iListenedEvents->At(i)->iSpecBuf->Des().Compare( aEventSpec ) == 0 ) + { + aIndex = i; + return ETrue; + } + } + return EFalse; + } + +TInt REventMediator::ReadLogArguments(TInt aCount, VA_LIST aList, TDesC8** aPointers, TInt* aLengths, TInt& aOverAllLength) + { + if(aPointers==NULL || aLengths==NULL) + return KErrNoMemory; + aOverAllLength=0; + for (TInt i=0; iLength(); + aOverAllLength += aLengths[i]; + TInt fillerLth = 4 - (aLengths[i] % 4); + if (fillerLth > 0 && fillerLth < 4) + { + aOverAllLength += fillerLth; + } + + } + return KErrNone; + } + +EXPORT_C TInt REventMediator::DeletePrivateFiles() + { + return SendReceive (CEventMediatorSession::KEventMediatorDeletePrivateFiles, TIpcArgs()); + } + + +EXPORT_C TInt REventMediator::GetEventLogSize(TInt& aEventLogSize) + { + TPckg eventLogSizePckg(aEventLogSize); + + return SendReceive (CEventMediatorSession::KEventMediatorGetEventLogSize, + TIpcArgs(&eventLogSizePckg)); + } + +EXPORT_C TInt REventMediator::GetEventLogHeader(TDes8& aEventLogHeader) + { + return SendReceive (CEventMediatorSession::KEventMediatorGetEventLogHeader, + TIpcArgs(&aEventLogHeader)); + } + +EXPORT_C TInt REventMediator::GetEventLogData(TDes8& aEventLogData) + { + return SendReceive (CEventMediatorSession::KEventMediatorGetEventLogData, + TIpcArgs(&aEventLogData)); + } + +EXPORT_C TInt REventMediator::ClearEventLog() + { + return SendReceive (CEventMediatorSession::KEventMediatorClearEventLog, TIpcArgs()); + } + + +void CEventListener::DoCancel() + { + if (iSpecBuf) + iSession->CancelListenToEvent(iType, *iSpecBuf); + else + iSession->CancelListenToEvent(iType); + } + +void CEventListener::RunL() // Should it leave? no + { + LOG(Log::Printf(_L("REventMediator::RunL()\n"))); + + if (iState == EStateListening) + { + HandleListeningComplete(); + } + } + +void CEventListener::HandleListeningComplete() + { + LOG(Log::Printf(_L("REventMediator::HandleListeningComplete()\n"))); + + // Event has occured, iSpecBuf is useless. + delete iSpecBuf; + iSpecBuf = NULL; + + TInt status=iStatus.Int(); + + LOG(Log::Printf(_L("REventMediator::HandleListeningComplete() - status = %d\n"), status)); + + if (status==KErrNone) + { + TInt dataLength = iDataLengthPckg(); + // Some events might not have data + if (dataLength) + { + iDataBuf = HBufC8::New(dataLength); + if (iDataBuf) + { + LOG(Log::Printf(_L("REventMediator::HandleListeningComplete() - going to call FetchData()\n"))); + + iDataPtr.Set(iDataBuf->Des()); + TInt err = iSession->FetchData(iSrvDataPtrPckg(), iDataPtr); + iState = EStateFetchingData; + // Event reporting to the observer and listener + // cleanup are handled in HandleFetchingComplete + HandleFetchingComplete(err); + return; + } + else + status = KErrNoMemory; + } + iObserver.EventOccured(status, iType, NULL); + } + else if (status!=KErrCancel) // Cancels are not reported + { + iObserver.EventOccured(status, iType, NULL); + } + + // Listened event has occured, so this listener is done + iSession->RemoveListener(this); + } + +void CEventListener::HandleFetchingComplete(TInt aError) + { + LOG(Log::Printf(_L("REventMediator::HandleFetchingComplete()\n"))); + + LOG(Log::Printf(_L("REventMediator::HandleFetchingComplete() - status = %d\n"), aError)); + + if (aError==KErrNone) + { + iObserver.EventOccured(aError, iType, iDataBuf); + } + else if (aError!=KErrCancel) // Cancels are not reported + { + iObserver.EventOccured(aError, iType, NULL); + } + + // Listened event has occured, so this listener is done + iSession->RemoveListener(this); + } + +CEventListener::CEventListener(TEventType aType,MEventObserver& aObserver, REventMediator* aSession) : + CActive(0), iType(aType), iObserver(aObserver), iSession(aSession), + iDataPtr(NULL, 0), iState(EStateListening) + { + CActiveScheduler::Add(this); + } + +CEventListener::~CEventListener() + { + Cancel(); + delete iSpecBuf; + iSpecBuf = NULL; + delete iDataBuf; + iDataBuf = NULL; + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/eventviewer/BMARM/EVENTVIEWERU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventviewer/BMARM/EVENTVIEWERU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,10 @@ +EXPORTS + NewL__12CEventViewer @ 1 NONAME R3UNUSED ; CEventViewer::NewL(void) + GetEventUsingEventNumber__12CEventViewerRP7HBufC16UlR16TEventProperties @ 2 NONAME ; CEventViewer::GetEventUsingEventNumber(HBufC16 *&, unsigned long, TEventProperties &) + GetIapName__11EventViewerUlRt5TBuf81i50 @ 3 NONAME R3UNUSED ; EventViewer::GetIapName(unsigned long, TBuf8<50> &) + GetIapNames__11EventViewerUlRt5TBuf81i50UlT2 @ 4 NONAME ; EventViewer::GetIapNames(unsigned long, TBuf8<50> &, unsigned long, TBuf8<50> &) + GetMostRecentEvent__12CEventViewerRP7HBufC16R16TEventProperties @ 5 NONAME R3UNUSED ; CEventViewer::GetMostRecentEvent(HBufC16 *&, TEventProperties &) + GetNextEvent__12CEventViewerRP7HBufC16R16TEventProperties @ 6 NONAME R3UNUSED ; CEventViewer::GetNextEvent(HBufC16 *&, TEventProperties &) + GetPreviousEvent__12CEventViewerRP7HBufC16R16TEventProperties @ 7 NONAME R3UNUSED ; CEventViewer::GetPreviousEvent(HBufC16 *&, TEventProperties &) + DeleteLogFile__12CEventViewer @ 8 NONAME R3UNUSED ; CEventViewer::DeleteLogFile(void) + diff -r 000000000000 -r 33413c0669b9 vpnengine/eventviewer/BWINS/EVENTVIEWERU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventviewer/BWINS/EVENTVIEWERU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,12 @@ +EXPORTS + ??1CEventViewer@@UAE@XZ @ 1 NONAME ; CEventViewer::~CEventViewer(void) + ?DeleteLogFile@CEventViewer@@QAEHXZ @ 2 NONAME ; int CEventViewer::DeleteLogFile(void) + ?GetEventUsingEventNumber@CEventViewer@@QAEHAAPAVHBufC16@@KAAUTEventProperties@@@Z @ 3 NONAME ; int CEventViewer::GetEventUsingEventNumber(class HBufC16 * &, unsigned long, struct TEventProperties &) + ?GetIapName@EventViewer@@SAHKAAV?$TBuf8@$0DC@@@@Z @ 4 NONAME ; int EventViewer::GetIapName(unsigned long, class TBuf8<50> &) + ?GetIapNames@EventViewer@@SAHKAAV?$TBuf8@$0DC@@@K0@Z @ 5 NONAME ; int EventViewer::GetIapNames(unsigned long, class TBuf8<50> &, unsigned long, class TBuf8<50> &) + ?GetMostRecentEvent@CEventViewer@@QAEHAAPAVHBufC16@@AAUTEventProperties@@@Z @ 6 NONAME ; int CEventViewer::GetMostRecentEvent(class HBufC16 * &, struct TEventProperties &) + ?GetNextEvent@CEventViewer@@QAEHAAPAVHBufC16@@AAUTEventProperties@@@Z @ 7 NONAME ; int CEventViewer::GetNextEvent(class HBufC16 * &, struct TEventProperties &) + ?GetPreviousEvent@CEventViewer@@QAEHAAPAVHBufC16@@AAUTEventProperties@@@Z @ 8 NONAME ; int CEventViewer::GetPreviousEvent(class HBufC16 * &, struct TEventProperties &) + ?NewL@CEventViewer@@SAPAV1@XZ @ 9 NONAME ; class CEventViewer * CEventViewer::NewL(void) + ?GetSnapName@EventViewer@@SAHKAAV?$TBuf8@$0DC@@@@Z @ 10 NONAME ; int EventViewer::GetSnapName(unsigned long, class TBuf8<50> &) + diff -r 000000000000 -r 33413c0669b9 vpnengine/eventviewer/EABI/eventViewerU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventviewer/EABI/eventViewerU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,13 @@ +EXPORTS + _ZN11EventViewer10GetIapNameEmR5TBuf8ILi50EE @ 1 NONAME + _ZN11EventViewer11GetIapNamesEmR5TBuf8ILi50EEmS2_ @ 2 NONAME + _ZN12CEventViewer12GetNextEventERP7HBufC16R16TEventProperties @ 3 NONAME + _ZN12CEventViewer13DeleteLogFileEv @ 4 NONAME + _ZN12CEventViewer16GetPreviousEventERP7HBufC16R16TEventProperties @ 5 NONAME + _ZN12CEventViewer18GetMostRecentEventERP7HBufC16R16TEventProperties @ 6 NONAME + _ZN12CEventViewer24GetEventUsingEventNumberERP7HBufC16mR16TEventProperties @ 7 NONAME + _ZN12CEventViewer4NewLEv @ 8 NONAME + _ZTI12CEventViewer @ 9 NONAME ; ## + _ZTV12CEventViewer @ 10 NONAME ; ## + _ZN11EventViewer11GetSnapNameEmR5TBuf8ILi50EE @ 11 NONAME + diff -r 000000000000 -r 33413c0669b9 vpnengine/eventviewer/data/vpnlogmessages.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventviewer/data/vpnlogmessages.rss Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,72 @@ +/* +* Copyright (c) 2002-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Resource definitions for Event viewer. +* +*/ + + + +NAME EVVI + +#include +#include +#include "vpnlogmessages1.lms" + +RESOURCE RSS_SIGNATURE { } +RESOURCE TBUF r_vpn_msg_created_server { buf=qtn_vpn_msg_created_server; } +RESOURCE TBUF r_vpn_msg_deleted_server { buf=qtn_vpn_msg_deleted_server; } +RESOURCE TBUF r_vpn_msg_updated_server { buf=qtn_vpn_msg_updated_server; } +RESOURCE TBUF r_vpn_msg_installed_policy_file { buf=qtn_vpn_msg_installed_policy_file; } +RESOURCE TBUF r_vpn_msg_installed_policy_server { buf=qtn_vpn_msg_installed_policy_server; } +RESOURCE TBUF r_vpn_msg_policy_install_fail { buf=qtn_vpn_msg_policy_install_fail; } +RESOURCE TBUF r_vpn_msg_policy_update_fail { buf=qtn_vpn_msg_policy_update_fail; } +RESOURCE TBUF r_vpn_msg_deleted_policy { buf=qtn_vpn_msg_deleted_policy; } +RESOURCE TBUF r_vpn_msg_updated_policy { buf=qtn_vpn_msg_updated_policy; } +RESOURCE TBUF r_vpn_msg_serv_identity_verify_fail { buf=qtn_vpn_msg_serv_identity_verify_fail; } +RESOURCE TBUF r_vpn_msg_updated_enrollment_service { buf=qtn_vpn_msg_updated_enrollment_service; } +RESOURCE TBUF r_vpn_msg_deleted_enrollment_service { buf=qtn_vpn_msg_deleted_enrollment_service; } +RESOURCE TBUF r_vpn_msg_installed_enrollment_service { buf=qtn_vpn_msg_installed_enrollment_service; } + +RESOURCE TBUF r_vpn_msg_policy_serv_auth_fail { buf=qtn_vpn_msg_policy_serv_auth_fail; } +RESOURCE TBUF r_vpn_msg_serv_auth_fail_client_cert_exp { buf=qtn_vpn_msg_serv_auth_fail_client_cert_exp; } +RESOURCE TBUF r_vpn_msg_serv_auth_fail_serv_cert_exp { buf=qtn_vpn_msg_serv_auth_fail_serv_cert_exp; } +RESOURCE TBUF r_vpn_msg_policy_serv_conn_fail { buf=qtn_vpn_msg_policy_serv_conn_fail; } +RESOURCE TBUF r_vpn_msg_serv_err_resp_received { buf=qtn_vpn_msg_serv_err_resp_received; } +RESOURCE TBUF r_vpn_msg_enroll_cert_policy_serv { buf=qtn_vpn_msg_enroll_cert_policy_serv; } +RESOURCE TBUF r_vpn_msg_pol_serv_cert_enr_fail { buf=qtn_vpn_msg_pol_serv_cert_enr_fail; } +RESOURCE TBUF r_vpn_msg_cert_installed { buf=qtn_vpn_msg_cert_installed; } +RESOURCE TBUF r_vpn_msg_cert_install_failed { buf=qtn_vpn_msg_cert_install_failed; } + +RESOURCE TBUF r_vpn_msg_created_vpn_access_point_with_ap { buf=qtn_vpn_msg_created_vpn_access_point_with_ap; } +RESOURCE TBUF r_vpn_msg_created_vpn_access_point_with_snap { buf=qtn_vpn_msg_created_vpn_access_point_with_snap; } +RESOURCE TBUF r_vpn_msg_unspecified_error { buf=qtn_vpn_msg_unspecified_error; } +RESOURCE TBUF r_vpn_msg_vpn_iap_activated { buf=qtn_vpn_msg_vpn_iap_activated; } +RESOURCE TBUF r_vpn_msg_vpn_iap_act_failed { buf=qtn_vpn_msg_vpn_iap_act_failed; } + +RESOURCE TBUF r_vpn_msg_vpn_iap_act_failed_cert_not_valid { buf=qtn_vpn_msg_vpn_iap_act_failed_cert_not_valid; } +RESOURCE TBUF r_vpn_msg_vpn_iap_act_failed_cert_exp_miss { buf=qtn_vpn_msg_vpn_iap_act_failed_cert_exp_miss; } +RESOURCE TBUF r_vpn_msg_real_iap_act_failed { buf=qtn_vpn_msg_real_iap_act_failed; } +RESOURCE TBUF r_vpn_msg_vpn_gw_no_resp { buf=qtn_vpn_msg_vpn_gw_no_resp; } +RESOURCE TBUF r_vpn_msg_vpn_gw_auth_ok { buf=qtn_vpn_msg_vpn_gw_auth_ok; } +RESOURCE TBUF r_vpn_msg_vpn_gw_auth_fail { buf=qtn_vpn_msg_vpn_gw_auth_fail; } +RESOURCE TBUF r_vpn_msg_vpn_iap_deact { buf=qtn_vpn_msg_vpn_iap_deact; } +RESOURCE TBUF r_vpn_msg_real_iap_deact { buf=qtn_vpn_msg_real_iap_deact; } +RESOURCE TBUF r_vpn_msg_vpn_iap_deact_timeout { buf=qtn_vpn_msg_vpn_iap_deact_timeout; } +RESOURCE TBUF r_vpn_msg_vpn_gw_err_resp_received { buf=qtn_vpn_msg_vpn_gw_err_resp_received; } +RESOURCE TBUF r_vpn_msg_data_dropped_due_policy { buf=qtn_vpn_msg_data_dropped_due_policy; } +RESOURCE TBUF r_vpn_msg_vpn_iap_deact_real_iap_terminated { buf=qtn_vpn_msg_vpn_iap_deact_real_iap_terminated; } +RESOURCE TBUF r_vpn_msg_real_iap_reactivated { buf=qtn_vpn_msg_real_iap_reactivated; } +RESOURCE TBUF r_vpn_msg_sent_error_response { buf=qtn_vpn_msg_sent_error_response; } +RESOURCE TBUF r_vpn_msg_addr_info_for_vpn_ap { buf=qtn_vpn_msg_addr_info_for_vpn_ap; } +RESOURCE TBUF r_vpn_msg_cert_error { buf=qtn_vpn_msg_cert_error; } diff -r 000000000000 -r 33413c0669b9 vpnengine/eventviewer/data/vpnlogmessages1.lms --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventviewer/data/vpnlogmessages1.lms Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,300 @@ +/* +* ============================================================================== +* Name : vpnlogmessages1.lms +* Part of : eventviewer +* Description : This is a localisation file for IPSec VPN software log messages. +* Version : %version: 3 % +* +* Copyright © 2003-2008 Nokia. All rights reserved. +* This material, including documentation and any related computer +* programs, is protected by copyright controlled by Nokia. All +* rights are reserved. Copying, including reproducing, storing, +* adapting or translating, any or all of this material requires the +* prior written consent of Nokia. This material also contains +* confidential information which may not be disclosed to others +* without the prior written consent of Nokia. +* ============================================================================ +* Template version: 4.1 +* +* Syntax of a logical name entry in this file is the following: +* +* // d:context description (line 1) +* // d:context description (line N) +* // l:P_No +* // +* #define qtn_?feature/?module_name_?freetext "?text" +* #define text_?feature/?module_name_?freetext "?text" +* +* where +* "qtn_" or "text_" starts a logical name, which does not +* contain dots. +* "d:" starts description line(s), which +* clarify entry's context with information like: +* 1. Is a word a verb in imperative or is it a noun ? +* - what does text "Set" mean ? +* 2. What will replace %U (unicode text parameter) or +* %A (8-bit text parameter) or +* %N (number parameter) included in texts ? +* - is it phone number or email address ? +* "l:" starts a layout information (one line). +* "P" and "No" are symbols in LAF's information table +* - "P" is parent pane or current pane +* - "No" is reference number in table +* +* ============================================================================== +*/ + +// LOCALISATION STRINGS + +// **VPN LOG MESSAGES + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_created_server "Created policy server '%U'" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_deleted_server "Deleted policy server '%U'" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_updated_server "Updated policy server '%U'" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_installed_policy_file "Installed policy '%A' from file" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_installed_policy_server "Installed policy '%1A' from server '%2U'" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_policy_install_fail "Failed to install policy '%A', reason code %N" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_policy_update_fail "Failed to update policy '%A', reason code %N" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_deleted_policy "Deleted policy '%A'" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_updated_policy "Updated policy '%1A' from server '%2A'" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_installed_enrollment_service "Installed enrollment service configuration for certification authority '%1A' from server '%2U'" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_updated_enrollment_service "Updated enrollment service configuration for certification authority '%1A' from server '%2A'" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_deleted_enrollment_service "Deleted enrollment service configuration for certification authority '%1A'" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_serv_identity_verify_fail "Failed to verify identity of server '%U', reason code %N" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_policy_serv_auth_fail "Failed to authenticate to policy server '%U', reason code %N" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_serv_auth_fail_client_cert_exp "Failed to authenticate to policy server '%U', client certificate expired/revoked, server synchronisation required" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_serv_auth_fail_serv_cert_exp "Failed to authenticate to policy server '%U', server certificate expired, server definition must be deleted and re-created" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_policy_serv_conn_fail "Failed to connect to policy server '%1U', reason code %2N, state code %3N" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_serv_err_resp_received "Received error response from server '%1U', error code %2N, state code %3N" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_enroll_cert_policy_serv "Enrolled client certificate for accessing policy server '%1U', user identity '%2A'" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_pol_serv_cert_enr_fail "Failed to enroll client certificate for accessing policy server '%1U', reason code %2N, user identity '%3A'" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_cert_installed "Installed certificate: %A" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_cert_install_failed "Failed to install certificate. Reason code %N, certificate: %A" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_created_vpn_access_point_with_ap "Created VPN access point '%1A', policy '%2A', Internet access point '%3A'" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_created_vpn_access_point_with_snap "Created VPN access point '%1A', policy '%2A', Internet destination '%3A'" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_unspecified_error "Unspecified error, source '%1A', error code %2N, state code %3N" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_vpn_iap_activated "Activated VPN access point '%1A', IP address %2A" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_vpn_iap_act_failed "Failed to activate VPN access point '%A', reason code %N" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_vpn_iap_act_failed_cert_not_valid "Failed to activate VPN access point '%A', client certificate not yet valid" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_vpn_iap_act_failed_cert_exp_miss "Failed to activate VPN access point '%A', client certificate expired or missing" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_real_iap_act_failed "Failed to create Internet connection via Internet access point '%1A', VPN access point '%2A', reason code %3N" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_vpn_gw_no_resp "Received no response from VPN gateway %1A, VPN access point %2A" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_vpn_gw_auth_ok "Authenticated to VPN gateway '%1A', VPN access point %2A" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_vpn_gw_auth_fail "Failed to authenticate to VPN gateway '%1A', VPN access point '%2A'" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_vpn_iap_deact "Deactivated VPN access point '%A'" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_real_iap_deact "Closed Internet connection established via Internet access point '%1A', VPN access point '%2A'" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_vpn_iap_deact_timeout "Deactivated VPN access point %A', VPN policy timed out" + +//d:Detail's message in message query. +//d:Error +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_vpn_gw_err_resp_received "Received an error response from VPN gateway '%1A', VPN access point %2A, error code %3N " + +//d:Detail's message in message query. +//d:Warning +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_data_dropped_due_policy "Dropped data due to VPN policy, source address '%A', reason code %N" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_vpn_iap_deact_real_iap_terminated "Deactivated VPN access point %1A', Internet connection via Internet access point '%2A' was terminated" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_real_iap_reactivated "Reopened Internet connection via Internet access point '%1A', VPN access point '%2A'" + +//d:Detail's message in message query. +//d:Information +//l:popup_query_sat_info_window_1 +// +#define qtn_vpn_msg_sent_error_response "Sent an error response to VPN gateway '%1A', VPN access point '%2A', error code %3N" +#define qtn_vpn_msg_addr_info_for_vpn_ap "Address info for VPN access point '%1A': virtual IP '%2A', local IP '%3A', NAT status code %4N" +#define qtn_vpn_msg_cert_error "Certificate error. Possible reason: subject or issuer name of certificate contains unsupported attribute. " + + +// End of File diff -r 000000000000 -r 33413c0669b9 vpnengine/eventviewer/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventviewer/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This file provides the information required for building the module. +* +*/ + + + +#include + +PRJ_PLATFORMS + +PRJ_EXPORTS + + +PRJ_MMPFILES + +eventviewer.mmp + +PRJ_TESTMMPFILES diff -r 000000000000 -r 33413c0669b9 vpnengine/eventviewer/group/eventviewer.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventviewer/group/eventviewer.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project eventViewer +* +*/ + + + +#include + +TARGET eventViewer.dll +TARGETTYPE dll +UID 0x1000008d 0x10200EC5 + +CAPABILITY ALL -Tcb +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE eventviewer.cpp +SOURCE logfilehandler.cpp +SOURCE eventformater.cpp + +// The resource file containing IPSec VPN error messages, +// generated for the system error resolver. +SOURCEPATH ../data +START RESOURCE vpnlogmessages.rss +HEADER +TARGETPATH /resource +END + +USERINCLUDE ../inc +USERINCLUDE ../../vpncommon/inc +USERINCLUDE ../data +USERINCLUDE ../../eventmediatorapi/inc +USERINCLUDE ../../vpnmanager/inc +USERINCLUDE ../../../vpnapiimpl/inc + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY euser.lib +LIBRARY efsrv.lib +LIBRARY bafl.lib +LIBRARY eventmedapi.lib +LIBRARY cmmanager.lib +LIBRARY charconv.lib + +DEBUGLIBRARY flogger.lib diff -r 000000000000 -r 33413c0669b9 vpnengine/eventviewer/inc/eventviewer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventviewer/inc/eventviewer.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2003-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Utility methods for eventviewer +* +*/ + + + +#ifndef __EVENTVIEWER__ +#define __EVENTVIEWER__ + +#include + +//////////////////////////////////////////////////////// +// Typedefs +//////////////////////////////////////////////////////// + +typedef TBuf8 TIapName; + + +///////////////////////////////////////////////////////// +// EventViewer Class +///////////////////////////////////////////////////////// +class EventViewer +{ +public: + IMPORT_C static TInt GetIapName(TUint32 aIapId, TIapName& aIapName); + IMPORT_C static TInt GetSnapName(TUint32 aSnapId, TIapName& aSnapName); + + IMPORT_C static TInt GetIapNames(TUint32 aIapId1, TIapName& aIapName1, + TUint32 aIapId2, TIapName& aIapName2); + + +private: + static void DoGetIapNameL(TUint32 aIapId, TIapName& aIapName); + + static void DoGetIapNamesL(TUint32 aIapId1, TIapName& aIapName1, + TUint32 aIapId2, TIapName& aIapName2); + + static void DoGetSnapNameL(TUint32 aSnapId, TIapName& aSnapName); +}; +#endif \ No newline at end of file diff -r 000000000000 -r 33413c0669b9 vpnengine/eventviewer/inc/eventviewer.rls --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventviewer/inc/eventviewer.rls Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Resource definitions for eventViewer. +* +*/ + + + + +/* +rls_string STRING_No_Label1 "" // empty for non-file app's +*/ + +rls_string STRING_r_policy_import_ok "Policy import successful %U %N OK" +rls_string STRING_r_policy_import_failed "Policy import failed %U %N " +rls_string STRING_r_policy_export_failed "Policy file is lost %U %N 12345 " + diff -r 000000000000 -r 33413c0669b9 vpnengine/eventviewer/inc/eventviewer2.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventviewer/inc/eventviewer2.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,284 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Log File Handler. +* +*/ + + +#ifndef __EVENTVIEWER2__ +#define __EVENTVIEWER2__ + +#include +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////// +// Literals +//////////////////////////////////////////////////////// +#include "eventmediatorapi.h" + +#define LOG_ELEM_TRAILER_LTH 12 +#define LOG_ELEM_HEADER_LTH 32 +#define KBYTES_TO_BYTES 1024 +//efine ELEM_HEADER_LTH 8 +#define FILE_BEGIN 0 +#define END_MARK_1 0xefbeadde +#define END_MARK_2 0xeeabedfe +#define LOG_FILE_ID 0x474F4C45 // ELOG + + +///////////////////////////////////////////////////////////////// +// Enumeration of log event categories. +//////////////////////////////////////////////////////////////// + +enum TLogCategory2 + { + ELogInfo, + ELogWarning, + ELogError, + ELogDebug + }; + + +///////////////////////////////////////////////////////// +// TEventProperties - data to be returned with the event +// text to the caller +///////////////////////////////////////////////////////// +struct TEventProperties + +{ + TUint32 iSourceComponent; // Uid of source component + TTime iTimeStamp; // 64 bit time stamp + TLogCategory2 iCategory; // Info, Warning, Error, Debug + TUint32 iMsgId; // MsgId in localization file + TUint32 iEventNumber; // Event number +}; + + +///////////////////////////////////////////////////////// +// Packed File Header +///////////////////////////////////////////////////////// +class TFileHeader +{ + public: // Methods + inline TInt32 GetFileId() const {return ((TInt32)(u.iData32[0]));}; + inline TInt32 GetPositionOfNextFree() const {return ((TInt32)(u.iData32[1]));}; + inline TInt32 GetPositionOfWrapping() const {return ((TInt32)(u.iData32[2]));}; + inline TInt32 GetCurrEventNumber() const {return ((TInt32)(u.iData32[3]));}; + + private: + union + { + TUint32 iData32[4]; + } u; +}; + + + +///////////////////////////////////////////////////////// +// Unpacked File Header +///////////////////////////////////////////////////////// + +class TUnpackedFileHeader + { + public: + TUint32 iFileId; // ELOG + TUint32 iPositionOfNextFree; + TUint32 iPositionOfWrapping; + TUint32 iCurrEventNumber; + }; + +///////////////////////////////////////////////////////// +// Packed Log Element +/////////////////////////////////////////////////////// +class TLogElem + { + public: // Methods + inline TInt32 GetEventLength() const {return ((TInt32)(u.iData32[0]));}; + inline TInt32 GetEventNumber() const {return ((TInt32)(u.iData32[1]));}; + inline TInt64 GetTimeStamp() const + { + return MAKE_TINT64(u.iData32[3], u.iData32[2]);; + }; + inline TInt32 GetSourceComponent() const {return ((TInt32)(u.iData32[4]));}; + inline TLogCategory2 GetCategory() const {return ((TLogCategory2)(u.iData32[5]));}; + inline TInt32 GetMsgId() const {return ((TInt32)(u.iData32[6]));}; + inline TInt32 GetDescrCount() const {return ((TInt32)(u.iData32[7]));}; + +private: + union + { + TUint32 iData32[8]; + } u; + }; + +///////////////////////////////////////////////////////// +// Unpacked Log Element +///////////////////////////////////////////////////////// + +class TUnpackedLogElem +{ + public: + TUint32 iEventLength; + TUint32 iEventNumber; + TInt64 iTimeStamp; + TUint32 iSourceComponent; + TLogCategory2 iCategory; + TUint32 iMsgId; + TUint32 iDescrCount; +}; + +///////////////////////////////////////////////////////// +// Packed Log Element trailer +///////////////////////////////////////////////////////// +class TLogElemTrailer +{ + public: // Methods + inline TInt32 GetEndMark1() const {return ((TInt32)(u.iData32[0]));}; + inline TInt32 GetEndMark2() const {return ((TInt32)(u.iData32[1]));}; + inline TInt32 GetEventLength() const {return ((TInt32)(u.iData32[2]));}; + + private: + union + { + TUint32 iData32[3]; + } u; +}; + +///////////////////////////////////////////////////////// +// Unpacked Element trailer +///////////////////////////////////////////////////////// + +class TUnpackedLogElemTrailer +{ + public: + TUint32 iEndMark1; + TUint32 iEndMark2; + TUint32 iEventLength; +}; + + +///////////////////////////////////////////////////////// +// EventViewer Class +///////////////////////////////////////////////////////// +class CEventViewer : public CBase +{ + + + // + // EventViewer API in EventViewer.cpp + // + public: + IMPORT_C static CEventViewer* NewL(); + IMPORT_C ~CEventViewer(); + void ConstructL(); + + IMPORT_C TInt GetMostRecentEvent (HBufC*& aEventText, + TEventProperties& aEventProperties); + + IMPORT_C TInt GetNextEvent (HBufC*& aEventText, + TEventProperties& aEventProperties); + + IMPORT_C TInt GetPreviousEvent (HBufC*& aEventText, + TEventProperties& aEventProperties); + + IMPORT_C TInt GetEventUsingEventNumber( + HBufC*& aEventText, + TUint32 aEventNumber, + TEventProperties& aEventProperties); + + IMPORT_C TInt GetOldestEvent (HBufC*& aEventText, + TEventProperties& aEventProperties); + + IMPORT_C TInt DeleteLogFile(); + + // + // EventViewer internal functions in EventViewer.cpp + // + private: + TInt GetRequestedEvent( HBufC*& aEventText, + TEventProperties& aEventProperties, + TUint32 aEventNumber, + TInt aMethodId); + + TInt GetRequestedEventL( HBufC*& aEventText, + TEventProperties& aEventProperties, + TUint32 aEventNumber, + TInt aMethodId); + + // + // EventViewer internal functions in LogFileHandler.cpp + // + private: + TInt OpenLogFile(); + void CloseLogFile(); + void TakeCopyOfFileHeader(TUnpackedFileHeader& asrc, + TUnpackedFileHeader& adest); + void OpenResourceFileL(); + + TInt ReadWholeLogFileToMemoryBuffer(); + TInt ReadLogFileHeader(); + TInt CopyPackedFileHeaderToUnpackedObject( TDesC8& aFileHeader); + TBool IsLogFileModified(); + TInt EventLookup(TUint32 aEventNumber); + TInt GetStartPositionOfLogElem(TUint32 aEndOfLogElemPosition, + TUint32* aLogElemPosition); + void CopyPackedLogElemToUnpackedObject(TUint32 iPositionOfCurrLogElem); + HBufC* SearchEventTextL( TUint32 aMsgId); + HBufC* ModifyEventText(HBufC* aEventTextSrc, + TUint32 aDescrCount, // Count of descriptor elements + TUint32 aDescrDataPosition); // Descriptors: lth data lth data.... + HBufC* FormatEvent(TInt aDescrCount, // Count of lth/data pairs + const TDesC8& aDescrList, // lth lth ... data data ... + const TDesC& aEventString); // string got from localisation file + TInt AnalyseConvSpec( + const TDesC& SourceBuf, // + TInt& aOffset, // offset of conversion spec element + TUint32& aConvType, // U or N (KConvTypex) + TUint32& aSeqNumber); // Seq number included to conv spec elem + HBufC* GetDescriptorData ( + TUint32 aDescrCount, // Count of lth/data pairs + const TDesC8& aDescrList, // lth lth ... data data ... + TUint32 aConvType, // KConvTypeN or KConvTypeU + TUint32 aDescrNumber); // Seq number of lth/data pair + TInt BufferAppend(HBufC*& aDestBuf, + const TDesC& aString); + + void DoDeleteLogFileL(); // In LogFileHandler.cpp + + private: + RFs iFS; + REventMediator iEventMediator; + TUnpackedFileHeader iCurrFileHeader; + TUnpackedFileHeader iPreviousFileHeader; + TUnpackedLogElem iUnpackedLogElem; + TUnpackedLogElemTrailer iLogElemTrailer; + TUint32 iRequestedEventNumber; + HBufC8* iLogFileBuf; + TInt iLogFileSize; + TInt iWrappingOccured; + TUint32 iPositionOfCurrLogElem; + RResourceFile iResourceFile; + HBufC* iResultBuf; // Formatted event is build to this buffer + + // + // Current API call parameters + // + HBufC** iEventText; + TEventProperties* iEventProperties; +}; +#endif \ No newline at end of file diff -r 000000000000 -r 33413c0669b9 vpnengine/eventviewer/inc/log_eventviewer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventviewer/inc/log_eventviewer.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Logging utility. +* +*/ + + + +#if !defined(__LOG_EVENTVIEWER_H__) +#define __LOG_EVENTVIEWER_H__ + +_LIT(KLogFile,"eview.txt"); + +#include "logcommon.h" + +#endif // __LOG_EVENTVIEWER_H__ diff -r 000000000000 -r 33413c0669b9 vpnengine/eventviewer/rom/eventviewer.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventviewer/rom/eventviewer.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Image description file for project eventviewer +* +*/ + + + +#ifndef __EVENTVIEWER_IBY__ +#define __EVENTVIEWER_IBY__ + +#ifdef SYMBIAN_EXCLUDE_IPSEC + +REM Feature EVENTVIEWER not included in this rom + +#else + +file=ABI_DIR\BUILD_DIR\eventviewer.dll SHARED_LIB_DIR\eventviewer.dll +data=DATAZ_\RESOURCE_FILES_DIR\vpnlogmessages.rsc RESOURCE_FILES_DIR\vpnlogmessages.rsc + +#endif // SYMBIAN_EXCLUDE_IPSEC + +#endif // __EVENTVIEWER_IBY__ diff -r 000000000000 -r 33413c0669b9 vpnengine/eventviewer/src/eventformater.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventviewer/src/eventformater.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,449 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Event formatting services. +* +*/ + + +#include "eventviewer2.h" + +#define KEventBufferSizeIncrement 1000 +#define KConvTypeU 1 +#define KConvTypeN 2 +#define KConvTypeA 3 + + +/////////////////////////////////////////////////////////////////// +// HBufC* aDestBuf = FormatEvent(TInt aDescrCount, TDesc8 aDescrList, +// aEventString) +// +// This function formats an event string loaded from the localisation +// file by replacing the conversion specification elements with the data +// description parameters available in a log event read from the +// log file. +// +// -- aDestBuf = the result of formatting. The caller have to release +// the buffer +// -- aDescrCount = number of data description elements (lth/data +// pairs) in aDescrList. +// -- aDescrList = LTH, LTH, ... , Data , Data, ... +// -- aEventString = text containing 0 - 20 conversion specification +// elements. The format of conversion specification elements is +// as follows: %N %U or %iN %iU, where % starts a specification, +// N is numeric data, U is Unicode data, i is an optional sequence +// number of description used with this specification (1,2,3...). +// +/////////////////////////////////////////////////////////////////// +HBufC* CEventViewer::FormatEvent(TInt aDescrCount, + const TDesC8& aDescrList, + const TDesC& aEventString) + { + TInt err; + TInt beginOffset; + TInt convSpecOffset; + TInt continueToLoop; + TInt descrNumber; + TInt currDescrNumber; + TUint32 convType; + TUint32 seqNumber; + HBufC* descrBuf = 0; + + // Allocate a buffer for the result data. This buffer will + // contain the modified event string. The buffer may be extended + // during the operation. + + iResultBuf = HBufC::New( KEventBufferSizeIncrement); + if (iResultBuf == 0) + { + return iResultBuf; + } + // + // Prepare to process an event string + // + beginOffset = 0; + err = KErrNone; + continueToLoop = ETrue; + currDescrNumber = 0; + // + // Loop here until all conversion specifications of an event string + // have been processed + // + while (continueToLoop) + { + + // + // Locate a conversion specification element (It begins with '%' + // + + convSpecOffset = aEventString.Mid(beginOffset).Locate('%'); + + // + // If no prefix (%) found, copy the last or the only part + // of text to buffer + // + + if (convSpecOffset == KErrNotFound) + { + TInt lth = aEventString.Length(); + if (lth > beginOffset) + { + TPtrC tempPtr = aEventString.Mid(beginOffset, lth - beginOffset); + err = BufferAppend(iResultBuf, + tempPtr); + } + continueToLoop = EFalse; + continue; + } + + // + // Copy the part preceding the conv spec to the destination buffer + // + TPtrC tempPtr = aEventString.Mid(beginOffset, convSpecOffset); + err = BufferAppend(iResultBuf, + tempPtr); + if (err != KErrNone) + { + continueToLoop = EFalse; + continue; + } + + // + // Analyse the conversion specification element + // + beginOffset += convSpecOffset + 1; + err = AnalyseConvSpec( + aEventString, + beginOffset, + convType, + seqNumber); + if (err != KErrNone) + { + continueToLoop = EFalse; + continue; + } + + // + // Define the seq number of the descriptor element + // + + if (seqNumber == 0) { + currDescrNumber++, // no number in conv spec element + descrNumber = currDescrNumber; + } + else + { + descrNumber = seqNumber; // number available in conv spec element + } + + // + // Find descritptor from the descriptor list and return the data + // + descrBuf = 0; + descrBuf = GetDescriptorData ( + aDescrCount, + aDescrList, + convType, + descrNumber); + if (descrBuf == 0) + { + continue; + } + // + // Store the data got from the descriptor list to the + // destination buffer + // + + err = BufferAppend(iResultBuf, + descrBuf->Des()); + if (err != KErrNone) + { + continueToLoop = EFalse; + continue; + } + delete descrBuf; + descrBuf = 0; + beginOffset++; + } + // + // While loop completed + // + delete descrBuf; + return iResultBuf; + } +/////////////////////////////////////////////////////////////////// +// GetDescriptorData - Searches the requested descriptor and +// returns the data. +// +// -- returns: converted data in heap buffer. Caller must delete the +// buffer. Null if no descriptor returned. +// +// -- aDescrCount defines the number of LTH/DATA pairs +// +// --aDescrList has the following format: +// LTH LTH ... DATA DATA ..., where +// -- LTH is TUint32 length of corresponding DATA +// -- DATA is either 32-bit integer or 8-bit byte strings. +// +// --aConvType has value KConvTypeN (integer to desimal conversion +// needed) or KConvTypeU (Unicode data) +// or KConvTypeA (8-bits data) +// +// -- aDescrNumber is the sequence number of LTH/DATA pair (1, 2..) +// +// +/////////////////////////////////////////////////////////////////// +HBufC* CEventViewer::GetDescriptorData ( + TUint32 aDescrCount, + const TDesC8& aDescrList, + TUint32 aConvType, + TUint32 aDescrNumber) + + { + HBufC* descrDataBuf = 0; + TBuf8<4> lthBuf; + TUint lth = 0;; + + // + // Check that descriptor number is valid + // + if (aDescrNumber > aDescrCount || aDescrNumber == 0) + { + return descrDataBuf; // return Null + } + + TInt dataOffset = 0; + TInt lthOffset = 0; + TUint32 currDescrNumber = 1; + + // + // Search the requested LTH/DATA pair + // + TInt fillerLth = 0; + while (currDescrNumber <= aDescrNumber) + { + lthBuf.Copy(&aDescrList[lthOffset],4); // Copy lth to 4 byte buffer + lth = *(TInt*) (lthBuf.Ptr()); + dataOffset += 4; + fillerLth = 0; + if (currDescrNumber < aDescrNumber) + { + dataOffset += lth; + if (lth % 4 != 0) + { + fillerLth = 4 - (lth % 4); + } + dataOffset += fillerLth; // Remainder is filler count in data + } + lthOffset += 4; + currDescrNumber++; + } + dataOffset += 4 * (aDescrCount - (currDescrNumber - 1)); // rest of lth fields + + // + // Convert integer to character string + // + + if (aConvType == KConvTypeN) + { + TInt intValue; + if (lth != 4) + { + return descrDataBuf; // return 0, because wrong size for integer + } + descrDataBuf = HBufC::New(16); + if (descrDataBuf !=0) + { + TPtr descrDataPtr(descrDataBuf->Des()); + TPtrC8 ptr8 = aDescrList.Mid(dataOffset, 4); + intValue = *(TInt*) (ptr8.Ptr()); + descrDataPtr.Num(intValue); + } + return descrDataBuf; + } + else if (aConvType == KConvTypeA) + + // + // ConvType == A, convert 8-bit string to unicode + // + { + descrDataBuf = HBufC::New(lth); + if (descrDataBuf == 0) + { + return descrDataBuf; + } + TPtr descrDataPtr(descrDataBuf->Des()); + TPtrC8 ptr8 = aDescrList.Mid(dataOffset, lth); + descrDataPtr.Copy(ptr8); + return descrDataBuf; + } + else + + // + // ConvType == U, unicode string, only copy data + // + { + descrDataBuf = HBufC::New(lth/2); + if (descrDataBuf == 0) + { + return descrDataBuf; + } + TPtr descrDataPtr(descrDataBuf->Des()); + TPtrC8 ptr8 = aDescrList.Mid(dataOffset, lth); + TPtrC ptr16(reinterpret_cast(ptr8.Ptr()), ptr8.Length() / 2);; + descrDataPtr.Copy(ptr16); + return descrDataBuf; + } + } + +/////////////////////////////////////////////////////////////////// +// AnalyseConvSpec - Analyse Conversion Specification string +// The format of string is as follows: +// %U or %N or %A or %sU or %sN or %sA where: +// -- % is prefix +// -- U means Unicode (16-bits) data +// -- A means 8-bits data +// -- N means numeric data +// -- s means 1 or 2 character sequence number +/////////////////////////////////////////////////////////////////// +TInt CEventViewer::AnalyseConvSpec( + const TDesC& aSourceBuf, + TInt& aOffset, // input/output + TUint32& aConvType, // U or N + TUint32& aSeqNumber) + { + TInt currOffset = aOffset; + TUint32 seqNumber = 0; + TUint32 convType; + TInt sourceDataLeft = aSourceBuf.Length() - aOffset; + TBuf<2> seqNumberBuf; + + // One byte data should exist + + if (sourceDataLeft < 1) + { + return KErrNotFound; + } + + // Check if 1 or 2 byte long sequence number follows. Value + // should be 1 - 20. + + if (aSourceBuf[currOffset] >= '0' && + aSourceBuf[currOffset] <= '9') + { + seqNumberBuf.Copy(&aSourceBuf[currOffset], 1); + currOffset++; + sourceDataLeft--; + + if (aSourceBuf[currOffset] >= '0' && + aSourceBuf[currOffset] <= '9') + { + seqNumberBuf.Append(&aSourceBuf[currOffset], 1); + currOffset++; + sourceDataLeft--; + } + TLex seqNumberLex(seqNumberBuf); + seqNumberLex.Val(seqNumber, EDecimal); + if (seqNumber == 0 || seqNumber > 20) + { + return KErrNotFound; + } + } + + // One byte data should exist + + if (sourceDataLeft < 1) + { + return KErrNotFound; + } + + // Check if the conversion type is U + + + if (aSourceBuf[currOffset] == 'U' || + aSourceBuf[currOffset] == 'u') + { + convType = KConvTypeU; + } + + // Check if the conversion type is N + + else if + (aSourceBuf[currOffset] == 'N' || + aSourceBuf[currOffset] == 'n') + { + convType = KConvTypeN; + } + + // Check if the conversion type is A + + else if + (aSourceBuf[currOffset] == 'A' || + aSourceBuf[currOffset] == 'a') + { + convType = KConvTypeA; + } + else + { + return KErrNotFound; + } + + // Return parameters to caller + + aConvType = convType; + aOffset = currOffset; + aSeqNumber = seqNumber; + return KErrNone; + } + + + +/////////////////////////////////////////////////////////////// +// BufferAppend() +// This function appends a buffer by storing a new string. +// If the buffer does not have space enough, the function extends +// the buffer. +// +/////////////////////////////////////////////////////////////// +TInt CEventViewer::BufferAppend(HBufC*& aDestBuf, + const TDesC& aString) + { + TInt err = KErrNone; + // Make sure that we have enough space for the new text + + TInt spaceLeft = aDestBuf->Des().MaxLength() - aDestBuf->Des().Length(); + if (aString.Length() > spaceLeft) + { + // Allocate enough space for the new string + some additional + // free space so that allocations are not too frequent + + TInt newMaxLength = aDestBuf->Des().MaxLength() + aString.Length() + KEventBufferSizeIncrement; + HBufC* tempBuf = aDestBuf->ReAlloc(newMaxLength); + if (tempBuf != NULL) + { + aDestBuf = tempBuf; + } + else + { + err = KErrNoMemory; + } + } + // + // Store current string to the buffer + // + aDestBuf->Des().Append(aString); + return err; + } + + + diff -r 000000000000 -r 33413c0669b9 vpnengine/eventviewer/src/eventviewer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventviewer/src/eventviewer.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,653 @@ +/* +* Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Event viewer +* +*/ + + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "eventviewer.h" +#include "eventviewer2.h" +#include "log_eventviewer.h" + +///////////////////////////////////////////// +// Method IDs +//////////////////////////////////////////// +#define KGetMostRecentEvent 0 +#define KGetNextEvent 1 +#define KGetPreviousEvent 2 +#define KGetEventUsingEventNumber 3 + + +////////////////////////////////////////////////////////////// +// Create EventViewer object +///////////////////////////////////////////////////////////// +EXPORT_C CEventViewer* CEventViewer::NewL() + { + CEventViewer *self = new (ELeave) CEventViewer(); + CleanupStack::PushL(self); + self->ConstructL(); + LOG(Log::Printf(_L("Constructing EventViewer\n"))); + CleanupStack::Pop(); // self + return self; + } + +///////////////////////////////////////////////////////////// +// CEventViewer::CEventViewer() +// C++ default constructor +///////////////////////////////////////////////////////////// +// +// CEventViewer::CEventViewer() : iEikonEnv(*iCoeEnv) +// { +// } + +////////////////////////////////////////////////////////////// +// Phase 2 constructor +///////////////////////////////////////////////////////////// +void CEventViewer::ConstructL() + { + TInt status = iFS.Connect(); + if (status != KErrNone) + { + LOG(Log::Printf(_L("iFS.Connect failed %d\n"), status)); + User::Leave(status); + } + + status = iEventMediator.Connect(); + if (status != KErrNone) + { + LOG(Log::Printf(_L("iEventMediator.Connect failed %d\n"), status)); + User::Leave(status); + } + + status = OpenLogFile(); // Open log file and read file header + if (status != KErrNone) + { + LOG(Log::Printf(_L("OpenLogFile failed %d\n"), status)); + User::Leave(status); + } + OpenResourceFileL(); + } +////////////////////////////////////////////////////////////// +// Destructor +///////////////////////////////////////////////////////////// +CEventViewer::~CEventViewer() + { + LOG(Log::Printf(_L("Destructing EventViewer\n"))); + + delete iLogFileBuf; + iLogFileBuf = 0; + CloseLogFile(); + delete iResultBuf; + iResultBuf = 0; + iResourceFile.Close(); + iFS.Close(); + iEventMediator.Close(); + } + +////////////////////////////////////////////////////////////// +// OpenResourceFileL() +// Used in ConstructL to get resource file +////////////////////////////////////////////////////////////// +// +void CEventViewer::OpenResourceFileL() + { + //RResourceFile resourceFile; + _LIT(KResourceFile, "\\resource\\vpnlogmessages.rsc"); + + TFileName resourceFileName(KResourceFile); + TFileName dllName; + Dll::FileName(dllName); + TBuf<2> drive = dllName.Left(2); + resourceFileName.Insert(0, drive); + iResourceFile.OpenL(iFS, resourceFileName); + iResourceFile.ConfirmSignatureL(); + } + + +////////////////////////////////////////////////////////////// +// Release resources allocated for a call +///////////////////////////////////////////////////////////// +//void CEventViewer::ReleaseResourcesL() +// { + +// } + +////////////////////////////////////////////////////////////////// +// +// GetMostRecentEvent +// +///////////////////////////////////////////////////////////////// +EXPORT_C TInt CEventViewer::GetMostRecentEvent( + HBufC*& aEventText, + TEventProperties& aEventProperties) + { + TInt status = GetRequestedEvent( + aEventText, + aEventProperties, + 0, // Event number + KGetMostRecentEvent); + return status; + } +////////////////////////////////////////////////////////////////// +// +// GetNextEvent +// +///////////////////////////////////////////////////////////////// +EXPORT_C TInt CEventViewer::GetNextEvent( + HBufC*& aEventText, + TEventProperties& aEventProperties) + { + TInt status = GetRequestedEvent( + aEventText, + aEventProperties, + 0, // Event number + KGetNextEvent); + return status; + } + +////////////////////////////////////////////////////////////////// +// +// GetPrevousEvent +// +///////////////////////////////////////////////////////////////// +EXPORT_C TInt CEventViewer::GetPreviousEvent( + HBufC*& aEventText, + TEventProperties& aEventProperties) + { + TInt status = GetRequestedEvent( + aEventText, + aEventProperties, + 0, // Event number + KGetPreviousEvent); + return status; + } + +////////////////////////////////////////////////////////////////// +// +// GetEventUsingEventNumber +// +///////////////////////////////////////////////////////////////// +EXPORT_C TInt CEventViewer::GetEventUsingEventNumber( + HBufC*& aEventText, + TUint32 aEventNumber, + TEventProperties& aEventProperties) + { + TInt status = GetRequestedEvent( + aEventText, + aEventProperties, + aEventNumber, + KGetEventUsingEventNumber); + return status; + } + + +////////////////////////////////////////////////////////////////// +// +// GetRequestedEvent - Get Requested Event +// This is a common function for API calls. It searches the event +// that the API user has requested. The function returns a buffer +// containing the event text and TEventProperties structure that +// contains some parameters relating to the event. +// +///////////////////////////////////////////////////////////////// + TInt CEventViewer::GetRequestedEvent( + HBufC*& aEventText, + TEventProperties& aEventProperties, + TUint32 aEventNumber, + TInt aMethodId) + { + TInt status = 0; + TRAPD (err, status = GetRequestedEventL( + aEventText, + aEventProperties, + aEventNumber, + aMethodId)) + + if (err != KErrNone) + { + LOG(Log::Printf(_L("API request failed, status %d\n"), err)); + + status = err; + } + return status; + } + +TInt CEventViewer::GetRequestedEventL( + HBufC*& aEventText, + TEventProperties& aEventProperties, + TUint32 aEventNumber, + TInt aMethodId) + { + TInt status; + LOG(Log::Printf(_L("API request received, method = %d\n"), aMethodId)); + + // + // Store the API parameters to this object + // + iEventText = &aEventText; + iEventProperties = &aEventProperties; + // + // Produce the event number that the user is requesting + // + + switch (aMethodId) + { + case KGetMostRecentEvent: + { + + // Read the log file to memory buffer if not yet done + + if (iLogFileBuf == 0) + { + + status = ReadWholeLogFileToMemoryBuffer(); + if (status != KErrNone) + { + break; + } + TakeCopyOfFileHeader(iCurrFileHeader, iPreviousFileHeader); + } + + // Check if the log file has been modified and read the log + // file header + + else + { + status = ReadLogFileHeader(); + if (status != KErrNone) + { + break; + } + if (IsLogFileModified()) + { + TakeCopyOfFileHeader(iCurrFileHeader, iPreviousFileHeader); + } + } + iRequestedEventNumber = iCurrFileHeader.iCurrEventNumber; + break; + } + + case KGetNextEvent: + { + iRequestedEventNumber++; + break; + } + case KGetPreviousEvent: + { + iRequestedEventNumber--; + break; + } + case KGetEventUsingEventNumber: + { + iRequestedEventNumber = aEventNumber; + break; + } + default: + { + break; + } + } + // + // Check the validity of requested event number + // + + if (iRequestedEventNumber == 0 || + iRequestedEventNumber > iCurrFileHeader.iCurrEventNumber || + iLogFileBuf == 0) // Logfile not yet in memory + { + LOG(Log::Printf(_L("API request completed, requested event not found \n"))); + return KErrNotFound; + } + // + // Search the event from the memory resident log file + // + status = EventLookup(iRequestedEventNumber); + if (status != KErrNone) + { + return status; // Event not found + } + // + // Event found, copy the packed format log element parameters to an + // unpacked object + // + + CopyPackedLogElemToUnpackedObject(iPositionOfCurrLogElem); + + // + // Search the event text relating to the MsgId + // + HBufC* eventTextBuf; + eventTextBuf = SearchEventTextL(iUnpackedLogElem.iMsgId); + if (eventTextBuf == 0) + { + return KErrNoMemory; + } + + // + // Modify the event text with the descriptor data + // DescrPtr points to a list of following elements: + // TInt DataLength + // TInt8 Data + // + + TUint32 descrDataPosition = iPositionOfCurrLogElem + LOG_ELEM_HEADER_LTH; + HBufC* modifiedEventTextBuf = ModifyEventText( + eventTextBuf, + iUnpackedLogElem.iDescrCount, // Count of descriptor elements + descrDataPosition); // Descriptors: lth,lth,...data,data... + if (modifiedEventTextBuf == 0) + { + return KErrNoMemory; + } + // + // An event is available, return data to the caller + // + *iEventText = modifiedEventTextBuf; + iResultBuf = 0; + iEventProperties->iEventNumber = iUnpackedLogElem.iEventNumber; + iEventProperties->iMsgId = iUnpackedLogElem.iMsgId; + TTime tmpTime(iUnpackedLogElem.iTimeStamp); + iEventProperties->iTimeStamp = tmpTime; + iEventProperties->iSourceComponent = iUnpackedLogElem.iSourceComponent; + iEventProperties->iCategory = iUnpackedLogElem.iCategory; + LOG(Log::Printf(_L("API request completed OK \n"))); + + return KErrNone; + + } + + + ////////////////////////////////////////////////////////////////////// + // EventLookup + // This function searches an event from the log file buffer that + // matches with the requested event number. + ////////////////////////////////////////////////////////////////////// +TInt CEventViewer::EventLookup(TUint32 aEventNumber) + { + TUint32 positionOfLogElemEnd = iCurrFileHeader.iPositionOfNextFree; + TUint32 positionOfLogElem; + TInt searchGoing = ETrue; + TInt status = KErrNone; + iWrappingOccured = EFalse; + // + // Loop here until matching event found or end of elements reached + // or any error found + // + + while (searchGoing && status == KErrNone) + { + // + // Check if wrapping 1 + // + if (positionOfLogElemEnd == EVENTLOG_FILE_HEADER_LTH) + { + + + if (iCurrFileHeader.iPositionOfWrapping != 0) + { + positionOfLogElemEnd = iCurrFileHeader.iPositionOfWrapping; // Wrapping occurs + iWrappingOccured = ETrue; + } + else + { + status = KErrNotFound; + continue; + } + } + + // + // Produce the start position of an event + // + + status = GetStartPositionOfLogElem( positionOfLogElemEnd, + &positionOfLogElem); + if (status != KErrNone) + { + continue; + } + + // + // Check if requested event has been found + // + + if (iUnpackedLogElem.iEventNumber != aEventNumber) + { + positionOfLogElemEnd = positionOfLogElem; + continue; // Not found, continue + } + // + // Requested event found, stop the loop + // + status = KErrNone; + iPositionOfCurrLogElem = positionOfLogElem; + searchGoing = EFalse; + + } + + return status; + } + + +///////////////////////////////////////////////////////////////////// +// SearchEventText +// This function searches from the localization file the text string +// relating to the MsgId parameter and allocates an buffer in which +// it returns the data to the caller. +// +///////////////////////////////////////////////////////////////////// + +HBufC* CEventViewer::SearchEventTextL( TUint32 aMsgId) + { + HBufC8* resourceBuf = NULL; + HBufC* textDataBuf = NULL; + + // + // MsgId is a code defined in epoc32\include\eventviewererr.rsg + // file. It refers to a message in .rsc file. + // + TInt msgNumber = STATIC_CAST(TInt, aMsgId); + resourceBuf = iResourceFile.AllocReadL( msgNumber); + + TResourceReader resourceReader; + + resourceReader.SetBuffer(resourceBuf); + + textDataBuf = HBufC::New(resourceBuf->Length()); + if (textDataBuf) + { + TPtr textDataPtr(textDataBuf->Des()); + + resourceReader.Read((void*)textDataBuf->Ptr(), resourceBuf->Length()); + textDataPtr.SetLength(resourceBuf->Length()/2); + } + + delete resourceBuf; + return textDataBuf; + } + +///////////////////////////////////////////////////////////////////// +// ModifyEventText +// This function modifies the event text by the descriptors. +// Both the event text and descriptors are parameters of the +// function. +// +///////////////////////////////////////////////////////////////////// + +HBufC* CEventViewer::ModifyEventText( + HBufC* aEventTextSrc, + TUint32 aDescrCount, // Count of descriptor elements + TUint32 aDescrDataPosition) // Descriptors: lth data lth data.... + { + HBufC* modifiedEventText; + + // + // If descriptors exist, build pointer to the first + // length definition. The format of descriptor data + // is as follows: + // -- TUInt32 Length of parameter 1 (lth1) + // -- TUInt32 Length of parameter 2 (lth2) + // -- TUInt32 Length of parameter n (lthx) + // -- TInt8[lth1] Data 1 + // -- TInt8[lth2] Data 2 + // -- TInt8[lthx] Data n + // Variable length data, The format of + // data is defined by the conversion + // specification characters in the text string + // + + // + // No descriptors, return localisation data buffer + // + if (aDescrCount == 0) + { + return aEventTextSrc; + } + + // + // Build TPtr8 pointer for descriptor list + // + + TInt descrLth = iUnpackedLogElem.iEventLength - + LOG_ELEM_HEADER_LTH - + LOG_ELEM_TRAILER_LTH; + TPtr8 logFileBuf (iLogFileBuf->Des()); // Log file in memory + TPtr8 descrListPtr (const_cast(logFileBuf.Ptr())+ aDescrDataPosition, // Data ptr + descrLth, // Data length + descrLth); // Max length + // + // Modify the localisation data buffer with the descriptor data + // + modifiedEventText = FormatEvent( + aDescrCount, + descrListPtr, + aEventTextSrc->Des()); + + + delete aEventTextSrc; + return modifiedEventText; + } + + +///////////////////////////////////////////////////////////////////// +// GetIapName +// These functions are used to convert an IAP ID to IAP name. +// +//////////////////////////////////////////////////////////////////// +EXPORT_C TInt EventViewer::GetIapName(TUint32 aIapId, TIapName& aIapName) + { + TRAPD(err, DoGetIapNameL(aIapId, aIapName)); + return err; + } + +EXPORT_C TInt EventViewer::GetSnapName(TUint32 aSnapId, TIapName& aSnapName) + { + TRAPD(err, DoGetSnapNameL(aSnapId, aSnapName)); + return err; + } + +EXPORT_C TInt EventViewer::GetIapNames(TUint32 aIapId1, TIapName& aIapName1, + TUint32 aIapId2, TIapName& aIapName2) + { + TRAPD(err, DoGetIapNamesL(aIapId1, aIapName1, aIapId2, aIapName2)); + return err; + } + +void EventViewer::DoGetIapNameL(TUint32 aIapId, TIapName& aIapName) + { + using namespace CMManager; + + RCmManagerExt cmManagerExt; + cmManagerExt.OpenL(); + CleanupClosePushL(cmManagerExt); + + RCmConnectionMethodExt connectionMethod = cmManagerExt.ConnectionMethodL( aIapId ); + CleanupClosePushL(connectionMethod); + + HBufC* cmName = connectionMethod.GetStringAttributeL(ECmName); // Ownership passed + + aIapName.Copy(*cmName); + delete cmName; + cmName = NULL; + + CleanupStack::PopAndDestroy(&connectionMethod); + CleanupStack::PopAndDestroy(&cmManagerExt); + } + +void EventViewer::DoGetIapNamesL(TUint32 aIapId1, TIapName& aIapName1, + TUint32 aIapId2, TIapName& aIapName2) + { + using namespace CMManager; + + RCmManagerExt cmManagerExt; + cmManagerExt.OpenL(); + CleanupClosePushL(cmManagerExt); + + RCmConnectionMethodExt connectionMethod1 = cmManagerExt.ConnectionMethodL( aIapId1 ); + CleanupClosePushL(connectionMethod1); + + HBufC* cmName1 = connectionMethod1.GetStringAttributeL(ECmName); + CleanupStack::PushL(cmName1); + + aIapName1.Copy(*cmName1); + + RCmConnectionMethodExt connectionMethod2 = cmManagerExt.ConnectionMethodL( aIapId2 ); + CleanupClosePushL(connectionMethod2); + + HBufC* cmName2 = connectionMethod2.GetStringAttributeL(ECmName); // Ownership passed + + aIapName2.Copy(*cmName2); + + delete cmName2; + cmName2 = NULL; + CleanupStack::PopAndDestroy(4); + } + + +void EventViewer::DoGetSnapNameL(TUint32 aSnapId, TIapName& aSnapName) + { + RCmManagerExt cmManagerExt; + cmManagerExt.OpenL(); + CleanupClosePushL(cmManagerExt); + + RCmDestinationExt destination = cmManagerExt.DestinationL( aSnapId ); + CleanupClosePushL(destination); + + HBufC* snapName16bit = destination.NameLC(); + CnvUtfConverter::ConvertFromUnicodeToUtf8(aSnapName, *snapName16bit); + CleanupStack::PopAndDestroy(snapName16bit); + + CleanupStack::PopAndDestroy(); //destination + CleanupStack::PopAndDestroy(); //cmManagerExt + } + +///////////////////////////////////////////////////////////////////// +// DeleteLogFile +// This function deletes the eventlog.bin file +// +//////////////////////////////////////////////////////////////////// +EXPORT_C TInt CEventViewer::DeleteLogFile() + { + TRAPD(err, DoDeleteLogFileL()); + return err; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/eventviewer/src/logfilehandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/eventviewer/src/logfilehandler.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,315 @@ +/* +* Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Log file handler +* +*/ + + + +#include "eventviewer2.h" +#include "log_eventviewer.h" +//#include "logcommon.h" + +/////////////////////////////////////////////////////////////////// +// OpenLogFile +// This function checks the state of the LogFile and tries to open +// the file if it is not yet open. It also reads the header section +// of the file and checks that the file is a correct log file. +/////////////////////////////////////////////////////////////////// +TInt CEventViewer::OpenLogFile() + { + TInt status = ReadLogFileHeader(); + if (status != KErrNone) + { + return status; + } + + TakeCopyOfFileHeader(iCurrFileHeader, iPreviousFileHeader); + return KErrNone; + } + +/////////////////////////////////////////////////////////////////// +// CloseLogFile +// This function closes the log file +/////////////////////////////////////////////////////////////////// +void CEventViewer::CloseLogFile() + { + ; + } + +/////////////////////////////////////////////////////////////////// +// DoDeleteLogFileL +// This function deletes the event log file +/////////////////////////////////////////////////////////////////// +void CEventViewer::DoDeleteLogFileL() + { + CloseLogFile(); + TInt status = iEventMediator.ClearEventLog(); + LOG(Log::Printf(_L("Log cleared %d\n"), status)); + if (status != KErrNone) + { + User::Leave(status); + } + } + +/////////////////////////////////////////////////////////////////// +// ReadWholeLogFileToMemoryBuffer() +// +// This function reads the whole log file to a memory buffer +// and takes a new version of file header. +/////////////////////////////////////////////////////////////////// +TInt CEventViewer::ReadWholeLogFileToMemoryBuffer() + { + TInt status; + status = iEventMediator.GetEventLogSize(iLogFileSize); + if (status != KErrNone) + { + return status; + } + if (iLogFileSize < EVENTLOG_FILE_HEADER_LTH) + { + return KErrNotFound; + } + + delete iLogFileBuf; + iLogFileBuf = 0; + + iLogFileBuf = HBufC8::New(iLogFileSize + 2048); // 2048: it can be bigger now + if (iLogFileBuf == 0) + { + return KErrNoMemory; + } + + TPtr8 ptr(iLogFileBuf->Des()); + status = iEventMediator.GetEventLogData(ptr); + if (status != KErrNone) + { + return status; + } + + status = CopyPackedFileHeaderToUnpackedObject(ptr); + if (status != KErrNone) + { + return status; + } + return KErrNone; + } + +/////////////////////////////////////////////////////////////////// +// ReadLogFileHeader +// This function reads the packed format file header section of the +// event log file and copies the contents of header to the +// caller's unpacked object. +/////////////////////////////////////////////////////////////////// +TInt CEventViewer::ReadLogFileHeader() + { + TBuf8 fileHeaderBuf; + TInt status = iEventMediator.GetEventLogHeader(fileHeaderBuf); + if (status != KErrNone) + { + return status; + } + + status = CopyPackedFileHeaderToUnpackedObject(fileHeaderBuf); + if (status != KErrNone) + { + return status; + } + + return KErrNone; + } + +/////////////////////////////////////////////////////////////////// +// TakeCopyOfFileHeader +// This function takes a copy of the unpacked file header. +/////////////////////////////////////////////////////////////////// +void CEventViewer::TakeCopyOfFileHeader(TUnpackedFileHeader& asrc, + TUnpackedFileHeader& adest) + { + adest.iFileId = asrc.iFileId; + adest.iPositionOfNextFree = asrc.iPositionOfNextFree; + adest.iPositionOfWrapping = asrc.iPositionOfWrapping; + adest.iCurrEventNumber = asrc.iCurrEventNumber; + } + +/////////////////////////////////////////////////////////////////// +// CopyPackedFileHeaderToUnpackedObject +// This function copies the packet format file header to an +// unpacked object. +/////////////////////////////////////////////////////////////////// +TInt CEventViewer::CopyPackedFileHeaderToUnpackedObject( TDesC8& aFileHeader) + { + + // Convert the TDesC8 parameter to TUint8* format + + TFileHeader* fileHeader = (TFileHeader*) aFileHeader.Ptr(); + + // Copy the packet format header parameters to unpacked object + + iCurrFileHeader.iFileId = fileHeader->GetFileId(); + iCurrFileHeader.iPositionOfNextFree = fileHeader->GetPositionOfNextFree(); + iCurrFileHeader.iPositionOfWrapping = fileHeader->GetPositionOfWrapping(); + iCurrFileHeader.iCurrEventNumber = fileHeader->GetCurrEventNumber(); + + // Check the file Id + + if (iCurrFileHeader.iFileId != LOG_FILE_ID) + { + return KErrNotFound; + } + + return KErrNone; + } + +/////////////////////////////////////////////////////////////////// +// IsLogFileModified +// Check if the logfile has been modified (file header is no more +// the same as previously) +/////////////////////////////////////////////////////////////////// +TBool CEventViewer::IsLogFileModified() + { + + if (iCurrFileHeader.iFileId == iPreviousFileHeader.iFileId + && + iCurrFileHeader.iPositionOfNextFree == iPreviousFileHeader.iPositionOfNextFree) + { + return EFalse; + } + return ETrue; + } + + + +/////////////////////////////////////////////////////////////////// +// GetStartPositionOfLogElem +// This function calculates the start position of a log element. +// As input parameter it has the position of the first byte +// after the element. +/////////////////////////////////////////////////////////////////// +TInt CEventViewer::GetStartPositionOfLogElem(TUint32 aPositionOfLogElemEnd, + TUint32* aPositionOfLogElem) + { + + // Set base for the most recent log element trailer + + TPtr8 logFileBuf (iLogFileBuf->Des()); // Log file in memory + TUint32 logElemTrailerPos = aPositionOfLogElemEnd - LOG_ELEM_TRAILER_LTH; + + if (iWrappingOccured && logElemTrailerPos <= iCurrFileHeader.iPositionOfNextFree) + { + + return KErrNotFound; + } + + TPtr8 elemTrailer (const_cast(logFileBuf.Ptr())+ logElemTrailerPos, // Data ptr + LOG_ELEM_TRAILER_LTH, // Data length + LOG_ELEM_TRAILER_LTH); // Max length + // Convert the TPtr8 parameter to TUint8* format + + TLogElemTrailer* elemTrailerPtr = (TLogElemTrailer*) elemTrailer.Ptr(); + + // Copy the packet format trailer parameters to unpacked object + + iLogElemTrailer.iEndMark1 = elemTrailerPtr->GetEndMark1(); + iLogElemTrailer.iEndMark2 = elemTrailerPtr->GetEndMark2(); + iLogElemTrailer.iEventLength = elemTrailerPtr->GetEventLength(); + + // Check the validity of trailer + + if (iLogElemTrailer.iEndMark1 != END_MARK_1 + || + iLogElemTrailer.iEndMark2 != END_MARK_2 + || + iLogElemTrailer.iEventLength > aPositionOfLogElemEnd + + EVENTLOG_FILE_HEADER_LTH) + { + + return KErrGeneral; + } + + // Set position for the current log element + + TUint32 logElemPos = aPositionOfLogElemEnd - iLogElemTrailer.iEventLength; + + if (iWrappingOccured && logElemPos < iCurrFileHeader.iPositionOfNextFree) + { + + return KErrNotFound; + } + + TPtr8 logElem (const_cast(logFileBuf.Ptr())+ logElemPos, // Data ptr + iLogElemTrailer.iEventLength, // Data length + iLogElemTrailer.iEventLength); + + // Convert the TPtr8 parameter to TUint8* format + + TLogElem* logElemPtr = (TLogElem*) logElem.Ptr(); + + // Copy the event number and event length parameters + // from packed format log element to unpacked object + + iUnpackedLogElem.iEventLength = logElemPtr->GetEventLength(); + iUnpackedLogElem.iEventNumber = logElemPtr->GetEventNumber(); + + // Verify the extracted data + + if (iUnpackedLogElem.iEventNumber > iCurrFileHeader.iCurrEventNumber + || + iUnpackedLogElem.iEventLength != iLogElemTrailer.iEventLength) + { + + return KErrGeneral; + } + + *aPositionOfLogElem = logElemPos; + + return KErrNone; + + } + + // + // Event found, copy the packed format log element parameters to an + // unpacked object + // + + +/////////////////////////////////////////////////////////////////// +// CopyPackedFileHeaderToUnpackedObject +// This function copies the packet format log file element to an +// unpacked object. +/////////////////////////////////////////////////////////////////// +void CEventViewer::CopyPackedLogElemToUnpackedObject(TUint32 aPositionOfCurrLogElem) + { + // Build the log element pointer + + TPtr8 logFileBuf (iLogFileBuf->Des()); // Log file in memory + TPtr8 logElem (const_cast(logFileBuf.Ptr())+ aPositionOfCurrLogElem, // Data ptr + iUnpackedLogElem.iEventLength, // Data length + iUnpackedLogElem.iEventLength); // Max length + + // Convert the TPtr8 parameter to TUint8* format + + TLogElem* logElemPtr = (TLogElem*) logElem.Ptr(); + + + // Copy the packet format header parameters to unpacked object + + iUnpackedLogElem.iMsgId = logElemPtr->GetMsgId(); + iUnpackedLogElem.iTimeStamp = logElemPtr->GetTimeStamp(); + iUnpackedLogElem.iSourceComponent = logElemPtr->GetSourceComponent(); + iUnpackedLogElem.iCategory = logElemPtr->GetCategory(); + iUnpackedLogElem.iDescrCount = logElemPtr->GetDescrCount(); + + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/EABI/ikecertU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/EABI/ikecertU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,57 @@ +EXPORTS + _ZN10CIkeCaElem4NewLEP6HBufC8 @ 1 NONAME + _ZN10CIkeCaElemD0Ev @ 2 NONAME + _ZN10CIkeCaElemD1Ev @ 3 NONAME + _ZN10CIkeCaElemD2Ev @ 4 NONAME + _ZN10CIkeCaListC1Ei @ 5 NONAME + _ZN10CIkeCaListC2Ei @ 6 NONAME + _ZN11IkePkiUtils13CastCertArrayEPK13CArrayFixFlatIPK18TCertificateISAKMPE @ 7 NONAME + _ZN11IkePkiUtils16CertifyIdentityLEPK16CX509CertificateR6TDesC8i @ 8 NONAME + _ZN11IkePkiUtils16VerifyCertChainLERK13CArrayFixFlatIP16CX509CertificateERS2_RK10CIkeCaList @ 9 NONAME + _ZN11IkePkiUtils18VerifyCertificateLERK13CArrayFixFlatIP17TCertPayloadIkev2ERK10CIkeCaList @ 10 NONAME + _ZN11IkePkiUtils18VerifyCertificateLERK13CArrayFixFlatIPK18TCertificateISAKMPERK10CIkeCaList @ 11 NONAME + _ZN11IkePkiUtils20GetIdentityFromCertLEhRK6TDesC8 @ 12 NONAME + _ZN11IkePkiUtils21VerifyIkev1SignatureLERK6TDesC8S2_RK16CX509Certificate @ 13 NONAME + _ZN11IkePkiUtils21VerifyIkev2SignatureLERK6TDesC8S2_RK16CX509Certificate @ 14 NONAME + _ZN11IkePkiUtils22GetCertSubjectNameDERLEPK16CX509CertificateR5TDes8 @ 15 NONAME + _ZN16CIkeV1PkiService10ReadChainLEP8CIkeDataPK6HBufC8 @ 16 NONAME + _ZN16CIkeV1PkiService12GetTrustedCAEv @ 17 NONAME + _ZN16CIkeV1PkiService14GetCertificateEv @ 18 NONAME + _ZN16CIkeV1PkiService14GetTrustedICA1Ev @ 19 NONAME + _ZN16CIkeV1PkiService14GetTrustedICA2Ev @ 20 NONAME + _ZN16CIkeV1PkiService14ImportCACertsLEP13CArrayFixFlatIP9TCertInfoE @ 21 NONAME + _ZN16CIkeV1PkiService15Ikev1SignatureLERK6TDesC8P8CIkeDataS2_R5TDes8 @ 22 NONAME + _ZN16CIkeV1PkiService21ReadUserCertWithNameLERK6TDesC8P8CIkeDatai @ 23 NONAME + _ZN16CIkeV1PkiService4NewLEP8CIkeDataR9MIkeDebug @ 24 NONAME + _ZN16CIkeV1PkiService6CaListEv @ 25 NONAME + _ZN16CIkeV1PkiServiceD0Ev @ 26 NONAME + _ZN16CIkeV1PkiServiceD1Ev @ 27 NONAME + _ZN16CIkeV1PkiServiceD2Ev @ 28 NONAME + _ZN16CIkeV2PkiService15Ikev2SignatureLERK6TDesC8RK12TOwnCertInfoS2_R5TDes8h @ 29 NONAME + _ZN16CIkeV2PkiService19InitIkeV2PkiServiceEPK8CIkeData @ 30 NONAME + _ZN16CIkeV2PkiService27ReadTrustedUserCertificateLEv @ 31 NONAME + _ZN16CIkeV2PkiService4NewLER24MIkeV2PkiServiceObserverR9MIkeDebug @ 32 NONAME + _ZN16CIkeV2PkiServiceD0Ev @ 33 NONAME + _ZN16CIkeV2PkiServiceD1Ev @ 34 NONAME + _ZN16CIkeV2PkiServiceD2Ev @ 35 NONAME + _ZN7IkeCert22GetSubjectAltNameDataLEPK16CX509Certificateh @ 36 NONAME + _ZN7IkeCert23GetCertificateFieldDERLEP6HBufC8i @ 37 NONAME + _ZN7IkeCert23GetCertificateFieldDERLEPK16CX509Certificatei @ 38 NONAME + _ZNK10CIkeCaElem11CertificateEv @ 39 NONAME + _ZNK10CIkeCaElem7KeyHashEv @ 40 NONAME + _ZNK16CIkeV2PkiService13TrustedCaNameEv @ 41 NONAME + _ZNK16CIkeV2PkiService17I1CertificateDataEv @ 42 NONAME + _ZNK16CIkeV2PkiService17I2CertificateDataEv @ 43 NONAME + _ZNK16CIkeV2PkiService19UserCertificateDataEv @ 44 NONAME + _ZNK16CIkeV2PkiService6CaListEv @ 45 NONAME + _ZTI10CIkeCaElem @ 46 NONAME ; ## + _ZTI10CIkeCaList @ 47 NONAME ; ## + _ZTI13CIkePublicKey @ 48 NONAME ; ## + _ZTI16CIkeV1PkiService @ 49 NONAME ; ## + _ZTI16CIkeV2PkiService @ 50 NONAME ; ## + _ZTV10CIkeCaElem @ 51 NONAME ; ## + _ZTV10CIkeCaList @ 52 NONAME ; ## + _ZTV13CIkePublicKey @ 53 NONAME ; ## + _ZTV16CIkeV1PkiService @ 54 NONAME ; ## + _ZTV16CIkeV2PkiService @ 55 NONAME ; ## + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/bwins/IKECERTU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/bwins/IKECERTU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,40 @@ +EXPORTS + ??0CIkeCaList@@QAE@H@Z @ 1 NONAME ; CIkeCaList::CIkeCaList(int) + ??1CIkeCaElem@@UAE@XZ @ 2 NONAME ; CIkeCaElem::~CIkeCaElem(void) + ??1CIkeV1PkiService@@UAE@XZ @ 3 NONAME ; CIkeV1PkiService::~CIkeV1PkiService(void) + ??1CIkeV2PkiService@@UAE@XZ @ 4 NONAME ; CIkeV2PkiService::~CIkeV2PkiService(void) + ?CaList@CIkeV1PkiService@@QAEPAVCIkeCaList@@XZ @ 5 NONAME ; class CIkeCaList * CIkeV1PkiService::CaList(void) + ?CaList@CIkeV2PkiService@@QBEABVCIkeCaList@@XZ @ 6 NONAME ; class CIkeCaList const & CIkeV2PkiService::CaList(void) const + ?CastCertArray@IkePkiUtils@@CAPBV?$CArrayFixFlat@PAVTCertPayloadIkev2@@@@PBV?$CArrayFixFlat@PB$$CBVTCertificateISAKMP@@@@@Z @ 7 NONAME ; class CArrayFixFlat const * IkePkiUtils::CastCertArray(class CArrayFixFlat const *) + ?Certificate@CIkeCaElem@@QBEPAVCX509Certificate@@XZ @ 8 NONAME ; class CX509Certificate * CIkeCaElem::Certificate(void) const + ?CertifyIdentityL@IkePkiUtils@@SAHPBVCX509Certificate@@AAVTDesC8@@H@Z @ 9 NONAME ; int IkePkiUtils::CertifyIdentityL(class CX509Certificate const *, class TDesC8 &, int) + ?GetCertSubjectNameDERL@IkePkiUtils@@SAHPBVCX509Certificate@@AAVTDes8@@@Z @ 10 NONAME ; int IkePkiUtils::GetCertSubjectNameDERL(class CX509Certificate const *, class TDes8 &) + ?GetCertificate@CIkeV1PkiService@@QAEPAVHBufC8@@XZ @ 11 NONAME ; class HBufC8 * CIkeV1PkiService::GetCertificate(void) + ?GetCertificateFieldDERL@IkeCert@@SAPAVHBufC8@@PAV2@H@Z @ 12 NONAME ; class HBufC8 * IkeCert::GetCertificateFieldDERL(class HBufC8 *, int) + ?GetCertificateFieldDERL@IkeCert@@SAPAVHBufC8@@PBVCX509Certificate@@H@Z @ 13 NONAME ; class HBufC8 * IkeCert::GetCertificateFieldDERL(class CX509Certificate const *, int) + ?GetIdentityFromCertL@IkePkiUtils@@SAPAVHBufC8@@EABVTDesC8@@@Z @ 14 NONAME ; class HBufC8 * IkePkiUtils::GetIdentityFromCertL(unsigned char, class TDesC8 const &) + ?GetSubjectAltNameDataL@IkeCert@@SAPAVHBufC8@@PBVCX509Certificate@@E@Z @ 15 NONAME ; class HBufC8 * IkeCert::GetSubjectAltNameDataL(class CX509Certificate const *, unsigned char) + ?GetTrustedCA@CIkeV1PkiService@@QAEPAVHBufC8@@XZ @ 16 NONAME ; class HBufC8 * CIkeV1PkiService::GetTrustedCA(void) + ?GetTrustedICA1@CIkeV1PkiService@@QAEPAVHBufC8@@XZ @ 17 NONAME ; class HBufC8 * CIkeV1PkiService::GetTrustedICA1(void) + ?GetTrustedICA2@CIkeV1PkiService@@QAEPAVHBufC8@@XZ @ 18 NONAME ; class HBufC8 * CIkeV1PkiService::GetTrustedICA2(void) + ?I1CertificateData@CIkeV2PkiService@@QBEABVTDesC8@@XZ @ 19 NONAME ; class TDesC8 const & CIkeV2PkiService::I1CertificateData(void) const + ?I2CertificateData@CIkeV2PkiService@@QBEABVTDesC8@@XZ @ 20 NONAME ; class TDesC8 const & CIkeV2PkiService::I2CertificateData(void) const + ?Ikev1SignatureL@CIkeV1PkiService@@QAEHABVTDesC8@@PAVCIkeData@@0AAVTDes8@@@Z @ 21 NONAME ; int CIkeV1PkiService::Ikev1SignatureL(class TDesC8 const &, class CIkeData *, class TDesC8 const &, class TDes8 &) + ?Ikev2SignatureL@CIkeV2PkiService@@QAEHABVTDesC8@@ABVTOwnCertInfo@@0AAVTDes8@@E@Z @ 22 NONAME ; int CIkeV2PkiService::Ikev2SignatureL(class TDesC8 const &, class TOwnCertInfo const &, class TDesC8 const &, class TDes8 &, unsigned char) + ?ImportCACertsL@CIkeV1PkiService@@QAEHPAV?$CArrayFixFlat@PAUTCertInfo@@@@@Z @ 23 NONAME ; int CIkeV1PkiService::ImportCACertsL(class CArrayFixFlat *) + ?InitIkeV2PkiService@CIkeV2PkiService@@QAEXPBVCIkeData@@@Z @ 24 NONAME ; void CIkeV2PkiService::InitIkeV2PkiService(class CIkeData const *) + ?KeyHash@CIkeCaElem@@QBEABVTDesC8@@XZ @ 25 NONAME ; class TDesC8 const & CIkeCaElem::KeyHash(void) const + ?NewL@CIkeCaElem@@SAPAV1@PAVHBufC8@@@Z @ 26 NONAME ; class CIkeCaElem * CIkeCaElem::NewL(class HBufC8 *) + ?NewL@CIkeV1PkiService@@SAPAV1@PAVCIkeData@@AAVMIkeDebug@@@Z @ 27 NONAME ; class CIkeV1PkiService * CIkeV1PkiService::NewL(class CIkeData *, class MIkeDebug &) + ?NewL@CIkeV2PkiService@@SAPAV1@AAVMIkeV2PkiServiceObserver@@AAVMIkeDebug@@@Z @ 28 NONAME ; class CIkeV2PkiService * CIkeV2PkiService::NewL(class MIkeV2PkiServiceObserver &, class MIkeDebug &) + ?ReadChainL@CIkeV1PkiService@@QAEHPAVCIkeData@@PBVHBufC8@@@Z @ 29 NONAME ; int CIkeV1PkiService::ReadChainL(class CIkeData *, class HBufC8 const *) + ?ReadTrustedUserCertificateL@CIkeV2PkiService@@AAEXXZ @ 30 NONAME ; void CIkeV2PkiService::ReadTrustedUserCertificateL(void) + ?ReadUserCertWithNameL@CIkeV1PkiService@@QAEHABVTDesC8@@PAVCIkeData@@H@Z @ 31 NONAME ; int CIkeV1PkiService::ReadUserCertWithNameL(class TDesC8 const &, class CIkeData *, int) + ?TrustedCaName@CIkeV2PkiService@@QBEABVTDesC8@@XZ @ 32 NONAME ; class TDesC8 const & CIkeV2PkiService::TrustedCaName(void) const + ?UserCertificateData@CIkeV2PkiService@@QBEABVTDesC8@@XZ @ 33 NONAME ; class TDesC8 const & CIkeV2PkiService::UserCertificateData(void) const + ?VerifyCertChainL@IkePkiUtils@@SAPAVCX509Certificate@@ABV?$CArrayFixFlat@PAVCX509Certificate@@@@AAPAV2@ABVCIkeCaList@@@Z @ 34 NONAME ; class CX509Certificate * IkePkiUtils::VerifyCertChainL(class CArrayFixFlat const &, class CX509Certificate * &, class CIkeCaList const &) + ?VerifyCertificateL@IkePkiUtils@@SAPAVCX509Certificate@@ABV?$CArrayFixFlat@PAVTCertPayloadIkev2@@@@ABVCIkeCaList@@@Z @ 35 NONAME ; class CX509Certificate * IkePkiUtils::VerifyCertificateL(class CArrayFixFlat const &, class CIkeCaList const &) + ?VerifyCertificateL@IkePkiUtils@@SAPAVCX509Certificate@@ABV?$CArrayFixFlat@PB$$CBVTCertificateISAKMP@@@@ABVCIkeCaList@@@Z @ 36 NONAME ; class CX509Certificate * IkePkiUtils::VerifyCertificateL(class CArrayFixFlat const &, class CIkeCaList const &) + ?VerifyIkev1SignatureL@IkePkiUtils@@SAHABVTDesC8@@0ABVCX509Certificate@@@Z @ 37 NONAME ; int IkePkiUtils::VerifyIkev1SignatureL(class TDesC8 const &, class TDesC8 const &, class CX509Certificate const &) + ?VerifyIkev2SignatureL@IkePkiUtils@@SAHABVTDesC8@@0ABVCX509Certificate@@@Z @ 38 NONAME ; int IkePkiUtils::VerifyIkev2SignatureL(class TDesC8 const &, class TDesC8 const &, class CX509Certificate const &) + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Build information file +* +*/ + + + +PRJ_PLATFORMS + +PRJ_EXPORTS + + +PRJ_MMPFILES +#ifdef VPNCLIENT_USE_STUBS + ikecerttest.mmp +#else + ikecert.mmp +#endif + +PRJ_TESTMMPFILES diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/group/ikecert.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/group/ikecert.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project ikecert +* +*/ + + + +#include + +TARGET ikecert.dll +TARGETTYPE DLL +UID 0x1000008d 0x10206995 + +CAPABILITY CAP_SERVER CommDD NetworkControl +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE ikev1pkiservice.cpp +SOURCE ikecert.cpp +SOURCE ikecaelem.cpp +SOURCE ikepublickey.cpp +SOURCE ikecalist.cpp +SOURCE ikepkiutils.cpp +SOURCE ikev2pkiservice.cpp + +USERINCLUDE ../inc +USERINCLUDE ../../kmdserver/inc +USERINCLUDE ../../ikeutils/inc +USERINCLUDE ../../ikev2lib/inc +USERINCLUDE ../../pkiserviceapi/inc +USERINCLUDE ../../ikepolparser/inc +USERINCLUDE ../../utlcrypto/inc +USERINCLUDE ../../../vpnapiimpl/inc +USERINCLUDE ../../utlpkcs10/inc +USERINCLUDE ../../vpnmanager/inc + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY euser.lib +LIBRARY x509.lib +LIBRARY x500.lib +LIBRARY crypto.lib +LIBRARY asn1.lib +LIBRARY pkiserviceapi.lib +LIBRARY utlcrypto.lib +LIBRARY utlpkcs10.lib +LIBRARY ikepolparser.lib +LIBRARY insock.lib +LIBRARY charconv.lib +DEBUGLIBRARY flogger.lib diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/group/ikecerttest.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/group/ikecerttest.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Test project definition file for project ikecert +* +*/ + + + +#include + +TARGET ikecert.dll +TARGETTYPE DLL +UID 0x1000008d 0x10206995 + +CAPABILITY CAP_SERVER CommDD NetworkControl +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE ikev1pkiservice.cpp +SOURCE ikecert.cpp +SOURCE ikecaelem.cpp +SOURCE ikepublickey.cpp +SOURCE ikecalist.cpp +SOURCE ikepkiutils.cpp +SOURCE ikev2pkiservice.cpp + +USERINCLUDE ../inc +USERINCLUDE ../../kmdserver/inc +USERINCLUDE ../../ikeutils/inc +USERINCLUDE ../../ikev2lib/inc +USERINCLUDE ../../pkiserviceapi/inc +USERINCLUDE ../../ikepolparser/inc +USERINCLUDE ../../utlcrypto/inc +USERINCLUDE ../../../vpnapiimpl/inc +USERINCLUDE ../../utlpkcs10/inc +USERINCLUDE ../../vpnmanager/inc + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY ikecert_proxy.lib +LIBRARY euser.lib +LIBRARY x509.lib +LIBRARY x500.lib +LIBRARY crypto.lib +LIBRARY asn1.lib +LIBRARY pkiserviceapi.lib +LIBRARY utlcrypto.lib +LIBRARY utlpkcs10.lib +LIBRARY ikepolparser.lib +LIBRARY insock.lib +LIBRARY charconv.lib +DEBUGLIBRARY flogger.lib + + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/inc/ikecaelem.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/inc/ikecaelem.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class containing information about one CA cert +* +*/ + + + +#ifndef C_IKECAELEM_H +#define C_IKECAELEM_H + +#include + +class CX509Certificate; + +/** + * Class containing the certificate and it's key info. + * + * @lib IkeCert.lib + * @since S60 v3.0 + */ +class CIkeCaElem : public CBase + { +public: + IMPORT_C static CIkeCaElem* NewL(HBufC8* aCert); + IMPORT_C ~CIkeCaElem(); + + IMPORT_C CX509Certificate* Certificate() const; + IMPORT_C const TDesC8& KeyHash() const; + +private: + CX509Certificate* iCaCert; + HBufC8* iKeyInfo; + }; + +#endif // C_IKECAELEM_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/inc/ikecalist.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/inc/ikecalist.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class containing list of CAs +* +*/ + + + +#ifndef C_IKECALIST_H +#define C_IKECALIST_H + +#include + + +class CIkeCaElem; +/** + * CA List + * List of CAs + * + * @lib IkeCert + * @since S60 v3.0 + */ +class CIkeCaList : public CArrayPtrFlat + { +public: + IMPORT_C CIkeCaList(TInt aGranularity); + ~CIkeCaList(); + CIkeCaElem* FindCaElem(const TDesC8& aKeyIdentifier) const; + }; + +#endif // ? C_IKECALIST_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/inc/ikecert.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/inc/ikecert.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: General utility methods for certificate handling +* +*/ + + + + +#ifndef IKECERT_H +#define IKECERT_H + + +#include + +class CX500DistinguishedName; +class CX509Certificate; + +/** + * General utility methods for certificate handling + * + * Contains static methods, which can be user to check thinks from + * certificates. + * + * @lib IkeCert.lib + */ +class IkeCert + { +public: + IMPORT_C static HBufC8* GetCertificateFieldDERL(HBufC8* aCertBfr, TInt aField); + IMPORT_C static HBufC8* GetCertificateFieldDERL(const CX509Certificate *aCert, TInt aField); + static TBool AltNameExistsL(const CX509Certificate *aX509Cert, const TDesC8 &aId); + IMPORT_C static HBufC8* GetSubjectAltNameDataL(const CX509Certificate *aX509Cert, TUint8 aIkeIdType); + static HBufC8* BuildPkcs1v15HashL(const TDesC8 &aHashIn); + static void CleanupSequence(TAny* aArray); + static TInt CheckValidityPeriod(const CX509Certificate& aCert, TInt aWarningMargin, TInt aErrorMargin ); + static TInt VerifyCertExtensionsL(const CX509Certificate& aX509Cert); + +private: + static TUint8* BERGetLengthL(TUint8* aP, TInt &aLen); + }; + + +#endif // IKECERT_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/inc/ikecertconst.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/inc/ikecertconst.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE cert definitions. +* +*/ + +#ifndef IKECERTCONST_H_ +#define IKECERTCONST_H_ + +const TInt KKmdIkeNoCertFoundErr = -5261; + +const TInt KSubjectName = 1; +const TInt KPublicKeyInfo = 2; +const TInt KIssuerName = 3; +#endif /*IKECERTCONST_H_*/ diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/inc/ikepkiutils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/inc/ikepkiutils.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,149 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: static method for certficate handling +* +*/ + + + + +#ifndef IKEPKIUTILS_H +#define IKEPKIUTILS_H + +#include + +class CX509Certificate; +class TCertPayloadIkev2; +class CIkeCaList; +class TCertificateISAKMP; +class TASN1DecGeneric; + +class IkePkiUtils + { +public: + + /* + * Verifies an IKEv2 signature with a public of + * specified certificate + * + * @param aSignature Signature data verified. + * @param aAuthData Data signed. + * @param aCert Certificate which contains the public key used for verification + * @result ETrue if signature is vefified OK, otherwise EFalse + */ + IMPORT_C static TBool VerifyIkev2SignatureL(const TDesC8& aSignature, + const TDesC8& aRefHash, + const CX509Certificate& aCerts); + + + /* + * Verifies an IKEv1 signature with a public of + * specified certificate + * + * @param aSignature Signature data verified. + * @param aRefHash Hash data which has been signed (= Encrypted with private key) + * @param aCert Certificate which contains the public key used for verification + * @result ETrue if signature is vefified OK, otherwise EFalse + */ + IMPORT_C static TBool VerifyIkev1SignatureL(const TDesC8& aSignature, + const TDesC8& aRefHash, + const CX509Certificate& aCerts); + + /* + * Gets IKE DER encoded Subject Name from the certificate and + * copy it into specified buffer + * + * @param aCert Certificate object pointer + * @param aSubjectName Reference to the subject name (returned) + * @result ETrue if operation succeeded, otherwise EFalse + */ + IMPORT_C static TBool GetCertSubjectNameDERL(const CX509Certificate* aCert, + TDes8& aSubjectName); + + /* + * Gets IKE identity data from specified certificate + * + * @param aIdType Specified IKE Identity type wanted. + * @param aCertData Certificate data from where the specified Identity data is taken + * @result The identity data buffer of NULL + */ + IMPORT_C static HBufC8* GetIdentityFromCertL(TUint8 aIdType, const TDesC8& aCertData); + + + /* + * Ccertifies a specified IKE identity with + * Certificate Identities + * + * @param aCert Verified user certificate + * @param aId IKE identity data used by peer + * @param aIdType IKE identity type + * @result ETrue if Identity is certified otherwise EFalse + */ + IMPORT_C static TBool CertifyIdentityL(const CX509Certificate* aCert, + TDesC8& aId, TInt aIdType); + + + /* + * Verifies the user Certificate used by the IKE peer. + * + * @param aCerts The array of IKE certificate payload(s) from where verified + * Certificate is found + * @result A pointer to a verified X509 certificate or NULL + */ + IMPORT_C static CX509Certificate* VerifyCertificateL(const CArrayFixFlat& aCerts, + const CIkeCaList& aTrustedCAList); + + + /* + * Verifies the user Certificate used by the IKE peer. + * + * @param aCerts The array of IKE certificate payload(s) from where verified + * Certificate is found + * @result A pointer to a verified X509 certificate or NULL + */ + IMPORT_C static CX509Certificate* VerifyCertificateL(const CArrayFixFlat& aCerts, + const CIkeCaList& aTrustedCAList); + + IMPORT_C static CX509Certificate* VerifyCertChainL(const CArrayFixFlat& aCerts, CX509Certificate*& realUserCert,const CIkeCaList& aTrustedCAList); + +private: + static TBool VerifySignatureL(const TInt aIkeVersion, + const TDesC8& aSignature, + const TDesC8& aRefHash, + const CX509Certificate& aCert); + + static CArrayPtrFlat* DecodeDERL(const TDesC8& aPtr, TInt& aPosition); + + /* + * Verifies user certificate by taking the following actions: + * -- Verify the signature of the user certificate with the public + * key of the CA certificate. + * -- Check the validity of the user certificate + * -- Check that extension field of the user certificate are correct + */ + static CX509Certificate* VerifyX509CertificateL(const CX509Certificate& aCaCert, + CX509Certificate& aCert); + + + static CX509Certificate* FindCaCertificateL(const CX509Certificate& aUserCert, + const CIkeCaList& aTrustedCAList); + + static const CArrayFixFlat* CastCertArray(const CArrayFixFlat* aCerts); + + + + + }; + +#endif //IKEPKIUTILS_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/inc/ikepublickey.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/inc/ikepublickey.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class containing information about one public key +* +*/ + + + +#ifndef C_IKEPUBLICKEY_H +#define C_IKEPUBLICKEY_H + +#include +#include "pkidefs.h" + +class CX509Certificate; + +/** + * Class containing information about one public key. + * Contains: key parameters, key data and key type info. + * + * @lib IkeCert.lib + * @since S60 v3.0 + */ +class CIkePublicKey : public CBase + { +public: + static CIkePublicKey* NewL(const CX509Certificate& aCert); + ~CIkePublicKey(); + + TPKIKeyAlgorithm Algorithm() const; + const TDesC8& KeyData() const; + const TDesC8& KeyParams() const; + +private: + CIkePublicKey(); + + HBufC8* iKeyParams; + HBufC8* iKeyData; + TPKIKeyAlgorithm iAlgorithm; + }; + +#endif // ? C_PUBLICKEY_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/inc/ikev1pkiservice.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/inc/ikev1pkiservice.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,165 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: PKI store and Certificate verification interface for IKEv1 +* plug-in +* +*/ + +#ifndef C_IKEV1PKISERVICE_H +#define C_IKEV1PKISERVICE_H + +#include +#include + +#include "pkiserviceapi.h" +#include "ikepolparser.h" + +class CX509Certificate; +class TASN1DecGeneric; + +class CIkeData; +class CIkeCaList; +class TCertPayloadIkev2; +class TCReqPayloadIkev2; +class TCertificateISAKMP; +class MIkePlugInServices; +class MIkeDebug; +class CIkeCaElem; +// +// CIkeV1PkiService Class +// +class CIkeV1PkiService : public CBase +{ + public: + IMPORT_C static CIkeV1PkiService* NewL( CIkeData* aIkeData, + MIkeDebug& aDebug ); + IMPORT_C ~CIkeV1PkiService(); + + + IMPORT_C TBool ImportCACertsL(CArrayFixFlat *aCAList); + IMPORT_C TInt ReadUserCertWithNameL(const TDesC8& aTrustedCaName, CIkeData* aIkeData, TBool aDnType); + IMPORT_C TInt Ikev1SignatureL(const TDesC8& aTrustedCaName, CIkeData* aIkeData, const TDesC8& aHashIn, TDes8& aSignature); + IMPORT_C CIkeCaList* CaList(); + IMPORT_C HBufC8* GetCertificate(); + IMPORT_C HBufC8* GetTrustedCA(); + IMPORT_C HBufC8* GetTrustedICA1(); + IMPORT_C HBufC8* GetTrustedICA2(); + IMPORT_C TInt ReadChainL(CIkeData* aIkeData, const HBufC8* aCAName); + + private: + CIkeV1PkiService( CIkeData* aIkeData, + MIkeDebug& aDebug ); + void ConstructL(); + + TInt ComputeSignatureL(const TDesC8& aTrustedAuthority, const TDesC8& aHashIn, TDes8& aSignature, TBool aRsaSignature); + TInt ReadCertificateL(const TDesC8& aTrustedAuthority, TBool aGetCACert); + + /** + * Initialized user certificate identification member variables. + * The information is taken from the policy file. + * Only the ID data, which is available is set, other + * data is zeroed. + * + * @result the size of the key, if available in the policy, zero otherwise. + */ + TUint InitUserCertIdentDataL(); + TBool GetNextCaElemL(); + TBool AddNextCaElemL(TInt& aStatus); + TInt GetNextCertificateL(); + TBool CertificateReadL(TInt& aStatus); + + TInt ReadCertificateL(const TPKIKeyIdentifier& aKeyIdentifier); + TInt ReadCertificateListL(); + TInt GetCertificateWithKeyIdL(const TDesC16& aKeyIdString); + TBool GetApplUidListL(const TDesC16& aApplUidString); + TBool ApplUidCertListCompletedL(TInt aStatus); + TBool ReadNextInListL(); + + +#ifdef _DEBUG + void CertReadCompleted(TBool aCaCert, TInt aStatus, TInt aLine ); + void HexToString(const TDesC8& aKeyId, TDes16& aKeyIdString); +#endif + + + private: + TInt iOperation; // Current operation ongoing + RPKIServiceAPI iPkiService; // PKI Service handle + CIkeCaList* iTrustedCAList; // Trusted CA certificate list + + TInt iCurrIndex; // Current index in name list + CArrayFixFlat* iCaNameList; // CA name list delivered + HBufC8* iCaName; // Ca name work buffer + HBufC8* iCa2Name; // Level 1 Intermediate Certificate + HBufC8* iCa1Name; // Level 2 Intermediate Certificate + + CIkeData* iIkeData; // Current policy data object + + RPointerArray iCasTrustedByPeer; // CA name list delivered + + HBufC8* iReadCertificate; // Certificate stream + HBufC8* iReadCertificateOrig; // Certificate stream of original own certificate + HBufC8* iSubjName; // Subject alt name buffer + HBufC8* iRfc822Name; // RFC822 name buffer + + TPtr8 iCertPtr; // For Pkiserviceapi calls + TAny* iResArray; // For Pkiserviceapi calls + TBool iReallocated; // Certificate buffer enlarged + TInt iCertBfrSize; // Certificate buffer size + + TPKIKeyIdentifier iCertKeyId; // Certficate keyid + RArray* iApplUidList; // Application UID list + CArrayFix* iCaCertList; // Applicable CA cert list + TInt iListIndex; // Current index in CA cert list + TBool iUserCertDerType; //0=ASCII, 1=DER + MIkeDebug& iDebug; + +}; + + +// +// CIkePkiService operation codes (iOperation) +// +const TInt KNoOperation = 0; +const TInt KBuildingCaList = 1; +const TInt KReadingCertificate = 2; +const TInt KProcessingApplUidList = 3; +const TInt KBuildingApplUidList = 4; +const TInt KSigning = 5; +const TInt KDecrypting = 6; + + +// +// Certificate field indicators for GetCertificateFieldDERL() +// + +#define IKEV2_CERT_KEYID_SIZE 20 +// +//Extra Errors for IkeCert::VerifyCertificateL() +// +const TInt KCertVerifyErrBadType = 1; +const TInt KCertVerifyErrNotValidYet = 2; +const TInt KCertVerifyErrExpired = 3; +const TInt KCertVerifyWithinMargin = 4; +const TInt KCertVerifyCriticalExt = 5; +const TInt KCertVerifyKeyUsageErr = 6; +const TInt KCertVerifyCACertificate = 7; + +const TInt KDefaultErrorMargin = 3600; // Default error marginal in Validity + +const TInt KSha1hashLth = 20; +const TInt KCertKeyIdLth = 20; // Certificate Key Identifier length = Length of SHA1 hash + + +#endif // C_IKEV1PKISERVICE_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/inc/ikev2pkiservice.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/inc/ikev2pkiservice.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,181 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 specifig certificate reading related stuff +* +*/ + + +#ifndef C_IKEV2PKISERVICE_H +#define C_IKEV2PKISERVICE_H + +#include + +#include "pkiserviceapi.h" + +class CIkeCaElem; +class TCertInfo; +class TCReqPayloadIkev2; +class CIkeData; +class CIkeCaList; +class MIkeV2PkiServiceObserver; +class TOwnCertInfo; +class MIkeDebug; + + +class CIkeV2PkiService : public CActive + { +public: + enum TIkeV2PkiServiceState + { + EPkiServiceIdle = 0, + EBuildingCaList, + EReadingCertificate, + EReadingCertificateChain + }; + + + + IMPORT_C static CIkeV2PkiService* NewL(MIkeV2PkiServiceObserver& aObserver, MIkeDebug& aDebug); + IMPORT_C ~CIkeV2PkiService(); + + + /** + * Reads all the CA certs defined in the list to the memory. + * + * This method is completed by calling: + * MIkeV2PkiServiceObserver::IkeV2PkiInitComleteL + * + * @param aCAList List of CA's, which are retrieved. + */ + IMPORT_C void InitIkeV2PkiService(const CIkeData* aIkeData); + + /* + * Computes IKEv2 signature with a specified private key. + * Actually a signature computed happens by referring the related certificate + * when the PKI store produces the signature with corresponding private key. + * + * @param aTrustedAuthority Trusted CA name coded either in ASN1 (DN) format or ASCII format + * @param aOwnCertInfo Own cert info from the IKE policy + * @param aMsgOctets Message data signed. A SHA1 hash is calculated over these message + * octets and result is encoded as PKCS1v15 signature before + * encrypted with private key + * @result signature length. + */ + IMPORT_C TInt Ikev2SignatureL(const TDesC8& aTrustedAuthority, + const TOwnCertInfo& aOwnCertInfo, + const TDesC8& aMsgOctets, + TDes8& aSignature, TUint8 aAuthMeth); + + + /** + * Returns a list of trusted CA certificates. + * If the InitIkeV2PkiService method is not called + * successfully before this method is called an + * empty list is returned. + * + * @result a list of trusted CA certificates. + */ + IMPORT_C const CIkeCaList& CaList() const; + + + /** + * + */ + IMPORT_C const TDesC8& UserCertificateData() const; + + IMPORT_C const TDesC8& I2CertificateData() const; + IMPORT_C const TDesC8& I1CertificateData() const; + /** + * Returns the name of the trsuted authority of + * user certificate. + * + * If no user certificates are loaded an empty string is returned. + * + * @result the name of the trusted authority of the user certificate. + */ + IMPORT_C const TDesC8& TrustedCaName() const; + +protected: + void DoCancel(); + void RunL(); + TInt RunError(TInt aError); + +private: + CIkeV2PkiService(MIkeV2PkiServiceObserver& aObserver, MIkeDebug& aDebug); + void ConstructL(); + + void ReadTrustedUserCertificateL(); + void ReadUserCertificateL(const TDesC8& aTrustedAuthority, TBool aGetCACert); + void ReadCertificateChainL(); + + + void InitIkeV2PkiServiceL(); + void ImportNextCaElemFromIkeDataListL(); + void BuildingCaListRunL(); + void ReadUserCertificateRunL(); + void ReadCertificateChainRunL(); + + static void CIkeV2PkiServiceApplUidArrayCleanup(TAny* any); + + + void SignalObserverL(TInt aStatus); +private: + MIkeV2PkiServiceObserver& iObserver; + MIkeDebug& iDebug; + + RPKIServiceAPI iPkiService; // PKI Service handle + TIkeV2PkiServiceState iState; // Current state + + HBufC8* iCaName; // Ca name work buffer + const CIkeData* iIkeData; // Current policy data object + + + HBufC8* iReadCertificate; // Certificate stream + TPtr8 iCertPtr; // For Pkiserviceapi calls + + HBufC8* iSubjName; // Subject alt name buffer + HBufC8* iRfc822Name; // RFC822 name buffer + TPKIKeyIdentifier iCertKeyId; // Certficate keyid + + TAny* iResArray; // For Pkiserviceapi calls + + RPointerArray iCasTrustedByPeer; // CA name list delivered + CArrayFixFlat* iIkeDataCAList; + CIkeCaList* iTrustedCAList; // Trusted CA certificate list + HBufC8* iUserCertificate; + HBufC8* i2Certificate; // Intermediate certificate Level 2 + HBufC8* i2CertificateName; + HBufC8* i1Certificate; // Intermediate certificate Level 1 + }; + + +/** +* IKE PKI service request complete +* @internalComponent +*/ +class MIkeV2PkiServiceObserver +{ + public: + /** + * IKE PKI service operation completed + * @internalComponent + * @param aStatus completion status of operation + * @param aObject pointer to CIkePkiService object + * + */ + virtual void IkeV2PkiInitCompleteL(TInt aStatus)=0; +}; + + +#endif //C_IKEV2PKISERVICE_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/inc/vpnlogger.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/inc/vpnlogger.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,108 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Logging code fot the dmadpki +* +*/ + + + + + +#ifndef VPNLOGGER_H +#define VPNLOGGER_H + +#if defined(_DEBUG) + +#include +#include + + +NONSHARABLE_CLASS(TTraceItem) + { +public: + inline TTraceItem(const TDesC& aTraceName); + inline ~TTraceItem(); + + inline static void TraceCleanupOperation(TAny* aItem); +private: + + HBufC* iTraceName; + TBool iMethodHasLeft; + }; + + +NONSHARABLE_CLASS(CVpnDebugLogger) : public CBase + { +public: + + inline static void InitializeDebugLoggerL(const TDesC& aFolder, const TDesC& aFileName); + inline static void FinalizeDebugLogger(); + inline static void LogWrite(const TDesC& aText); + inline static void LogWrite(const TDesC8& aText); + + inline static void LogWriteF(TRefByValue aFmt, ...); + inline static void LogWriteF(TRefByValue aFmt, ...); + + + inline static void HexWrite(const TDesC8& aData); + + +private: + inline void ConstructL(const TDesC& aFolder, const TDesC& aFileName); + inline ~CVpnDebugLogger(); + + inline static void TimeStamp(TDes& aBuffer); + inline static CVpnDebugLogger* VpnDebugLogger(); + + inline void WriteLogRaw(const TDesC& aLogMessage); + + + RFileLogger iFileLogger; + TUint iCallDepth; + + TBuf<512> iDebugString; + friend class TTraceItem; + + TUint8 iReferenceCount; + }; + +#define INITIALIZE_DEBUG_LOG_L(a, b) CVpnDebugLogger::InitializeDebugLoggerL((a), (b)) +#define FINALIZE_DEBUG_LOG CVpnDebugLogger::FinalizeDebugLogger(); + +/** + * Trace can't be used inside LC methods. + */ +#define TRACE(a) TTraceItem __trace(TPtrC((const TText *)L ## a)) +#define DEBUG_LOG(a) CVpnDebugLogger::LogWrite(a) +#define DEBUG_LOG1(a, b) CVpnDebugLogger::LogWriteF((a), (b)) +#define DEBUG_LOG2(a, b, c) CVpnDebugLogger::LogWriteF((a), (b), (c)) + +#define DEBUG_LOG_HEX(a) CVpnDebugLogger::HexWrite((a)) + +#include "vpnlogger.inl" + +#else + +#define INITIALIZE_DEBUG_LOG_L(a, b) +#define FINALIZE_DEBUG_LOG +#define TRACE(a) +#define DEBUG_LOG(a) +#define DEBUG_LOG1(a, b) +#define DEBUG_LOG2(a, b, c) + +#define DEBUG_LOG_HEX(a) + + +#endif //!defined(_DEBUG) +#endif //VPNLOGGER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/inc/vpnlogger.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/inc/vpnlogger.inl Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,359 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Logging code fot the dmadpki +* +*/ + + + + +#if defined(_DEBUG) + + +_LIT(KTraceOutOfMemory, "TRACE out of memory"); + +_LIT(KInMark, ">"); +_LIT(KOutMark, "<"); +_LIT(KDepthMark, "-"); +_LIT(KSeparator, " "); +_LIT(KLeaveFrom, "LEAVE FROM: "); + + + +void TTraceItem::TraceCleanupOperation(TAny* aItem) + { + + TTraceItem* traceCleanupItem = static_cast(aItem); + CVpnDebugLogger* logger = CVpnDebugLogger::VpnDebugLogger(); + logger->iCallDepth--; + + logger->iDebugString.Zero(); + + CVpnDebugLogger::TimeStamp(logger->iDebugString); + logger->iDebugString.Append(KLeaveFrom); + logger->iDebugString.Append(*(traceCleanupItem->iTraceName)); + logger->WriteLogRaw(logger->iDebugString); + + delete traceCleanupItem->iTraceName; + + traceCleanupItem->iMethodHasLeft = ETrue; + } + + +TTraceItem::TTraceItem(const TDesC& aTraceName) + { + iMethodHasLeft = EFalse; + + CVpnDebugLogger* logger = CVpnDebugLogger::VpnDebugLogger(); + + iTraceName = aTraceName.Alloc(); + if (iTraceName != NULL) + { + if (logger != NULL) + { + logger->iCallDepth++; + + logger->iDebugString.Zero(); + CVpnDebugLogger::TimeStamp(logger->iDebugString); + + for (TInt i = 0; i < logger->iCallDepth; ++i) + { + logger->iDebugString.Append(KDepthMark); + } + + logger->iDebugString.Append(KInMark); + logger->iDebugString.Append(KSeparator); + logger->iDebugString.Append(*iTraceName); + logger->WriteLogRaw(logger->iDebugString); + } + CleanupStack::PushL(TCleanupItem(TTraceItem::TraceCleanupOperation, this)); + } + else + { + if (logger != NULL) + { + logger->WriteLogRaw(KTraceOutOfMemory); + } + } + } + + +TTraceItem::~TTraceItem() + { + CVpnDebugLogger* logger = CVpnDebugLogger::VpnDebugLogger(); + + + if (!iMethodHasLeft) + { + if (iTraceName != NULL) + { + if (logger != NULL) + { + logger->iDebugString.Zero(); + CVpnDebugLogger::TimeStamp(logger->iDebugString); + logger->iDebugString.Append(KOutMark); + for (TInt i = 0; i < logger->iCallDepth; ++i) + { + logger->iDebugString.Append(KDepthMark); + } + + logger->iDebugString.Append(KSeparator); + logger->iDebugString.Append(*iTraceName); + logger->WriteLogRaw(logger->iDebugString); + + logger->iCallDepth--; + } + delete iTraceName; + CleanupStack::Pop(this); + + } + else + { + if (logger != NULL) + { + logger->WriteLogRaw(KTraceOutOfMemory); + } + } + } + } + + + +void CVpnDebugLogger::InitializeDebugLoggerL(const TDesC& aFolder, const TDesC& aFileName) + { + + CVpnDebugLogger* self = static_cast(Dll::Tls()); + if (self == NULL) + { + self = new (ELeave) CVpnDebugLogger; + CleanupStack::PushL(self); + self->ConstructL(aFolder, aFileName); + User::LeaveIfError(Dll::SetTls(self)); + CleanupStack::Pop(self); + } + self->iReferenceCount++; + } + + +void CVpnDebugLogger::ConstructL(const TDesC& aFolder, const TDesC& aFileName) + { + User::LeaveIfError(iFileLogger.Connect()); + iFileLogger.SetDateAndTime(EFalse, EFalse); + iFileLogger.CreateLog(aFolder, aFileName, EFileLoggingModeAppend); + } + + +CVpnDebugLogger::~CVpnDebugLogger() + { + if ( iFileLogger.Handle() != 0 ) + { + iFileLogger.Write(_L("Logger delete")); + iFileLogger.CloseLog(); + } + + iFileLogger.Close(); + } + + +void CVpnDebugLogger::FinalizeDebugLogger() + { + CVpnDebugLogger* self = static_cast(Dll::Tls()); + __ASSERT_ALWAYS(self != NULL, User::Invariant()); + + self->iReferenceCount--; + + if (self->iReferenceCount == 0) + { + Dll::SetTls(NULL); + delete self; + } + } + + +CVpnDebugLogger* CVpnDebugLogger::VpnDebugLogger() + { + return static_cast(Dll::Tls()); + } + + +void CVpnDebugLogger::WriteLogRaw(const TDesC& aLogMessage) + { + iFileLogger.Write(aLogMessage); + } + + +void CVpnDebugLogger::LogWrite(const TDesC& aText) + { + CVpnDebugLogger* logger = VpnDebugLogger(); + logger->iDebugString.Zero(); + CVpnDebugLogger::TimeStamp(logger->iDebugString); + + if (logger->iCallDepth > 0) + { + for (TUint i = 0; i < logger->iCallDepth; ++i) + { + logger->iDebugString.Append(_L(" ")); + } + logger->iDebugString.Append(_L(" ")); + } + + logger->iDebugString.Append(aText); + logger->WriteLogRaw(logger->iDebugString); + } + + +void CVpnDebugLogger::LogWrite(const TDesC8& aText) + { + CVpnDebugLogger* logger = VpnDebugLogger(); + logger->iDebugString.Zero(); + CVpnDebugLogger::TimeStamp(logger->iDebugString); + + if (logger->iCallDepth > 0) + { + for (TUint i = 0; i < logger->iCallDepth; ++i) + { + logger->iDebugString.Append(_L(" ")); + } + logger->iDebugString.Append(_L(" ")); + } + + TInt stringLength = logger->iDebugString.Length(); + TUint spaceLeft = logger->iDebugString.MaxLength() - stringLength; + + TUint16* ptr = const_cast(logger->iDebugString.Ptr() + stringLength); + TPtr buffer(ptr, spaceLeft); + buffer.Copy(aText); + + logger->iDebugString.SetLength(stringLength + buffer.Length()); + logger->WriteLogRaw(logger->iDebugString); + } + + +void CVpnDebugLogger::LogWriteF(TRefByValue aFmt, ...) + { + VA_LIST list; + VA_START(list,aFmt); + + + CVpnDebugLogger* logger = VpnDebugLogger(); + logger->iDebugString.Zero(); + CVpnDebugLogger::TimeStamp(logger->iDebugString); + + if (logger->iCallDepth > 0) + { + for (TUint i = 0; i < logger->iCallDepth; ++i) + { + logger->iDebugString.Append(_L(" ")); + } + logger->iDebugString.Append(_L(" ")); + } + + + const TDesC& format = aFmt; + + logger->iDebugString.AppendFormatList(format, list); + logger->WriteLogRaw(logger->iDebugString); + } + + + +void CVpnDebugLogger::LogWriteF(TRefByValue aFmt, ...) + { + TBuf8<512> buf; + + VA_LIST list; + VA_START(list,aFmt); + + const TDesC8& format = aFmt; + buf.FormatList(format, list); + + LogWrite(buf); + } + + +void CVpnDebugLogger::HexWrite(const TDesC8& aData) + { + const TUint KRowLength = 16; //16 bytes in one row + + TBuf<128> row; + + TUint rowCount = aData.Length() / KRowLength; + if (aData.Length() % KRowLength != 0) + { + rowCount++; + } + + for (TInt i = 0; i < rowCount; ++i) + { + _LIT(KRowStartFormat, "%04x: "); + TPtrC8 rowData(aData.Mid(KRowLength*i)); + + row.Zero(); + row.Format(KRowStartFormat, i*KRowLength); + TInt j; + for (j = 0; j < KRowLength; ++j) + { + if ( j < rowData.Length()) + { + _LIT(KDataByteFormat, "%02x "); + TUint8 byte = rowData[j]; + row.AppendFormat(KDataByteFormat, byte); + } + else + { + row.Append(_L(" ")); + } + } + + for (j = 0; j < KRowLength && j < rowData.Length(); ++j) + { + TUint8 byte = rowData[j]; + if (byte >= ' ' && byte <= '~') + { + row.Append(byte); + } + else + { + row.Append(_L(".")); + } + } + + + LogWrite(row); + } + } + + +void CVpnDebugLogger::TimeStamp(TDes& aBuffer) + { + TTime time; + time.HomeTime(); + TDateTime dateTime = time.DateTime(); + + + _LIT(KFormatTxt,"%02d/%02d/%d %02d:%02d:%02d.%03d "); + aBuffer.Format(KFormatTxt, + dateTime.Day()+1, + TInt(dateTime.Month()+1), + dateTime.Year(), + + dateTime.Hour(), dateTime.Minute(), dateTime.Second(), + dateTime.MicroSecond() + ); + + + } + + +#endif //defined(_DEBUG) diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/rom/ikecert.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/rom/ikecert.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Image description file for project ikecert +* +*/ + + + +#ifndef __IKECERT_IBY__ +#define __IKECERT_IBY__ + +#ifdef SYMBIAN_EXCLUDE_IPSEC + +REM Feature IKECERT not included in this rom + +#else + +file=ABI_DIR\BUILD_DIR\ikecert.dll SHARED_LIB_DIR\ikecert.dll + +#endif + +#endif // __IKECERT_IBY__ diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/src/ikecaelem.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/src/ikecaelem.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class containing information about one CA cert +* +*/ + + + + +#include + +#include "ikecaelem.h" +#include "ikecert.h" +#include "utlcrypto.h" +#include "ikev1pkiservice.h" +#include "ikecertconst.h" + +EXPORT_C CIkeCaElem* CIkeCaElem::NewL(HBufC8* aCert) + { + ASSERT(aCert); + CIkeCaElem* CaElem = new (ELeave) CIkeCaElem(); + CleanupStack::PushL(CaElem); + CaElem->iCaCert = CX509Certificate::NewL(*aCert); + delete aCert; + HBufC8* PublicKeyInfo = IkeCert::GetCertificateFieldDERL(CaElem->iCaCert, KPublicKeyInfo); + CleanupStack::PushL(PublicKeyInfo); + + // + // Calculate "Key Id" value as a SHA1 hash Subject Public Key Info element + // (specified so in IKEv2 draft) + // + CaElem->iKeyInfo = HBufC8::NewL(IKEV2_CERT_KEYID_SIZE); + CUtlMessageDigest* Digest = TUtlCrypto::MakeMessageDigesterL(TUtlCrypto::EUtlMessageDigestSha1); + TPtrC8 InData(PublicKeyInfo->Des()); + TPtrC8 KeyId = Digest->Final(InData); + CaElem->iKeyInfo->Des().Copy(KeyId); + delete Digest; + + CleanupStack::PopAndDestroy(PublicKeyInfo); + CleanupStack::Pop(CaElem); + return CaElem; + } + + +EXPORT_C CIkeCaElem::~CIkeCaElem() + { + delete iCaCert; + delete iKeyInfo; + } + + +EXPORT_C CX509Certificate* CIkeCaElem::Certificate() const + { + return iCaCert; + } + + +EXPORT_C const TDesC8& CIkeCaElem::KeyHash() const + { + return *iKeyInfo; + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/src/ikecalist.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/src/ikecalist.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class containing list of CAs +* +*/ + + + +#include "ikecalist.h" +#include "ikecaelem.h" + + +EXPORT_C CIkeCaList::CIkeCaList(TInt aGranularity) +:CArrayPtrFlat(aGranularity) + { + } + + +CIkeCaList::~CIkeCaList() + { + ResetAndDestroy(); + } + +CIkeCaElem* CIkeCaList::FindCaElem(const TDesC8& aKeyIdentifier) const + { + // + // Find a CIkeCaElem element using aKeyIdentifier as search argument + // + CIkeCaElem* result = NULL; + TInt i = 0; + TInt count = Count(); + while ( i < count ) + { + CIkeCaElem* caElem = At(i); + if ( caElem->KeyHash().Compare(aKeyIdentifier) == 0 ) + { + result = caElem; + break; + } + i ++; + } + return result; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/src/ikecert.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/src/ikecert.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,344 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: General utility methods for certificate handling +* +*/ + + + +#include + +#include "ikecert.h" +#include "ikev1pkiservice.h" +#include "ikev2const.h" +#include "ikecaelem.h" +#include "ikecertconst.h" + + +const TUint8 Pkcs1v15Sha1Header[15] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14}; + + +TUint8* IkeCert::BERGetLengthL(TUint8* aP, TInt &aLen) +{ + ASSERT(aP); + aP++; // skip tag + if (*aP <= 127) + { + aLen = *aP; + aP++; + } + else if (*aP == 0x81) + { + aP++; + aLen = *aP; + aP++; + } + else if (*aP == 0x82) + { + aP++; + aLen = *aP; + aP++; + aLen *= 256; + aLen += *aP; + aP++; + } + else { + User::Leave(KErrGeneral); + } + return aP; +} + + +EXPORT_C HBufC8* IkeCert::GetCertificateFieldDERL(const CX509Certificate* aCert, TInt aField) +{ + if ( !aCert ) + return NULL; + const TPtrC8 SignedData = aCert->SignedDataL(); + if ( SignedData.Length() == 0 ) + return NULL; + TUint8* Ptr = (TUint8*)SignedData.Ptr(); + TUint8* FieldPtr; + HBufC8* FieldBfr = NULL; + TInt length = 0; + // begin sequence + Ptr = IkeCert::BERGetLengthL(Ptr, length); + // context specific a0 03 + if (*Ptr==0xa0) + Ptr += 2; + // version + if (*Ptr==2) + { + Ptr = IkeCert::BERGetLengthL(Ptr, length); + Ptr += length; + } + // seq number + if (*Ptr==2) + { + Ptr = IkeCert::BERGetLengthL(Ptr, length); + Ptr += length; + } + // sign algorithm + Ptr = IkeCert::BERGetLengthL(Ptr, length); + Ptr += length; + // issuer name + FieldPtr = Ptr; + Ptr = IkeCert::BERGetLengthL(Ptr, length); + Ptr += length; + if ( aField == KIssuerName ) + { + FieldBfr = HBufC8::NewL(Ptr - FieldPtr); + FieldBfr->Des().Copy(FieldPtr, (Ptr - FieldPtr)); + } + // validity period + Ptr = IkeCert::BERGetLengthL(Ptr, length); + Ptr += length; + // subject name + FieldPtr = Ptr; + Ptr = IkeCert::BERGetLengthL(Ptr, length); + Ptr += length; + if ( aField == KSubjectName ) + { + FieldBfr = HBufC8::NewL(Ptr - FieldPtr); + FieldBfr->Des().Copy(FieldPtr, (Ptr - FieldPtr)); + } + // public key info + FieldPtr = Ptr; + Ptr = IkeCert::BERGetLengthL(Ptr, length); + Ptr += length; + if ( aField == KPublicKeyInfo ) + { + FieldBfr = HBufC8::NewL(Ptr - FieldPtr); + FieldBfr->Des().Copy(FieldPtr, (Ptr - FieldPtr)); + } + + return FieldBfr; +} + + +HBufC8* IkeCert::BuildPkcs1v15HashL(const TDesC8 &aHashIn) +{ + // + // Build Pkcs1v15 format ASN1 header for specified hash. + // Current implementation supports only hash algorithm SHA1 so + // the aHashIn length data MUST be exactly the length of SHA1 hash + // (20 bytes) + // + HBufC8* Pkcs1v15Hash = NULL; + + ASSERT( aHashIn.Length() == 20 ); + + Pkcs1v15Hash = HBufC8::NewL(20 + sizeof(Pkcs1v15Sha1Header)); + if ( Pkcs1v15Hash ) + { + Pkcs1v15Hash->Des().Copy((TUint8*)Pkcs1v15Sha1Header, sizeof(Pkcs1v15Sha1Header)); + Pkcs1v15Hash->Des().Append(aHashIn); + } + return Pkcs1v15Hash; +} + + +EXPORT_C HBufC8* IkeCert::GetCertificateFieldDERL(HBufC8* aCertBfr, TInt aField) +{ + if ( !aCertBfr ) + return NULL; + CX509Certificate* Cert = CX509Certificate::NewL(*aCertBfr); + CleanupStack::PushL(Cert); + HBufC8* Field = IkeCert::GetCertificateFieldDERL(Cert, aField); + CleanupStack::PopAndDestroy(Cert); + return Field; +} + + +TBool IkeCert::AltNameExistsL(const CX509Certificate *aX509Cert, const TDesC8 &aId) +{ + ASSERT(aX509Cert); + const CX509CertExtension *AltNameExt = aX509Cert->Extension(KSubjectAltName); + CX509GeneralName *NameId = CX509GeneralName::NewLC(aId); + TBool found = EFalse; + if (AltNameExt) + { + CX509AltNameExt* AltExt = CX509AltNameExt::NewLC(AltNameExt->Data()); + const CArrayPtrFlat&Names = AltExt->AltName(); + TInt Count = Names.Count(); + for (TInt i = 0; i < Count; i++) + { + const CX509GeneralName *Name = Names.At(i); + if (NameId->Tag() == Name->Tag() && + NameId->Data() == Name->Data()) + { + found = ETrue; + break; + } + } + CleanupStack::PopAndDestroy(AltExt); + } + CleanupStack::PopAndDestroy(NameId); + return found; +} + + +EXPORT_C HBufC8* IkeCert::GetSubjectAltNameDataL(const CX509Certificate* aX509Cert, TUint8 aIkeIdType) +{ + ASSERT(aX509Cert); + HBufC8* Identity = NULL; + const CX509CertExtension* AltNameExt = aX509Cert->Extension(KSubjectAltName); + + if ( AltNameExt ) + { + TGNType SubjAltNameType; + switch ( aIkeIdType ) + { + case ID_IPV4_ADDR: + SubjAltNameType = EX509IPAddress; + break; + case ID_FQDN: + SubjAltNameType = EX509DNSName; + break; + case ID_RFC822_ADDR: + SubjAltNameType = EX509RFC822Name; + break; + case ID_IPV6_ADDR: + SubjAltNameType = EX509IPAddress; + break; + default: + SubjAltNameType = EX509RFC822Name; + break; + } + CX509AltNameExt* AltExt = CX509AltNameExt::NewLC(AltNameExt->Data()); + const CArrayPtrFlat&Names = AltExt->AltName(); + TInt count = Names.Count(); + for (TInt i = 0; i < count; i++) + { + const CX509GeneralName *Name = Names.At(i); + if ( Name->Tag() == SubjAltNameType ) + { + // + // Allocate buffer and Copy subject alt name data to it (type tag and length is not copied !) + // + Identity = HBufC8::NewL(Name->Data().Length() - 2); + Identity->Des().Copy(((TUint8*)(Name->Data().Ptr()) + 2), (Name->Data().Length() - 2)); + break; + } + } + CleanupStack::PopAndDestroy(AltExt); + + } + return Identity; +} + + +TInt IkeCert::CheckValidityPeriod(const CX509Certificate& aCert, TInt aWarningMargin, TInt aErrorMargin ) +{ + TInt Status = KErrNone; + TTime current; + current.UniversalTime(); + TTimeIntervalSeconds ErrorMargin(aErrorMargin); + TTime StartTime = aCert.ValidityPeriod().Start(); + TTime FinishTime = aCert.ValidityPeriod().Finish(); + if ( (current + ErrorMargin) < StartTime ) + { + Status = KCertVerifyErrNotValidYet; + } + else + { + if (current > (FinishTime + ErrorMargin) ) + { + Status = KCertVerifyErrExpired; + } + else + { + // + // If a warning margin defined, check is the certificate within that + // + if ( aWarningMargin ) + { + TTimeIntervalSeconds WarningMargin(aWarningMargin); + if ( (current + WarningMargin) > (FinishTime + ErrorMargin) ) { + Status = KCertVerifyWithinMargin; + } + } + } + } + + return Status; +} + +// +// Verify certificate extensions +// +TInt IkeCert::VerifyCertExtensionsL(const CX509Certificate& aX509Cert) +{ + TInt Status = KErrNone; + const CArrayPtrFlat& CertExtensions = aX509Cert.Extensions(); + CX509CertExtension* Extension; + TInt Count = CertExtensions.Count(); + TInt i = 0; + + while ( i < Count ) + { + Extension = CertExtensions.At(i); + if ( Extension->Id() == KKeyUsage ) + { + // + // KeyUsage extension MUST have either digitalSignature or + // nonRepudiation bit set + // + CX509KeyUsageExt* KeyUsage = CX509KeyUsageExt::NewL(Extension->Data()); + if ( !KeyUsage->IsSet(EX509DigitalSignature) && !KeyUsage->IsSet(EX509NonRepudiation) ) + { + delete KeyUsage; + Status = KCertVerifyKeyUsageErr; + break; + } + else delete KeyUsage; + } + else if ( Extension->Id() == KBasicConstraints ) + { + // + // BasicConstraints extension MUST NOT have CA indicator + // + CX509BasicConstraintsExt* BasicConstraints = CX509BasicConstraintsExt::NewL(Extension->Data()); + if ( BasicConstraints->IsCA() ) + { + delete BasicConstraints; + Status = KCertVerifyCACertificate; + break; + } + else delete BasicConstraints; + } + else if ( Extension->Id() != KSubjectAltName && Extension->Critical() ) + { + // + // Unsupported critical section ==> Certificate NOT accepted + // + Status = KCertVerifyCriticalExt; + break; + } + + i++; + } + + return Status; +} + + +void IkeCert::CleanupSequence(TAny* aArray) + { + ASSERT(aArray); + CArrayPtrFlat* array = reinterpret_cast*>(aArray); + ASSERT(array); + array->ResetAndDestroy(); + delete array; + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/src/ikepkiutils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/src/ikepkiutils.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,587 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: static method for certficate handling +* +*/ + +#include +#include +#include + +#include "ikepkiutils.h" +#include "ikev1pkiservice.h" +#include "ikepublickey.h" +#include "utlcrypto.h" +#include "ikecert.h" +#include "ikecalist.h" +#include "ikecaelem.h" +#include "ikev2const.h" +#include "ikev2payloads.h" +#include "ikecertconst.h" + +EXPORT_C TBool IkePkiUtils::CertifyIdentityL(const CX509Certificate* aCert, + TDesC8& aId, TInt aIdType) + + { + TBool status = EFalse; + if ( aCert ) + { + // + // Check that specified identity exist in current certificate + // data. If aIdType type is ID_DER_ASN1_DN, identity must match + // with Certificate Subject name. + // All other aIdTypes ara checked against SubjectAltNames data, + // if present + // + if ( aIdType == ID_DER_ASN1_DN ) + { + // + // Binary DER encoding of an ASN.1 X.500 Distinguished Name identity + // is certified by comparing it to peer certificate subject name + // + + CX500DistinguishedName* asn1DnName = CX500DistinguishedName::NewLC(aId); + status = asn1DnName->ExactMatchL(aCert->SubjectName()); + CleanupStack::PopAndDestroy(asn1DnName); + + } + else + { + // + // Other identity types are certified by comparing it to the SubjectAltName field + // + HBufC8* idBuf = HBufC8::NewLC(aId.Length() + 2); + TUint8* idHdr = (TUint8*)idBuf->Des().Ptr(); + idHdr[1] = (TUint8)aId.Length(); + + switch ( aIdType ) + { + case ID_IPV4_ADDR: + idHdr[0] = 0x87; + break; + case ID_FQDN: + idHdr[0] = 0x82; + break; + case ID_RFC822_ADDR: + idHdr[0] = 0x81; + break; + case ID_IPV6_ADDR: + idHdr[0] = 0x87; + break; + default: + idHdr = NULL; + break; + } + + if ( idHdr ) + { + Mem::Copy(&idHdr[2], aId.Ptr(), aId.Length()); + TPtrC8 ptrId(idHdr, (aId.Length() + 2)); + status = IkeCert::AltNameExistsL(aCert, ptrId); + } + CleanupStack::PopAndDestroy(); //IdBuf + } + } + + return status; + } + + +EXPORT_C TBool IkePkiUtils::VerifyIkev2SignatureL(const TDesC8& aSignature, + const TDesC8& aAuthData, + const CX509Certificate& aCert) + { + // + // Calculate SHA1 hash over aAuthdata to build reference hash and + // verify IKEv2 signature with it + // + CUtlMessageDigest* Digest = TUtlCrypto::MakeMessageDigesterL(TUtlCrypto::EUtlMessageDigestSha1); + CleanupStack::PushL(Digest); + TPtrC8 RefHash = Digest->Final(aAuthData); + TBool Status = VerifySignatureL(MAJORV2, aSignature, RefHash, aCert); + CleanupStack::PopAndDestroy(Digest); + + return Status; + } + + +EXPORT_C TBool IkePkiUtils::VerifyIkev1SignatureL(const TDesC8& aSignature, + const TDesC8& aRefHash, + const CX509Certificate& aCert) + { + // + // Verify IKEv1 signature. + // + return VerifySignatureL(MAJORV1, aSignature, aRefHash, aCert); + } + + +EXPORT_C HBufC8* IkePkiUtils::GetIdentityFromCertL(TUint8 aIdType, const TDesC8& aCertData) + { + // + // Get IKE Identity data from specified Certificate data. The Id + // type parameter specifies the field of Certificate from where the + // Identity data is taken + // + HBufC8* identity; + CX509Certificate* cert = CX509Certificate::NewL(aCertData); + CleanupStack::PushL(cert); + if ( (aIdType == ID_DER_ASN1_DN) || (aIdType == ID_NOT_DEFINED) || (aIdType > ID_IPV6_ADDR) ) + { + // + // DER encoded ASN.1 X.500 Distinguished Name as IKE identity + // Get Id data from certificate subject name + // + identity = IkeCert::GetCertificateFieldDERL(cert, KSubjectName); + } + else + { + // + // Get IKE Identity from own certifate subject alt name extension (according to IdType value) + // + identity = IkeCert::GetSubjectAltNameDataL(cert, aIdType); + } + CleanupStack::PopAndDestroy(cert); + + return identity; + } + + +EXPORT_C TBool IkePkiUtils::GetCertSubjectNameDERL(const CX509Certificate* aCert, + TDes8& aSubjectName) + { + TBool status = ETrue; + HBufC8* nameBfr = IkeCert::GetCertificateFieldDERL(aCert, KSubjectName); + if ( nameBfr && ( nameBfr->Des().Length() <= aSubjectName.MaxLength() ) ) + { + aSubjectName.Copy(nameBfr->Des()); + delete nameBfr; + } + else + { + aSubjectName.SetLength(0); + status = EFalse; + } + + return status; + } + + +EXPORT_C CX509Certificate* IkePkiUtils::VerifyCertificateL(const CArrayFixFlat& aCerts, + const CIkeCaList& aTrustedCAList) + { + const CArrayFixFlat* certificateArray = IkePkiUtils::CastCertArray(&aCerts); + return VerifyCertificateL(*certificateArray, aTrustedCAList); + + } + + +EXPORT_C CX509Certificate* IkePkiUtils::VerifyCertificateL(const CArrayFixFlat& aCerts, + const CIkeCaList& aTrustedCAList) + { + // + // Find a requested certificate or chain of certificates from IKE certificate payload array + // using trusted CA list (iTrustedCAList). + // When requested certificate found verify this certificate. + // + CX509Certificate* certOk = NULL; + CX509Certificate* caCert = NULL; + CX509Certificate* currCert=NULL; + const TCertPayloadIkev2* firstCertPayload=NULL; + const TCertPayloadIkev2* certPayload = aCerts.At(0); + __ASSERT_DEBUG(certPayload != NULL, User::Invariant()); + CArrayFixFlat* caArray=new (ELeave) CArrayFixFlat (aCerts.Count()); + CleanupStack::PushL(caArray); + for ( TInt i = 0; i < aCerts.Count(); i++ ) + { + const TCertPayloadIkev2* currCertPayload=aCerts.At(i); + __ASSERT_DEBUG(currCertPayload != NULL, User::Invariant()); + if ( currCertPayload->GetEncoding() == X509_CERTIFICATE_SIGN ) + { + firstCertPayload=currCertPayload; + const TPtrC8 CertStream(currCertPayload->Certificate(), + (TPayloadIkev2::Cast(currCertPayload)->GetLength() - + TCertPayloadIkev2::Size())); + currCert = CX509Certificate::NewLC(CertStream); + caArray->AppendL(currCert); + } + } + if ( caArray->Count() == 1) + { + const TPtrC8 userCertStream(firstCertPayload->Certificate(), + (TPayloadIkev2::Cast(firstCertPayload)->GetLength() - + TCertPayloadIkev2::Size())); + firstCertPayload=NULL; + CX509Certificate* clientCert = CX509Certificate::NewLC(userCertStream); + caCert = IkePkiUtils::FindCaCertificateL(*clientCert, aTrustedCAList); + if ( caCert ) + { + certOk = IkePkiUtils::VerifyX509CertificateL(*caCert, *clientCert); + if ( certOk ) // CertOk = clientCert + { + CleanupStack::Pop(clientCert); // CertOk = Cert + clientCert=NULL; + + CleanupStack::PopAndDestroy(currCert); + currCert=NULL; + + CleanupStack::PopAndDestroy(caArray); + caArray=NULL; + + return certOk; + } + } + CleanupStack::PopAndDestroy(clientCert); // Cert + clientCert=NULL; + + CleanupStack::PopAndDestroy(currCert); + currCert=NULL; + + CleanupStack::PopAndDestroy(caArray); + caArray=NULL; + return NULL; + } + if ( caArray->Count()>1 ) //if certificate chain is received + { + CX509Certificate* userCert=NULL; + CX509Certificate* certChainRoot = IkePkiUtils::VerifyCertChainL(*caArray, userCert, aTrustedCAList); + + CX509Certificate* realUserCert=userCert; //Real user certificate found from chain as a parameter by reference + + //cleaning + TInt certCount=caArray->Count(); + for ( TInt i=0; iAt(i); + if ( realUserCert != itemPtr && certChainRoot != itemPtr ) + delete itemPtr; + } + for ( TInt i=0; iDelete(0); + delete caArray; + + if ( certChainRoot ) + caCert = IkePkiUtils::FindCaCertificateL(*certChainRoot, aTrustedCAList); + else + caCert=NULL; + if ( caCert ) + certOk = IkePkiUtils::VerifyX509CertificateL(*caCert, *certChainRoot); + if ( certChainRoot != userCert ) + delete certChainRoot; + if ( certOk ) + return realUserCert; + + else + return NULL; + } + return NULL; + } + + +EXPORT_C const CArrayFixFlat* IkePkiUtils::CastCertArray(const CArrayFixFlat* aCerts) + { + return reinterpret_cast*>(aCerts); + } + + +CX509Certificate* IkePkiUtils::VerifyX509CertificateL(const CX509Certificate& aCaCert, + CX509Certificate& aCert) + { + TPKIKeyAlgorithm reqKeyType = EPKIInvalidAlgorithm; + + switch (aCert.SigningAlgorithm().AsymmetricAlgorithm().Algorithm()) + { + case ERSA: + reqKeyType = EPKIRSA; + break; + case EDSA: + reqKeyType = EPKIDSA; + break; + default: + break; + } + + if ( reqKeyType == EPKIInvalidAlgorithm ) + return NULL; + + CIkePublicKey* pubKey = CIkePublicKey::NewL(aCaCert); + if ( !pubKey ) + return NULL; + + if ( reqKeyType != pubKey->Algorithm() ) + { + delete pubKey; + return NULL; + } + CleanupStack::PushL(pubKey); + TInt ret = KErrNotSupported; + TBool valid = EFalse; + + switch (pubKey->Algorithm()) + { + case EPKIRSA: + TRAP(ret, valid = aCert.VerifySignatureL(pubKey->KeyData())); + break; + + case EPKIDSA: + { + TX509KeyFactory keyFactory; + CDSAParameters* params = keyFactory.DSAParametersL(pubKey->KeyParams()); + CleanupStack::PushL(params); + + CSigningKeyParameters*sgkp = CSigningKeyParameters::NewLC(); + sgkp->SetDSAParamsL(*params); + aCert.SetParametersL(*sgkp); + TRAP(ret, valid = aCert.VerifySignatureL(pubKey->KeyData())); + CleanupStack::PopAndDestroy(sgkp); + CleanupStack::PopAndDestroy(params); + break; + } + + case EPKIInvalidAlgorithm: + break; + } + + CX509Certificate* ValidCert = NULL; + if ( valid && (ret == KErrNone) ) + { + // + // One hour error margin, no warning margin + // + ret = IkeCert::CheckValidityPeriod(aCert, 0, KDefaultErrorMargin); + if ( ret == KErrNone ) + { + // + // Verify certificate extensions + // + ret = IkeCert::VerifyCertExtensionsL(aCert); + if ( ret == KErrNone || ret == KCertVerifyCACertificate ) + ValidCert = &aCert; + } + } + + CleanupStack::PopAndDestroy(pubKey); + return ValidCert; +} + + +CX509Certificate* IkePkiUtils::FindCaCertificateL(const CX509Certificate& aUserCert, + const CIkeCaList& aTrustedCAList) + { + // + // Find a CA certificate from Trusted CA list (iTrustedCAList) for + // specified user certificate + // + const CX500DistinguishedName& issuerName = aUserCert.IssuerName(); + CX509Certificate* caCert = NULL; + + for (TInt i = 0; i < aTrustedCAList.Count(); i++) + { + // + // Find CA certificate for current user certificate by + // comparing certificate issuer name to the subject name of a + // CA certificate + // + caCert = aTrustedCAList.At(i)->Certificate(); + if ( issuerName.ExactMatchL(caCert->SubjectName()) ) + { + break; + } + caCert = NULL; + } + + return caCert; + } + + +TBool IkePkiUtils::VerifySignatureL(TInt aIkeVersion, + const TDesC8& aSignature, + const TDesC8& aRefHash, + const CX509Certificate& aCert) + { + // + // Verify IKE signature. + // + TBool status = EFalse; + + if ( aSignature.Length() > 0 ) + { + CIkePublicKey* publicKey = CIkePublicKey::NewL(aCert); + if ( !publicKey ) + { + return EFalse; + } + + CleanupStack::PushL(publicKey); + + switch (publicKey->Algorithm()) + { + case EPKIRSA: + { + HBufC8 *resBuf; + TUtlCrypto::RsaPublicKeyDecryptL(publicKey->KeyData(), aSignature, resBuf); + CleanupStack::PushL(resBuf); + + if ( aIkeVersion == MAJORV1 ) + { + // + // Because IKEv1 signature is not a "real" PKCS1 + // encoded signature but pure private encrypted has + // signature is verified by using RSA public key + // decrypt and result comparison to reference hash + // + status = (aRefHash.Compare(*resBuf) == 0); //Compare the result with the hash to see if they match + } + else + { + // + // IKEv2(n) signature is encoded as PKCS1v1_5 + // signature (EMSA-PKCS1-v1_5) + // ASN1 encoding of signature is the following: + // DigestInfo::=SEQUENCE{ + // digestAlgorithm AlgorithmIdentifier, + // digest OCTET STRING } + // + CArrayPtrFlat* seq = NULL; + TInt position = 0; + + TRAPD(err, seq = DecodeDERL(*resBuf, position)); + if ( err == KErrNone ) + { + TCleanupItem CleanupSeq(IkeCert::CleanupSequence, seq); + CleanupStack::PushL(CleanupSeq); + if (seq->Count() == 2) + { + // + // Currently the digestAlgorithm is not + // verified, but only digest value itself is + // compared with reference hash. + // ( see CPKCS1SignatureResult::DoVerifyL() in + // x509cert.cpp) + // + const TASN1DecGeneric* gen2 = seq->At(1); + TPtrC8 digest(gen2->GetContentDER()); + status = (aRefHash.Compare(digest) == 0); + } + CleanupStack::PopAndDestroy(); //CleanupSeq + } + else + { + // + // Verify signature as pure encrypted (SHA1) + // hash as old IKEv1 style "signature" + // + //DEB(iService.PrintText(_L("Old IKEv1 style signature used by IKEv2 peer !\n"));) + status = (aRefHash.Compare(*resBuf) == 0); //Compare the result with the hash to see if they match + } + } + CleanupStack::PopAndDestroy(resBuf); + break; + } + case EPKIDSA: + { + const TPtrC8 sigR = aSignature.Left(aSignature.Length() / 2); + const TPtrC8 sigS = aSignature.Right(aSignature.Length() / 2); + + status = TUtlCrypto::DsaVerifySignatureL(publicKey->KeyData(), + publicKey->KeyParams(), + sigR, sigS, aRefHash); + break; + } + default: //Only RSA and DSA are valid + User::Invariant(); + break; + } + + CleanupStack::PopAndDestroy(publicKey); + } + return status; + } + + +CArrayPtrFlat* IkePkiUtils::DecodeDERL(const TDesC8& aPtr, TInt& aPosition) + { + TASN1DecSequence decSeq; + CArrayPtrFlat* seq = decSeq.DecodeDERLC(aPtr, aPosition); + CleanupStack::Pop(seq); + return seq; + } + +EXPORT_C CX509Certificate* IkePkiUtils::VerifyCertChainL(const CArrayFixFlat& aCerts, CX509Certificate*& realUserCert, const CIkeCaList& aTrustedCAList) + { + CX509Certificate* currCaCert=NULL; + CX509Certificate* certOk=NULL; + CArrayFixFlat* issuerArray=new (ELeave) CArrayFixFlat (aCerts.Count()); + CArrayFixFlat* subjectArray=new (ELeave) CArrayFixFlat (aCerts.Count()); + CleanupStack::PushL(issuerArray); + CleanupStack::PushL(subjectArray); + for ( TInt i = 0; i < aCerts.Count(); i++ ) + { + issuerArray->AppendL(&aCerts.At(i)->IssuerName()); + subjectArray->AppendL(&aCerts.At(i)->SubjectName()); + } + TInt userCertIndex=0; + TInt caCertIndex=0; + + //find UserCert from aCerts array if not in first certificate payload + for ( TInt i = 0; i < (aCerts.Count()); i++ ) + { + for ( TInt j = 0; j < (aCerts.Count()); j++ ) + { + caCertIndex=j; + if ( i!=caCertIndex ) + { + const CX500DistinguishedName& issuerNameStr=*issuerArray->At(j); + if ( issuerNameStr.ExactMatchL(*subjectArray->At(i)) ) + userCertIndex=i+1; + } + } + if ( userCertIndex == i && i!=caCertIndex ) + break; + userCertIndex=i; + } + CleanupStack::PopAndDestroy(subjectArray); + CleanupStack::PopAndDestroy(issuerArray); + CX509Certificate* currCert = aCerts.At(userCertIndex); + TInt currCertIndex=0; + realUserCert=currCert; + //Verify chain and return highest CA + while ( currCertIndex < aCerts.Count()) + { + CX509Certificate* trustedCaCert = IkePkiUtils::FindCaCertificateL(*currCert, aTrustedCAList); + if ( trustedCaCert ) + return currCert; + else + { + for ( TInt j = 0; j < aCerts.Count(); j++ ) + { + currCaCert = aCerts.At(j); + if ( currCert->IssuerName().ExactMatchL(currCaCert->SubjectName())) + { + certOk = IkePkiUtils::VerifyX509CertificateL(*currCaCert, *currCert); + if ( certOk ) + break; + } + } + if ( !certOk ) //if chain is malicious break and return NULL + break; + currCertIndex++; + currCert=currCaCert; + } + } + return NULL; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/src/ikepublickey.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/src/ikepublickey.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,88 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class containing information about one public key. +* +*/ + + + + +#include +#include "ikepublickey.h" + +// +// CPublickey Class +// +CIkePublicKey* CIkePublicKey::NewL(const CX509Certificate& aCert) + { + CIkePublicKey* PubKey = new (ELeave) CIkePublicKey(); + CleanupStack::PushL(PubKey); + + switch ( aCert.PublicKey().AlgorithmId() ) + { + case ERSA: + PubKey->iAlgorithm = EPKIRSA; + PubKey->iKeyData = HBufC8::NewL(aCert.PublicKey().KeyData().Length()); + PubKey->iKeyData->Des().Copy(aCert.PublicKey().KeyData()); + CleanupStack::Pop(PubKey); //PubKey only removed from cleanup stack + break; + + case EDSA: + PubKey->iAlgorithm = EPKIDSA; + PubKey->iKeyData = HBufC8::NewL(aCert.PublicKey().KeyData().Length()); + PubKey->iKeyData->Des().Copy(aCert.PublicKey().KeyData()); + PubKey->iKeyParams = HBufC8::NewL(aCert.PublicKey().EncodedParams().Length()); + PubKey->iKeyParams->Des().Copy(aCert.PublicKey().EncodedParams()); + CleanupStack::Pop(PubKey); //PubKey only removed from cleanup stack + break; + + default: + CleanupStack::PopAndDestroy(PubKey); + PubKey = NULL; + break; + } + + return PubKey; + } + + +CIkePublicKey::CIkePublicKey() +:iAlgorithm(EPKIInvalidAlgorithm) + { + } + + +CIkePublicKey::~CIkePublicKey() + { + delete iKeyParams; + delete iKeyData; + } + + +TPKIKeyAlgorithm CIkePublicKey::Algorithm() const + { + return iAlgorithm; + } + + +const TDesC8& CIkePublicKey::KeyData() const + { + return *iKeyData; + } + + +const TDesC8& CIkePublicKey::KeyParams() const + { + return *iKeyParams; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/src/ikev1pkiservice.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/src/ikev1pkiservice.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,1067 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: PKI store and Certificate verification interface class +* implementation for IKEv1 plug-in +* +*/ + +#include +#include +#include +#include + +#include "ikedebug.h" +#include "ikev1pkiservice.h" +#include "utlcrypto.h" +#include "ikecert.h" +#include "ikecaelem.h" +#include "ikepublickey.h" +#include "ikecalist.h" +#include "ikepkiutils.h" +#include "pkcs10.h" +#include "vpnapidefs.h" +#include "pkiutil.h" +#include "ikecertconst.h" + +// +// CIkeV1PkiService Class +// +_LIT8(KEmptyString, ""); + + +EXPORT_C CIkeV1PkiService* CIkeV1PkiService::NewL( + CIkeData* aIkeData, + MIkeDebug& aDebug +) +{ + CIkeV1PkiService* self = + new (ELeave) CIkeV1PkiService(aIkeData, aDebug); + + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; +} + + +CIkeV1PkiService::CIkeV1PkiService( + CIkeData* aIkeData, + MIkeDebug& aDebug +) : + iOperation(KNoOperation), + iIkeData(aIkeData), + iCertPtr(NULL, 0), + iCertBfrSize(2048), + iDebug(aDebug) +{ +} + + +void CIkeV1PkiService::ConstructL() +{ + User::LeaveIfError(iPkiService.Connect()); + + // Set certificate store type to device certificate store, + // if Own_cert_type is defined as "DEVICE" + if ( iIkeData->iClientCertType != NULL ) + { + TPtrC16 certStoreType = iIkeData->iClientCertType->GetData(); + if ( certStoreType.CompareF(_L("DEVICE")) == 0 ) + { + User::LeaveIfError(iPkiService.SetStoreType(EPkiStoreTypeDevice)); + } + else + { + User::LeaveIfError(iPkiService.SetStoreType(EPkiStoreTypeUser)); + } + } + + iTrustedCAList = new (ELeave) CIkeCaList(2); + iReadCertificate = HBufC8::NewL(iCertBfrSize); + + + //The code assumes that these are not NULL. + //Reallocated, when needed + iSubjName = HBufC8::NewL(2); + iRfc822Name = HBufC8::NewL(2); +} + + +EXPORT_C CIkeV1PkiService::~CIkeV1PkiService() +{ + if ( iApplUidList ) + { + iApplUidList->Reset(); + delete iApplUidList; + } + + if ( iCaCertList ) + { + iCaCertList->Reset(); + delete iCaCertList; + } + + delete iTrustedCAList; + + iCasTrustedByPeer.Reset(); + iCasTrustedByPeer.Close(); + + delete iCaName; + delete iCa1Name; + delete iCa2Name; + + delete iReadCertificate; + delete iSubjName; + delete iRfc822Name; + + + iPkiService.Close(); +} + + +EXPORT_C TBool CIkeV1PkiService::ImportCACertsL( + CArrayFixFlat *aCAList +) +{ + DEBUG_LOG(_L("-> CIkeV1PkiService::ImportCACertsL")); + + // + // Build trusted CA certificate list into CIkeV1PkiService object + // aCAList call parameter array contains the list of trusted CA:s + // (names in ASCII format). + // Read corresponding certificate from PKI store and if found, + // add a new element (=CIkeCaElem) into CIkeCaList + // + TBool Status = EFalse; + + if ( aCAList && aCAList->Count() ) + { + delete iCaName; + + iCaName = NULL; + iCaName = HBufC8::NewL(256); + iCaNameList = aCAList; + iCurrIndex = 0; + iOperation = KBuildingCaList; + + Status = GetNextCaElemL(); + } + + return Status; +} + + +// +// CIkeV1PkiService::ReadCertWithNameL +// This method is used to read a certificate from the PKI store. +// Input parameters: +// -- const TDesC8& Trusted CA name +// -- TBool aGetCACert +// ETrue = Read a CA certificate; EFalse read an user certificate +// Output parameters: +// -- X509 certificate into iReadCertificate buffer +// +EXPORT_C TInt CIkeV1PkiService::ReadUserCertWithNameL( + const TDesC8& aTrustedCaName, CIkeData* aIkeData, TBool aDnType) + +{ + iIkeData = aIkeData; + + delete iCaName; + iCaName = NULL; + iCaName = HBufC8::NewL(aTrustedCaName.Length()); + iCaName->Des().Copy(aTrustedCaName); + + delete iReadCertificate; + iReadCertificate=NULL; + + TInt Status = ReadCertificateL(*iCaName, EFalse); + + iUserCertDerType=aDnType; + return Status; +} +EXPORT_C TInt CIkeV1PkiService::ReadChainL(CIkeData* aIkeData, const HBufC8* aCAName) +{ + iIkeData = aIkeData; + delete iReadCertificate; + iReadCertificate=NULL; + //read own certificate + TInt Status = ReadCertificateL(KEmptyString, EFalse); + TInt StatusICA1 = KErrNotFound; + TInt StatusICA2 = KErrNotFound; + TInt StatusICA = KErrNotFound; + + if ( Status == KErrNone ) + { + iReadCertificateOrig = HBufC8::NewL(iReadCertificate->Length()); + TPtr8 iReadCertCopy(iReadCertificateOrig->Des()); + iReadCertCopy.Copy(iReadCertificate->Des()); + delete iCaName; + iCaName = NULL; + iCaName = IkeCert::GetCertificateFieldDERL(iReadCertificate, KIssuerName); + + //Read ICA2 + StatusICA2 = ReadCertificateL(KEmptyString, ETrue); + + if ( StatusICA2 != KErrNone) + { + delete iReadCertificateOrig; + iReadCertificateOrig=NULL; + return KErrNotFound; + } + } + if ( Status == KErrNone && StatusICA2 == KErrNone) + { + + delete iCaName; + iCaName = NULL; + iCaName = IkeCert::GetCertificateFieldDERL(iReadCertificate, KIssuerName); + delete iCa2Name; + iCa2Name=NULL; + iCa2Name = GetCertificate(); + + CX500DistinguishedName* dn=NULL; + CX500DistinguishedName* asn1DnNameofICaName = NULL; + dn = CX500DistinguishedName::NewLC(*aCAName); + asn1DnNameofICaName = CX500DistinguishedName::NewLC(*iCaName); + + if ( asn1DnNameofICaName->ExactMatchL(*dn) ) + + { + StatusICA=KErrNone; + //read ICA1 + StatusICA1 = ReadCertificateL(KEmptyString, ETrue); + if ( StatusICA1 != KErrNone) + { + delete iReadCertificateOrig; + iReadCertificateOrig=NULL; + + CleanupStack::PopAndDestroy(asn1DnNameofICaName); + asn1DnNameofICaName=NULL; + + CleanupStack::PopAndDestroy(dn); + dn=NULL; + + return KErrNotFound; + } + } + else + { + StatusICA1 = ReadCertificateL(KEmptyString, ETrue); + if ( StatusICA1 == KErrNotFound) + { + delete iReadCertificateOrig; + iReadCertificateOrig=NULL; + + CleanupStack::PopAndDestroy(asn1DnNameofICaName); + asn1DnNameofICaName=NULL; + + CleanupStack::PopAndDestroy(dn); + dn=NULL; + + return KVpnErrInvalidCaCertFile; + } + else + StatusICA1=KErrNone; + } + CleanupStack::PopAndDestroy(asn1DnNameofICaName); + asn1DnNameofICaName=NULL; + + CleanupStack::PopAndDestroy(dn); + dn=NULL; + + } + + if ( Status == KErrNone && StatusICA1 == KErrNone && StatusICA2 == KErrNone) + { + if ( StatusICA == KErrNotFound ) + { + delete iCaName; + iCaName = NULL; + iCaName = IkeCert::GetCertificateFieldDERL(iReadCertificate, KIssuerName); + } + delete iCa1Name; + iCa1Name=NULL; + iCa1Name = GetCertificate(); + + CX500DistinguishedName* dn=NULL; + CX500DistinguishedName* asn1DnNameofICaName = NULL; + + dn = CX500DistinguishedName::NewLC(*aCAName); + + asn1DnNameofICaName = CX500DistinguishedName::NewLC(*iCaName); + + if ( asn1DnNameofICaName->ExactMatchL(*dn) ) + { + delete iCaName; + iCaName=NULL; + iCaName=HBufC8::NewL(aCAName->Length()); + iCaName->Des().Copy(*aCAName); + + TInt Status = ReadCertificateL(KEmptyString, ETrue); + + delete iCaName; + iCaName = NULL; + iCaName = IkeCert::GetCertificateFieldDERL(iCa2Name, KSubjectName); + + delete iReadCertificate; + iReadCertificate=iReadCertificateOrig; + iReadCertificateOrig=NULL; + + CleanupStack::PopAndDestroy(asn1DnNameofICaName); + asn1DnNameofICaName=NULL; + + CleanupStack::PopAndDestroy(dn); + dn=NULL; + + if ( Status!=KErrNone ) + return KVpnErrInvalidCaCertFile; + else + return KErrNone; + } + else + { + delete iReadCertificate; + + iReadCertificate=iReadCertificateOrig; + iReadCertificateOrig=NULL; + delete iReadCertificateOrig; + + delete iReadCertificate; + iReadCertificate=NULL; + + CleanupStack::PopAndDestroy(asn1DnNameofICaName); + asn1DnNameofICaName=NULL; + + CleanupStack::PopAndDestroy(dn); + dn=NULL; + + return KErrNotFound; + } + } + return KErrNotFound; +} + +// +// CIkeV1PkiService::Ikev1SignatureL +// This method is used to compute IKEv1 signature with a specified private key. +// Actually a signature computed happens by referring the related certificate +// when the PKI store produces the signature with corresponding private key. +// Parameters: +// -- const TDesC8& aTrustedAuthority +// Trusted CA name coded either in ASN1 (DN) format or ASCII format +// -- CIkeData* aHostData +// Related IKE configuration section. Used to get IdentitySubjectName or +// Identity Rfc822 Name information for actual PKI service ReadCertificateL +// method call +// -- const TDesC8& aHashIn +// Hash data signed (in matter of fact the hash data is simply +// encrypted with private key) +// Return: +// -- TInt, sign length +// +EXPORT_C TInt CIkeV1PkiService::Ikev1SignatureL( + const TDesC8& aTrustedCaName, + CIkeData* aIkeData, + const TDesC8& aHashIn, + TDes8& aSignature +) +{ + iIkeData = aIkeData; + return ComputeSignatureL(aTrustedCaName, aHashIn, aSignature, EFalse); +} + + +EXPORT_C CIkeCaList* CIkeV1PkiService::CaList() +{ + return iTrustedCAList; +} + + +EXPORT_C HBufC8* CIkeV1PkiService::GetCertificate() +{ + HBufC8* Cert = iReadCertificate; + iReadCertificate = NULL; + return Cert; +} + + +EXPORT_C HBufC8* CIkeV1PkiService::GetTrustedCA() +{ + HBufC8* Cert = iCaName; + iCaName = NULL; + return Cert; +} + + +EXPORT_C HBufC8* CIkeV1PkiService::GetTrustedICA1() +{ + HBufC8* Cert = iCa1Name; + iCa1Name = NULL; + return Cert; +} + +EXPORT_C HBufC8* CIkeV1PkiService::GetTrustedICA2() +{ + HBufC8* Cert = iCa2Name; + iCa2Name = NULL; + return Cert; +} + +TInt CIkeV1PkiService::ComputeSignatureL( + const TDesC8& aTrustedAuthority, + const TDesC8& aHashIn, + TDes8& aSignature, + TBool aRsaSignature +) +{ + DEBUG_LOG(_L("-> CIkeV1PkiService::ComputeSignatureL")); + + TPKIKeyAlgorithm keyAlgorithm = EPKIRSA; + TUint keySize = InitUserCertIdentDataL(); + HBufC8* Asn1EncodedHash = NULL; + TPtrC8 hashIn(aHashIn); + + if ( aRsaSignature ) + { + // + // Build PKCS1v15 format signature (ASN1 encoded) + // + Asn1EncodedHash = IkeCert::BuildPkcs1v15HashL(aHashIn); + + ASSERT( Asn1EncodedHash != NULL ); + hashIn.Set(Asn1EncodedHash->Des()); + } + + TInt SignLth = 0; + TInt err = iPkiService.Sign(aTrustedAuthority, *iSubjName, *iRfc822Name, + EX509DigitalSignature, keySize, + keyAlgorithm, hashIn, aSignature); + + if (err == KErrNone) + { + SignLth = aSignature.Length(); + } + + DEBUG_LOG2(_L("Sign returned %d, length=%d"), err, SignLth); + User::LeaveIfError(err); + + delete Asn1EncodedHash; + return SignLth; +} + + +TInt CIkeV1PkiService::ReadCertificateL( + const TDesC8& aTrustedAuthority, TBool aGetCACert +) +{ + // + // Read certificate from PKI store using pkiserviceapi + // + DEBUG_LOG( + _L("-> ReadCertificateL(aTrustedAuthority, aGetCACert)") + ); + + TInt Status = KErrNone; + TPKIKeyAlgorithm keyAlgorithm = EPKIRSA; + TPKICertificateOwnerType ownerType; + TUint keySize = 0; + + if (aGetCACert) + { + DEBUG_LOG(_L("Reading CA certificate")); + + ownerType = EPKICACertificate; + + //Init CA cert ident data. + //aTrustedAuthority (issuer) checking for CA certs is not supported. + if ( aTrustedAuthority.Length() == 0 ) + { + delete iSubjName; + iSubjName = NULL; + iSubjName = iCaName->AllocL(); + iRfc822Name->Des().Zero(); + } + } + else + { + DEBUG_LOG(_L("Reading User certificate")); + ownerType = EPKIUserCertificate; + keySize = InitUserCertIdentDataL(); + } + + for (;;) // Only for easy exits... + { + if ( iReallocated ) + { + // + // Allocate a new buffer for ASN1 coded certificate read from + // PKI store. Buffer size is now asked from pkiserviceapi + // + delete iReadCertificate; + iReadCertificate = NULL; + TInt RealCertSize; + + if ( iPkiService.GetRequiredBufferSize(RealCertSize) == KErrNone ) + iCertBfrSize = (RealCertSize | 0x3) + 1; + // Try double size in error case + else iCertBfrSize = (iCertBfrSize << 1); + } + + if ( !iReadCertificate ) + { + iReadCertificate=NULL; + iReadCertificate = HBufC8::NewL(iCertBfrSize); + } + + iCertPtr.Set(iReadCertificate->Des()); + iCertPtr.Zero(); + + TRequestStatus status; + iPkiService.ReadCertificateL(aTrustedAuthority, + *iSubjName, *iRfc822Name, + ownerType, keySize, + keyAlgorithm, iCertPtr, + &iResArray, status); + + + User::WaitForRequest(status); + Status = status.Int(); + iPkiService.Finalize(iResArray); + iResArray = NULL; + + if ( (Status == KPKIErrBufferTooShort) && !iReallocated ) + { + // + // Certificate buffer was too small try to read once more if + // not already tried + // + iReallocated = ETrue; + } + else + { + if ( Status == KErrNone ) + { + //iReadCertificate->Des().SetLength(iCertPtr.Length()); + iReallocated = EFalse; + } + break; + } + + } + + DEBUG_LOG( + _L("<- ReadCertificateL(aTrustedAuthority, aGetCACert)") + ); + + return Status; +} + + +TUint CIkeV1PkiService::InitUserCertIdentDataL() +{ + DEBUG_LOG(_L("-> CIkeV1PkiService::InitUserCertIdentDataL")); + __ASSERT_ALWAYS(iIkeData != NULL, User::Invariant()); + + TUint keySize = 0; // Default: Length is undefined + + if ( !iReallocated ) + { + // + // Get possible user identity information from current IKE policy + // section and convert it from 16-bit Unicode into UTF-8 format + // + TInt Lth = 3*( iIkeData->iOwnCert.iSubjectDnSuffix.Length() ); + + if ( Lth ) + { + delete iSubjName; + iSubjName = NULL; + iSubjName = HBufC8::NewL(Lth); + + TPtr8 dn8 = iSubjName->Des(); + TPtrC16 dn16( iIkeData->iOwnCert.iSubjectDnSuffix ); + + if ( 0 != CnvUtfConverter::ConvertFromUnicodeToUtf8( + dn8, dn16 ) ) + { + User::Leave(KErrCorrupt); + } + } + else + { + iSubjName->Des().Zero(); + } + + Lth = iIkeData->iOwnCert.iRfc822NameFqdn.Length(); + + if ( Lth ) + { + delete iRfc822Name; + iRfc822Name = NULL; + iRfc822Name = HBufC8::NewL(Lth); + iRfc822Name->Des().Copy(iIkeData->iOwnCert.iRfc822NameFqdn); + } + else + { + iRfc822Name->Des().Zero(); + } + + if ( iIkeData->iOwnCert.iPrivateKeyLength ) + { + keySize = iIkeData->iOwnCert.iPrivateKeyLength; + } + } + + DEBUG_LOG(_L("<- CIkeV1PkiService::InitUserCertIdentDataL")); + return keySize; +} + + +TBool CIkeV1PkiService::GetNextCaElemL() +{ + // + // Get next CA certificate from PKI store using current CA name in + // iCaNameList. + // + DEBUG_LOG(_L("-> CIkeV1PkiService::GetNextCaElemL")); + + TCertInfo* CertInfo; + TBool Ret; + + Ret = EFalse; + TInt Status; + + while ( iCurrIndex < iCaNameList->Count() ) + { + CertInfo = iCaNameList->At(iCurrIndex); + + if ( CertInfo->iFormat == CA_NAME ) + { + TPtr8 dn8 = iCaName->Des(); + TPtrC16 dn16( CertInfo->iData ); + + if ( 0 != CnvUtfConverter::ConvertFromUnicodeToUtf8( + dn8, dn16 + ) ) + { + User::Leave(KErrCorrupt); + } + + Status = ReadCertificateL(KEmptyString, ETrue); + Ret |= AddNextCaElemL(Status); + } + else if ( CertInfo->iFormat == KEY_ID ) + { + Status = GetCertificateWithKeyIdL(CertInfo->iData); + Ret |= AddNextCaElemL(Status); + } + else if ( CertInfo->iFormat == APPL_UID ) + { + Ret |= GetApplUidListL(CertInfo->iData); + } + else + { + Ret |= EFalse; + iCurrIndex ++; + DEBUG_LOG1( + _L("Unsupported CA certificate element format = %d"), + CertInfo->iFormat + ); + } + + } + + iCaNameList = NULL; + + DEBUG_LOG(_L("<- CIkeV1PkiService::GetNextCaElemL")); + return Ret; +} + + +TBool CIkeV1PkiService::AddNextCaElemL(TInt& aStatus) +{ + DEBUG_LOG(_L("-> CIkeV1PkiService::AddNextCaElemL()")); + + // + // CA has been read PKI store. Build and add a new CIkeCaElem to CIkeCaList + // +#ifdef _DEBUG + CertReadCompleted(ETrue, aStatus, __LINE__); +#endif // _DEBUG + + if (aStatus == KErrNotFound) + { + DEBUG_LOG(_L(" Leave: status == KErrNotFound")); + User::Leave(KVpnErrInvalidCaCertFile); + } + + TBool Ret; + + if ( aStatus == KErrNone ) + { + ASSERT(iReadCertificate); + HBufC8* CaCert = iReadCertificate; // Link CA buffer to CIkeCaElem + CaCert->Des().SetLength(iCertPtr.Length()); + iReadCertificate = NULL; + CleanupStack::PushL(CaCert); + CIkeCaElem* CaElem = CIkeCaElem::NewL(CaCert); + CleanupStack::Pop(CaCert); + CleanupStack::PushL(CaElem); + iTrustedCAList->AppendL(CaElem); + CleanupStack::Pop(CaElem); + + if ( iOperation == KProcessingApplUidList ) + iListIndex ++; + else iCurrIndex ++; + + Ret = ETrue; + } + else + { + if ( iOperation == KProcessingApplUidList ) + iListIndex ++; + else iCurrIndex ++; + + Ret = EFalse; + } + + DEBUG_LOG(_L("<- CIkeV1PkiService::AddNextCaElemL()")); + + return Ret; +} + +TInt CIkeV1PkiService::GetNextCertificateL() +{ + DEBUG_LOG(_L("-> CIkeV1PkiService::GetNextCertificateL")); + // + // Get next user certificate from PKI store using either Key + // identifier or CA name as read argument + // + TInt Status = KErrNotFound; + if ( iCasTrustedByPeer.Count() > 0 ) + { + CIkeCaElem* CaElem = iCasTrustedByPeer[0]; + iCasTrustedByPeer.Remove(0); + iOperation = KReadingCertificate; + + HBufC8* CaName = IkeCert::GetCertificateFieldDERL( + CaElem->Certificate(), KSubjectName + ); + + if ( CaName ) + { + delete iCaName; + iCaName = CaName; + ReadCertificateL(*iCaName, EFalse); + Status = KErrNone; + } + + } + + DEBUG_LOG(_L("<- CIkeV1PkiService::GetNextCertificateL")); + return Status; +} + + +TBool CIkeV1PkiService::CertificateReadL(TInt& aStatus) +{ + // + // A Certificate has been read PKI store. + // Build X509 certificate object from certificate data + // +#ifdef _DEBUG + CertReadCompleted(EFalse, aStatus, __LINE__); +#endif // _DEBUG + TBool Status = ETrue; + + if ( aStatus == KErrNone ) + { + iReallocated = EFalse; + iReadCertificate->Des().SetLength(iCertPtr.Length()); + } + else + { + if ( (aStatus == KPKIErrBufferTooShort) && !iReallocated ) + { + // + // Certificate buffer was too small try to read once more if + // not already tried + // + Status = EFalse; + aStatus = KErrNone; + iReallocated = ETrue; + ReadCertificateL(*iCaName, EFalse); + } + + if ( (aStatus != KErrNone) && ( aStatus != KPKIErrBufferTooShort) ) + { + // + // User certificate not found from PKI store, try to read next + // + iReallocated = EFalse; + aStatus = GetNextCertificateL(); + + if ( aStatus == KErrNone ) + { + Status = EFalse; + } + } + } + + return Status; +} + + +TInt CIkeV1PkiService::ReadCertificateL(const TPKIKeyIdentifier& aKeyIdentifier) +{ + // + // Read certificate from PKI store using pkiserviceapi + // + TRequestStatus status; + + for (;;) // Only for easy exits... + { + if ( iReallocated ) + { + // + // Allocate a new buffer for ASN1 coded certificate read from + // PKI store. Buffer size is now asked from pkiserviceapi + // + delete iReadCertificate; + iReadCertificate = NULL; + TInt RealCertSize; + + if ( iPkiService.GetRequiredBufferSize(RealCertSize) == KErrNone ) + iCertBfrSize = (RealCertSize | 0x3) + 1; + // Try double size in error case + else iCertBfrSize = (iCertBfrSize << 1); + } + + if ( !iReadCertificate ) + iReadCertificate = HBufC8::NewL(iCertBfrSize); + + iCertPtr.Set((TUint8*)iReadCertificate->Ptr(), 0, iCertBfrSize); + + iPkiService.ReadCertificateL(aKeyIdentifier, iCertPtr, + &iResArray, status); + + User::WaitForRequest(status); + iPkiService.Finalize(iResArray); + iResArray = NULL; + + if ( (status.Int() == KPKIErrBufferTooShort) && !iReallocated ) + { + // + // Certificate buffer was too small try to read once more if + // not already tried + // + iReallocated = ETrue; + } + else + { + if ( status.Int() == KErrNone ) + { + iReadCertificate->Des().SetLength(iCertPtr.Length()); + iReallocated = EFalse; + } + break; + } + + } + + return status.Int(); +} + + +TInt CIkeV1PkiService::ReadCertificateListL() +{ + // + // Read certificate list with Application UID:s + // + if ( iCaCertList ) + { + iCaCertList->Reset(); + delete iCaCertList; + iCaCertList = NULL; + } + + iOperation = KBuildingApplUidList; + + iPkiService.ListApplicableCertificatesL( + (const RArray&)(*iApplUidList), iCaCertList + ); + + return KErrNone; +} + + +TInt CIkeV1PkiService::GetCertificateWithKeyIdL(const TDesC16& aKeyIdString) +{ + TInt Status; + + if ( IkeParser::TextToHexOctets(aKeyIdString, iCertKeyId) ) + Status = ReadCertificateL(iCertKeyId); + else Status = KErrArgument; + + return Status; +} + + +TBool CIkeV1PkiService::GetApplUidListL(const TDesC16& aApplUidString) +{ + // + // Build application UID array to get trusted CA certificate list + // from PKI service. + // + if ( iApplUidList ) + { + iApplUidList->Reset(); + delete iApplUidList; + iApplUidList = NULL; + } + + iApplUidList = IkeParser::GetApplUidListL(aApplUidString); + + TBool Status = (iApplUidList->Count() != 0); + + if ( Status ) + { + TInt Ret = ReadCertificateListL(); + Status = ( Ret == KErrNone); + iListIndex = 0; + + Status = ApplUidCertListCompletedL(Ret); + } + + return Status; +} + + +TBool CIkeV1PkiService::ApplUidCertListCompletedL(TInt aStatus) +{ + DEBUG_LOG2( + _L("Certificate list read completed, status= %d, list elem count= %d"), + aStatus, iCaCertList->Count() + ); + DEBUG_LOG1( + _L(" APPL UID(s) = %S\n"), &iCaNameList->At(iCurrIndex)->iData + ); + + TBool Ret; + + if ( (aStatus == KErrNone) && iCaCertList->Count() ) + { + // + // Start to read in trusted CA certificates provided in list + // + iOperation = KProcessingApplUidList; + Ret = ReadNextInListL(); + } + else + { + // + // No trusted CA certificates found with current application + // UID:s. Continue processing CA elements + // + Ret = EFalse; + iOperation = KBuildingCaList; + iCurrIndex ++; + + } + + return Ret; +} + + +TBool CIkeV1PkiService::ReadNextInListL() +{ + TBool Status = EFalse; + + TInt Ret; + + while ( iListIndex < iCaCertList->Count() ) + { + Ret = ReadCertificateL(iCaCertList->At(iListIndex).iSubjectKeyId); + if ( AddNextCaElemL(Ret) ) + Status = ETrue; + } + + iCurrIndex ++; + + return Status; +} + + +#ifdef _DEBUG + +void CIkeV1PkiService::CertReadCompleted(TBool aCaCert, TInt aStatus, TInt aLine ) +{ + TBuf<320>DebugMsg; + if ( aCaCert ) + { + ASSERT( iCurrIndex < iCaNameList->Count() ); + DebugMsg.Format(_L("Trusted CA certificate read completed with status = %d (line = %d)"), + aStatus, aLine); + DebugMsg.AppendFormat(_L(" ; Search criteria: ")); + TCertInfo* CertInfo = iCaNameList->At(iCurrIndex); + switch ( CertInfo->iFormat ) + { + case CA_NAME: + DebugMsg.AppendFormat(_L("CA_NAME = %S\n"), &CertInfo->iData); + break; + case KEY_ID: + DebugMsg.AppendFormat(_L("KEY_ID = %S\n"), &CertInfo->iData); + break; + default: + TBuf<48> KeyIdString; + ASSERT( iListIndex < iCaCertList->Count() ); + HexToString(iCaCertList->At(iListIndex).iSubjectKeyId, KeyIdString); + DebugMsg.AppendFormat(_L("APPL_UID/ = %S\n"), &KeyIdString); + break; + } + } + else + { + DEBUG_LOG2(_L("End user certificate read completed with status = %d (line = %d)\n"), + aStatus, aLine); + } + DEBUG_LOG(DebugMsg); +} + +void CIkeV1PkiService::HexToString(const TDesC8& aKeyId, TDes16& aKeyIdString) +{ + TInt i = 0; + TUint x; + TUint y; + + while (i < aKeyId.Length()) + { + x = (TUint)aKeyId[i]; + for ( TInt j = 4; j >= 0; j -= 4 ) + { + y = (x >> j) & 0xf; + TChar ch(y); + if ( y < 0xa ) + ch += 0x30; + else if ( (y > 9) && (y < 0x10) ) + ch += (0x61 - 0xa); + else ch += (0x30 - ch); + aKeyIdString.Append(ch); + } + i ++; + } +} + +#endif //_DEBUG diff -r 000000000000 -r 33413c0669b9 vpnengine/ikecert/src/ikev2pkiservice.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikecert/src/ikev2pkiservice.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,812 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 specifig certificate reading related stuff +* +*/ + +#include +#include +#include + +#include "ikev2pkiservice.h" +#include "utlcrypto.h" +#include "ikecert.h" +#include "ikecaelem.h" +#include "ikecalist.h" +#include "ikedebug.h" +#include "ikepolparser.h" +#include "ikev2const.h" +#include "ikecertconst.h" +// +// CIkePkiService Class +// +_LIT8(KEmptyString, ""); + + +const TInt KDefaultCertificateBufferSize = 2048; + +// +// Certificate field indicators for GetCertificateFieldDERL() +// + +#ifdef _DEBUG + +#define SET_ACTIVE DEBUG_LOG2(_L("CIkeV2PkiService::SetActive (0x%x) %d\n"), this, __LINE__);\ + SetActive() + +#else + +#define SET_ACTIVE SetActive() + +#endif + + +EXPORT_C CIkeV2PkiService* CIkeV2PkiService::NewL(MIkeV2PkiServiceObserver& aObserver, MIkeDebug& aDebug) + { + CIkeV2PkiService* self = new (ELeave) CIkeV2PkiService(aObserver, aDebug); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +CIkeV2PkiService::CIkeV2PkiService(MIkeV2PkiServiceObserver& aObserver, MIkeDebug& aDebug) + :CActive(EPriorityStandard), + iObserver(aObserver), + iDebug(aDebug), + iState(EPkiServiceIdle), + iCertPtr(NULL, 0) + { + CActiveScheduler::Add(this); + } + + +void CIkeV2PkiService::ConstructL() + { + User::LeaveIfError(iPkiService.Connect()); + + iTrustedCAList = new (ELeave) CIkeCaList(2); + iReadCertificate = HBufC8::NewL(KDefaultCertificateBufferSize); + iCertPtr.Set(iReadCertificate->Des()); + + //The code assumes that these are not NULL. + //Reallocated, when needed + iSubjName = HBufC8::NewL(2); + iRfc822Name = HBufC8::NewL(2); + } + + +EXPORT_C CIkeV2PkiService::~CIkeV2PkiService() + { + Cancel(); + + delete iUserCertificate; + delete i1Certificate; + delete i2Certificate; + delete i2CertificateName; + delete iTrustedCAList; + + iCasTrustedByPeer.Reset(); + iCasTrustedByPeer.Close(); + + delete iCaName; + delete iReadCertificate; + delete iSubjName; + delete iRfc822Name; + + iPkiService.Close(); + } + + +void CIkeV2PkiService::DoCancel() + { + + iPkiService.CancelPendingOperation(); + iState = EPkiServiceIdle; + + delete iCaName; + iCaName = NULL; + + __ASSERT_DEBUG(iReadCertificate != NULL, User::Invariant()); + iReadCertificate->Des().Zero(); + + + __ASSERT_DEBUG(iSubjName != NULL, User::Invariant()); + iSubjName->Des().Zero(); + + __ASSERT_DEBUG(iRfc822Name != NULL, User::Invariant()); + iRfc822Name->Des().Zero(); + + + iCasTrustedByPeer.Reset(); + + delete iIkeDataCAList; + iIkeDataCAList = NULL; + + iTrustedCAList->ResetAndDestroy(); + } + + +TInt CIkeV2PkiService::RunError(TInt /*aError*/) + { + //Currently RunL may leave. + //But we seem to ignore the possible leave. + + return KErrNone; + } + + +EXPORT_C void CIkeV2PkiService::ReadTrustedUserCertificateL() + { + __ASSERT_ALWAYS(!IsActive(), User::Invariant()); + __ASSERT_ALWAYS(iTrustedCAList != NULL, User::Invariant()); + __ASSERT_ALWAYS(iIkeData->iOwnCert.iOwnCertExists, User::Invariant()); + + iCasTrustedByPeer.Reset(); + + for (TInt i = 0; i < iTrustedCAList->Count(); ++i) + { + CIkeCaElem* caElem = (*iTrustedCAList)[i]; + User::LeaveIfError(iCasTrustedByPeer.Append(caElem)); + } + + + iState = EReadingCertificate; + + if (iTrustedCAList->Count() > 0) + { + CIkeCaElem* CaElem = iCasTrustedByPeer[0]; + HBufC8* caName = IkeCert::GetCertificateFieldDERL(CaElem->Certificate(), KSubjectName); + if (caName == NULL) + { + User::Leave(KErrArgument); + } + delete iCaName; + iCaName = caName; + + ReadUserCertificateL(*iCaName, EFalse); + } + else + { + //No CA's found. + //We can't read anything + User::Leave(KErrNotFound); + } + } + + +EXPORT_C TInt CIkeV2PkiService::Ikev2SignatureL(const TDesC8& aTrustedAuthority, + const TOwnCertInfo& aOwnCertInfo, + const TDesC8& aMsgOctets, + TDes8& aSignature, TUint8 aAuthMeth) + { + __ASSERT_ALWAYS(!IsActive(), User::Invariant()); + + TPKIKeyAlgorithm keyAlgorithm = EPKIRSA; + TInt length = aOwnCertInfo.iSubjectDnSuffix.Length(); + if ( length ) + { + delete iSubjName; + iSubjName = NULL; + iSubjName = HBufC8::NewL(length); + iSubjName->Des().Copy(aOwnCertInfo.iSubjectDnSuffix); + } + else + { + iSubjName->Des().Zero(); + } + + length = aOwnCertInfo.iRfc822NameFqdn.Length(); + if ( length ) + { + delete iRfc822Name; + iRfc822Name = NULL; + iRfc822Name = HBufC8::NewL(length); + iRfc822Name->Des().Copy(aOwnCertInfo.iRfc822NameFqdn); + } + else + { + iRfc822Name->Des().Zero(); + } + + // + // Build PKCS1v15 format signature (ASN1 encoded) for RSA and SHA1 for DSA + // + CUtlMessageDigest* digest = TUtlCrypto::MakeMessageDigesterL(TUtlCrypto::EUtlMessageDigestSha1); + CleanupStack::PushL(digest); + HBufC8* asn1EncodedHash =NULL; + HBufC8* DSSHash = NULL; + + switch( aAuthMeth ) + { + case RSA_DIGITAL_SIGN: + asn1EncodedHash = IkeCert::BuildPkcs1v15HashL(digest->Final(aMsgOctets)); + User::LeaveIfNull(asn1EncodedHash); + CleanupStack::PopAndDestroy(digest); + CleanupStack::PushL(asn1EncodedHash); + User::LeaveIfError(iPkiService.Sign(aTrustedAuthority, *iSubjName, *iRfc822Name, + EX509DigitalSignature, aOwnCertInfo.iPrivateKeyLength, + keyAlgorithm, *asn1EncodedHash, aSignature)); + CleanupStack::PopAndDestroy(asn1EncodedHash); + DEBUG_LOG(_L("Signing Auth data using RSA key.")); + break; + case DSS_DIGITAL_SIGN: + DSSHash = HBufC8::New(20); + DSSHash->Des().Append(digest->Final(aMsgOctets)); + CleanupStack::PopAndDestroy(digest); + CleanupStack::PushL(DSSHash); + User::LeaveIfError(iPkiService.Sign(aTrustedAuthority, *iSubjName, *iRfc822Name, + EX509DigitalSignature, aOwnCertInfo.iPrivateKeyLength, + keyAlgorithm, *DSSHash, aSignature)); + CleanupStack::PopAndDestroy(DSSHash); + DEBUG_LOG(_L("Signing Auth data using DSA key.")); + break; + default: + DEBUG_LOG1(_L("Authentication method %d not supported when using digital signatures."), aAuthMeth); + User::Leave(KErrNotSupported); + break; + } + + return aSignature.Length(); + } + + +EXPORT_C const CIkeCaList& CIkeV2PkiService::CaList() const + { + return *iTrustedCAList; + } + + +EXPORT_C const TDesC8& CIkeV2PkiService::UserCertificateData() const + { + if (iUserCertificate != NULL) + { + return *iUserCertificate; + } + else + { + return KEmptyString; + } + } + +EXPORT_C const TDesC8& CIkeV2PkiService::I2CertificateData() const + { + if (i2Certificate != NULL) + { + return *i2Certificate; + } + else + { + return KEmptyString; + } + } + +EXPORT_C const TDesC8& CIkeV2PkiService::I1CertificateData() const + { + if (i1Certificate != NULL) + { + return *i1Certificate; + } + else + { + return KEmptyString; + } + } + + +EXPORT_C const TDesC8& CIkeV2PkiService::TrustedCaName() const + { + if ( i2CertificateName != NULL ) + { + return *i2CertificateName; + } + if (iCaName != NULL) + { + return *iCaName; + } + else + { + return KEmptyString; + } + } + + +void CIkeV2PkiService::ReadUserCertificateL(const TDesC8& aTrustedAuthority, TBool aGetCACert) + { + __ASSERT_DEBUG(iReadCertificate != NULL, User::Invariant()); + // + // Read certificate from PKI store using pkiserviceapi + // + TPKIKeyAlgorithm keyAlgorithm = EPKIRSA; + TPKICertificateOwnerType ownerType; + TUint keySize = 0; + + if ( aGetCACert ) + { + ownerType = EPKICACertificate; + + //Init CA cert ident data. + //aTrustedAuthority (issuer) checking for CA certs is not supported. + //__ASSERT_ALWAYS(aTrustedAuthority.Length() == 0, User::Invariant()); + if ( aTrustedAuthority.Length() == 0 ) + { + delete iSubjName; + iSubjName = NULL; + iSubjName = iCaName->AllocL(); + iRfc822Name->Des().Zero(); + } + } + else + { + ownerType = EPKIUserCertificate; + TInt length = iIkeData->iOwnCert.iSubjectDnSuffix.Length(); + if ( length ) + { + delete iSubjName; + iSubjName = NULL; + iSubjName = HBufC8::NewL(length); + iSubjName->Des().Copy(iIkeData->iOwnCert.iSubjectDnSuffix); + } + else + { + iSubjName->Des().Zero(); + } + + length = iIkeData->iOwnCert.iRfc822NameFqdn.Length(); + if ( length ) + { + delete iRfc822Name; + iRfc822Name = NULL; + iRfc822Name = HBufC8::NewL(length); + iRfc822Name->Des().Copy(iIkeData->iOwnCert.iRfc822NameFqdn); + } + else + { + iRfc822Name->Des().Zero(); + } + keySize = iIkeData->iOwnCert.iPrivateKeyLength; + } + iPkiService.ReadCertificateL(aTrustedAuthority, + *iSubjName, *iRfc822Name, + ownerType, keySize, + keyAlgorithm, iCertPtr, + &iResArray, iStatus); + SET_ACTIVE; + } + + +void CIkeV2PkiService::CIkeV2PkiServiceApplUidArrayCleanup(TAny* any) + { + RArray* applUidList = reinterpret_cast*>(any); + applUidList->Reset(); + applUidList->Close(); + delete applUidList; + } + + +void CIkeV2PkiService::RunL() + { + DEBUG_LOG1(_L("CIkeV2PkiService::RunL: Status %d"), iStatus.Int()); + + // + // A PKI service operation completed. Take actions according to + // iOperation code + // + + TInt err = KErrNone; + + TInt status = iStatus.Int(); + + iPkiService.Finalize(iResArray); + iResArray = NULL; + + + switch ( iState ) + { + case EBuildingCaList: + TRAP(err, BuildingCaListRunL()); + break; + case EReadingCertificate: + TRAP(err, ReadUserCertificateRunL()); + break; + case EReadingCertificateChain: + TRAP(err, ReadCertificateChainRunL()); + break; + default: + DEBUG_LOG(_L("RunL called in unknown state")); + User::Invariant(); + break; + } + + if ( err != KErrNone ) + { + DEBUG_LOG(_L("Operation completed. Signalling observer.")); + + SignalObserverL(err); + } + } + + +void CIkeV2PkiService::ReadUserCertificateRunL() + { + // + // A Certificate has been read PKI store. + // Build X509 certificate object from certificate data + // + switch(iStatus.Int()) + { + case KErrNone: + iUserCertificate = iReadCertificate->AllocL(); + iReadCertificate->Des().Zero(); + SignalObserverL(KErrNone); + break; + case KPKIErrBufferTooShort: + { + // + // Allocate a new buffer for ASN1 coded certificate read from PKI store + // Buffer size is now asked from pkiserviceapi + // + TInt realCertSize; + User::LeaveIfError(iPkiService.GetRequiredBufferSize(realCertSize)); + + delete iReadCertificate; + iReadCertificate = NULL; + + iReadCertificate = HBufC8::NewL(realCertSize); + iCertPtr.Set(iReadCertificate->Des()); + + ReadUserCertificateL(*iCaName, EFalse); + } + break; + case KPKIErrNotFound: + { + // + // Get next user certificate from PKI store using either Key + // identifier or CA name as read argument + // + iCasTrustedByPeer.Remove(0); + if ( iCasTrustedByPeer.Count() > 0 ) + { + + CIkeCaElem* CaElem = iCasTrustedByPeer[0]; + HBufC8* caName = IkeCert::GetCertificateFieldDERL(CaElem->Certificate(), KSubjectName); + if (caName == NULL) + { + User::Leave(KErrArgument); + } + delete iCaName; + iCaName = caName; + caName=NULL; + delete caName; + ReadUserCertificateL(*iCaName, EFalse); + } + else + { + User::Leave(KErrNotFound); + } + } + break; + case KErrNotFound: + ReadCertificateChainL(); + break; + default: + User::Leave(iStatus.Int()); + break; + } + } + + +void CIkeV2PkiService::BuildingCaListRunL() + { + + switch(iStatus.Int()) + { + case KErrNone: + { + iIkeDataCAList->Delete(0); + + ASSERT(iReadCertificate); + HBufC8* caCert = iReadCertificate; // Link CA buffer to CIkeCaElem + CleanupStack::PushL(caCert); + + iReadCertificate = NULL; + iReadCertificate = HBufC8::NewL(KDefaultCertificateBufferSize); + iCertPtr.Set(iReadCertificate->Des()); + + + CIkeCaElem* caElem = CIkeCaElem::NewL(caCert); + CleanupStack::Pop(caCert); + CleanupStack::PushL(caElem); + + //Append ca cert to list, if not already present. + if (iTrustedCAList->FindCaElem(caElem->KeyHash()) == NULL) + { + iTrustedCAList->AppendL(caElem); + CleanupStack::Pop(caElem); + } + else + { + CleanupStack::PopAndDestroy(caElem); + } + + if (iIkeDataCAList->Count() > 0) + { + ImportNextCaElemFromIkeDataListL(); + } + else + { + + if (iIkeData->iOwnCert.iOwnCertExists) + { + ReadTrustedUserCertificateL(); + } + else + { + SignalObserverL(KErrNone); + } + } + } + break; + case KPKIErrBufferTooShort: + { + + DEBUG_LOG(_L("Buffer too short")); + + TInt certSize = 0; + User::LeaveIfError(iPkiService.GetRequiredBufferSize(certSize)); + + __ASSERT_DEBUG(iCertPtr.MaxLength() < certSize, User::Invariant()); + + delete iReadCertificate; + iReadCertificate = NULL; + iReadCertificate = HBufC8::NewL(certSize); + iCertPtr.Set(iReadCertificate->Des()); + + //Tries to reimport the certificate. + ImportNextCaElemFromIkeDataListL(); + } + break; + default: + DEBUG_LOG1(_L("Error code %d"), iStatus.Int()); + User::Leave(iStatus.Int()); + break; + } + } + + +EXPORT_C void CIkeV2PkiService::InitIkeV2PkiService(const CIkeData* aIkeData) + { + __ASSERT_DEBUG(iState == EPkiServiceIdle, User::Invariant()); + __ASSERT_DEBUG(iIkeDataCAList == NULL, User::Invariant()); + __ASSERT_DEBUG(aIkeData->iCAList != NULL, User::Invariant()); + __ASSERT_DEBUG(aIkeData->iCAList->Count() > 0, User::Invariant()); + __ASSERT_DEBUG(iIkeData == NULL, User::Invariant()); + + iIkeData = aIkeData; + + iState = EBuildingCaList; + TRAPD(err, InitIkeV2PkiServiceL()); + if (err != KErrNone) + { + iStatus = KRequestPending; + SET_ACTIVE; + + TRequestStatus* status = &iStatus; + User::RequestComplete(status, err); + } + } + + +void CIkeV2PkiService::InitIkeV2PkiServiceL() + { + if (iIkeData->iClientCertType != NULL) + { + if (iIkeData->iClientCertType->GetData().Compare(_L("DEVICE")) == 0) + { + User::LeaveIfError(iPkiService.SetStoreType(EPkiStoreTypeDevice)); + } + else + { + User::LeaveIfError(iPkiService.SetStoreType(EPkiStoreTypeUser)); + } + } + + iIkeDataCAList = new (ELeave) CArrayFixFlat(2); + for (TInt i = 0; i < iIkeData->iCAList->Count(); ++i) + { + const TCertInfo* info = (*iIkeData->iCAList)[i]; + iIkeDataCAList->AppendL(*info); + } + + ImportNextCaElemFromIkeDataListL(); + } + + +void CIkeV2PkiService::ImportNextCaElemFromIkeDataListL() + { + __ASSERT_DEBUG(iIkeDataCAList != NULL, User::Invariant()); + __ASSERT_DEBUG(iIkeDataCAList->Count() > 0, User::Invariant()); + + const TCertInfo certInfo = (*iIkeDataCAList)[0]; + switch(certInfo.iFormat) + { + case CA_NAME: + delete iSubjName; + iSubjName = NULL; + iSubjName = HBufC8::NewL(certInfo.iData.Length()); + iSubjName->Des().Copy(certInfo.iData); + iPkiService.ReadCertificateL(KEmptyString, + *iSubjName, KEmptyString, + EPKICACertificate, 0, + EPKIRSA, iCertPtr, + &iResArray, iStatus); + SET_ACTIVE; + break; + case KEY_ID: + if (!IkeParser::TextToHexOctets(certInfo.iData, iCertKeyId)) + { + User::Leave(KErrArgument); + } + iPkiService.ReadCertificateL(iCertKeyId, iCertPtr, + &iResArray, iStatus); + SET_ACTIVE; + break; + case APPL_UID: + { + //Get the list of applicable CA certs and appends it + //to the original list, which was defined in the policy. + //After this removes the currently handled node and + //calls the method recursively. + RArray* applUidList = IkeParser::GetApplUidListL(certInfo.iData); + CleanupStack::PushL(TCleanupItem(CIkeV2PkiServiceApplUidArrayCleanup, + applUidList)); + + CArrayFix* applicableCaCertList; + iPkiService.ListApplicableCertificatesL(*applUidList, applicableCaCertList); + + CleanupStack::PopAndDestroy(); //applUidList + + if (applicableCaCertList->Count() > 0) + { + CleanupStack::PushL(applicableCaCertList); + TCertInfo* info = new (ELeave) TCertInfo; + CleanupDeletePushL(info); + for (TInt i = 0; i < applicableCaCertList->Count(); i++) + { + const TCertificateListEntry& entry = (*applicableCaCertList)[i]; + info->iFormat = CA_NAME; + info->iData.Zero(); + info->iData.Copy(entry.iIdentitySubjectName); + + iIkeDataCAList->AppendL(*info); + DEBUG_LOG1(_L("Appending Applicable cert to the list (%S)"), &(info->iData)); + + } + + CleanupStack::PopAndDestroy(info); + CleanupStack::PopAndDestroy(applicableCaCertList); + + iIkeDataCAList->Delete(0); + ImportNextCaElemFromIkeDataListL(); + } + else + { + delete applicableCaCertList; + applicableCaCertList = NULL; + + iStatus = KRequestPending; + SET_ACTIVE; + + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNotFound); + } + } + break; + default: + User::Leave(KErrArgument); + break; + } + } + +void CIkeV2PkiService::ReadCertificateChainL() + { + delete iCaName; + iCaName = NULL; + iCaName = IkeCert::GetCertificateFieldDERL(iCasTrustedByPeer[0]->Certificate(), KSubjectName);; + iState = EReadingCertificateChain; + ReadUserCertificateL(KEmptyString, EFalse); + } + +void CIkeV2PkiService::ReadCertificateChainRunL() + { + TInt err; + HBufC8* issuerName=NULL; + TRAP(err, issuerName = IkeCert::GetCertificateFieldDERL(iReadCertificate, KIssuerName)); + if (err!=KErrNone) + { + err=KKmdIkeNoCertFoundErr; + User::Leave(err); + } + if ( issuerName->Compare(iCaName->Des())==0) + { + iReadCertificate->Des().Zero(); + delete issuerName; + issuerName = NULL; + SignalObserverL(KErrNone); + } + else + { + delete issuerName; + issuerName = NULL; + delete iCaName; + iCaName = NULL; + iCaName = IkeCert::GetCertificateFieldDERL(iReadCertificate, KIssuerName); + delete iSubjName; + iSubjName = NULL; + iSubjName = iCaName->AllocL(); + if ( !iUserCertificate) + iUserCertificate = iReadCertificate->AllocL(); + else if ( !i2Certificate ) + { + i2Certificate = iReadCertificate->AllocL(); + i2CertificateName= IkeCert::GetCertificateFieldDERL(i2Certificate, KSubjectName); + } + else if ( !i1Certificate) + i1Certificate = iReadCertificate->AllocL(); + + iPkiService.ReadCertificateL(KEmptyString, + *iSubjName, KEmptyString, + EPKICACertificate, 0, + EPKIRSA, iCertPtr, + &iResArray, iStatus); + SET_ACTIVE; + } + + } + +void CIkeV2PkiService::SignalObserverL(TInt aStatus) +{ + DEBUG_LOG1(_L("CIkeV2PkiService::SignalObserverL: Signalling with %d"), aStatus); + + if (aStatus != KErrNone) + { + delete iUserCertificate; + iUserCertificate = NULL; + + delete iCaName; + iCaName = NULL; + + iCertPtr.Zero(); + + iTrustedCAList->ResetAndDestroy(); // Trusted CA certificate list + + } + + iIkeData = NULL; + + iSubjName->Des().Zero(); + iRfc822Name->Des().Zero(); + + iCertKeyId.Zero(); + iResArray = NULL; + + iCasTrustedByPeer.Reset(); + + delete iIkeDataCAList; + iIkeDataCAList = NULL; + + iState = EPkiServiceIdle; + iObserver.IkeV2PkiInitCompleteL(aStatus); +} diff -r 000000000000 -r 33413c0669b9 vpnengine/ikepolparser/EABI/ikepolparserU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikepolparser/EABI/ikepolparserU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,52 @@ +EXPORTS + _ZN10TIkeParser10MainParseLEP13CIkeDataArray @ 1 NONAME + _ZN10TIkeParser12BufferAppendERP6HBufC8RK6TDesC8 @ 2 NONAME + _ZN10TIkeParser16GeneralInfoWriteEmmiRP6HBufC8 @ 3 NONAME + _ZN10TIkeParser16GeneralInfoWriteEmmiiRP6HBufC8 @ 4 NONAME + _ZN10TIkeParser17ParseIKESectionsLEP13CIkeDataArray @ 5 NONAME + _ZN10TIkeParser5WriteEP8CIkeDataRP6HBufC8 @ 6 NONAME + _ZN10TIkeParser6ParseLEP8CIkeData @ 7 NONAME + _ZN10TIkeParser9MainWriteEP8CIkeDataRP6HBufC8 @ 8 NONAME + _ZN10TIkeParserC1ERK7TDesC16i @ 9 NONAME + _ZN10TIkeParserC1Ev @ 10 NONAME + _ZN10TIkeParserC2ERK7TDesC16i @ 11 NONAME + _ZN10TIkeParserC2Ev @ 12 NONAME + _ZN10TSecParser16ParseGeneralDataEP12CGeneralData @ 13 NONAME + _ZN10TSecParser5WriteEP14CSecurityPieceRP6HBufC8 @ 14 NONAME + _ZN12CGeneralDataC1EPS_ @ 15 NONAME + _ZN12CGeneralDataC1Ev @ 16 NONAME + _ZN12CGeneralDataC2EPS_ @ 17 NONAME + _ZN12CGeneralDataC2Ev @ 18 NONAME + _ZN13CIkeDataArray10ConstructLEPS_ @ 19 NONAME + _ZN13CIkeDataArray4NewLEPS_ @ 20 NONAME + _ZN13CIkeDataArray4NewLEi @ 21 NONAME + _ZN13CIkeDataArray5CopyLEPS_ @ 22 NONAME + _ZN13CIkeDataArray5EmptyEv @ 23 NONAME + _ZN13CIkeDataArrayD0Ev @ 24 NONAME + _ZN13CIkeDataArrayD1Ev @ 25 NONAME + _ZN13CIkeDataArrayD2Ev @ 26 NONAME + _ZN14CSecurityPiece10ConstructLEi @ 27 NONAME + _ZN14CSecurityPiece8SetInfoLERK7TDesC16 @ 28 NONAME + _ZN14CSecurityPieceD0Ev @ 29 NONAME + _ZN14CSecurityPieceD1Ev @ 30 NONAME + _ZN14CSecurityPieceD2Ev @ 31 NONAME + _ZN14TGeneralParser5ParseEP12CGeneralData @ 32 NONAME + _ZN14TGeneralParserC1ERK7TDesC16 @ 33 NONAME + _ZN14TGeneralParserC2ERK7TDesC16 @ 34 NONAME + _ZN8CIkeData10ConstructLEPKS_ @ 35 NONAME + _ZN8CIkeData4NewLEPKS_ @ 36 NONAME + _ZN8CIkeData4NewLEv @ 37 NONAME + _ZN8CIkeData5CopyLEPKS_ @ 38 NONAME + _ZN8CIkeDataD0Ev @ 39 NONAME + _ZN8CIkeDataD1Ev @ 40 NONAME + _ZN8CIkeDataD2Ev @ 41 NONAME + _ZN9IkeParser15GetApplUidListLERK7TDesC16 @ 42 NONAME + _ZN9IkeParser15TextToHexOctetsERK7TDesC16R5TDes8 @ 43 NONAME + _ZN9IkeParser16TextToHexOctetsLERK7TDesC16 @ 44 NONAME + _ZTI13CIkeDataArray @ 45 NONAME ; ## + _ZTI14CSecurityPiece @ 46 NONAME ; ## + _ZTI8CIkeData @ 47 NONAME ; ## + _ZTV13CIkeDataArray @ 48 NONAME ; ## + _ZTV14CSecurityPiece @ 49 NONAME ; ## + _ZTV8CIkeData @ 50 NONAME ; ## + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikepolparser/bwins/IKEPOLPARSERU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikepolparser/bwins/IKEPOLPARSERU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,35 @@ +EXPORTS + ??0CGeneralData@@QAE@PAV0@@Z @ 1 NONAME ; CGeneralData::CGeneralData(class CGeneralData *) + ??0CGeneralData@@QAE@XZ @ 2 NONAME ; CGeneralData::CGeneralData(void) + ??0TGeneralParser@@QAE@ABVTDesC16@@@Z @ 3 NONAME ; TGeneralParser::TGeneralParser(class TDesC16 const &) + ??0TIkeParser@@QAE@ABVTDesC16@@H@Z @ 4 NONAME ; TIkeParser::TIkeParser(class TDesC16 const &, int) + ??0TIkeParser@@QAE@XZ @ 5 NONAME ; TIkeParser::TIkeParser(void) + ??1CIkeData@@UAE@XZ @ 6 NONAME ; CIkeData::~CIkeData(void) + ??1CIkeDataArray@@UAE@XZ @ 7 NONAME ; CIkeDataArray::~CIkeDataArray(void) + ??1CSecurityPiece@@UAE@XZ @ 8 NONAME ; CSecurityPiece::~CSecurityPiece(void) + ?BufferAppend@TIkeParser@@SAHAAPAVHBufC8@@ABVTDesC8@@@Z @ 9 NONAME ; int TIkeParser::BufferAppend(class HBufC8 * &, class TDesC8 const &) + ?ConstructL@CIkeDataArray@@QAEXPAV1@@Z @ 10 NONAME ; void CIkeDataArray::ConstructL(class CIkeDataArray *) + ?ConstructL@CSecurityPiece@@QAEXH@Z @ 11 NONAME ; void CSecurityPiece::ConstructL(int) + ?CopyL@CIkeDataArray@@QAEXPAV1@@Z @ 12 NONAME ; void CIkeDataArray::CopyL(class CIkeDataArray *) + ?Empty@CIkeDataArray@@QAEXXZ @ 13 NONAME ; void CIkeDataArray::Empty(void) + ?GeneralInfoWrite@TIkeParser@@SAHKKHAAPAVHBufC8@@@Z @ 14 NONAME ; int TIkeParser::GeneralInfoWrite(unsigned long, unsigned long, int, class HBufC8 * &) + ?GeneralInfoWrite@TIkeParser@@SAHKKHHAAPAVHBufC8@@@Z @ 15 NONAME ; int TIkeParser::GeneralInfoWrite(unsigned long, unsigned long, int, int, class HBufC8 * &) + ?GetApplUidListL@IkeParser@@SAPAV?$RArray@VTUid@@@@ABVTDesC16@@@Z @ 16 NONAME ; class RArray * IkeParser::GetApplUidListL(class TDesC16 const &) + ?MainParseL@TIkeParser@@QAEXPAVCIkeDataArray@@@Z @ 17 NONAME ; void TIkeParser::MainParseL(class CIkeDataArray *) + ?MainWrite@TIkeParser@@SAHPAVCIkeData@@AAPAVHBufC8@@@Z @ 18 NONAME ; int TIkeParser::MainWrite(class CIkeData *, class HBufC8 * &) + ?NewL@CIkeData@@SAPAV1@XZ @ 19 NONAME ; class CIkeData * CIkeData::NewL(void) + ?NewL@CIkeDataArray@@SAPAV1@H@Z @ 20 NONAME ; class CIkeDataArray * CIkeDataArray::NewL(int) + ?NewL@CIkeDataArray@@SAPAV1@PAV1@@Z @ 21 NONAME ; class CIkeDataArray * CIkeDataArray::NewL(class CIkeDataArray *) + ?Parse@TGeneralParser@@QAEHPAVCGeneralData@@@Z @ 22 NONAME ; int TGeneralParser::Parse(class CGeneralData *) + ?ParseGeneralData@TSecParser@@QAEHPAVCGeneralData@@@Z @ 23 NONAME ; int TSecParser::ParseGeneralData(class CGeneralData *) + ?ParseIKESectionsL@TIkeParser@@QAEXPAVCIkeDataArray@@@Z @ 24 NONAME ; void TIkeParser::ParseIKESectionsL(class CIkeDataArray *) + ?ParseL@TIkeParser@@QAEXPAVCIkeData@@@Z @ 25 NONAME ; void TIkeParser::ParseL(class CIkeData *) + ?SetInfoL@CSecurityPiece@@QAEXABVTDesC16@@@Z @ 26 NONAME ; void CSecurityPiece::SetInfoL(class TDesC16 const &) + ?TextToHexOctets@IkeParser@@SAHABVTDesC16@@AAVTDes8@@@Z @ 27 NONAME ; int IkeParser::TextToHexOctets(class TDesC16 const &, class TDes8 &) + ?TextToHexOctetsL@IkeParser@@SAPAVHBufC8@@ABVTDesC16@@@Z @ 28 NONAME ; class HBufC8 * IkeParser::TextToHexOctetsL(class TDesC16 const &) + ?Write@TIkeParser@@SAHPAVCIkeData@@AAPAVHBufC8@@@Z @ 29 NONAME ; int TIkeParser::Write(class CIkeData *, class HBufC8 * &) + ?Write@TSecParser@@SAHPAVCSecurityPiece@@AAPAVHBufC8@@@Z @ 30 NONAME ; int TSecParser::Write(class CSecurityPiece *, class HBufC8 * &) + ?ConstructL@CIkeData@@QAEXPBV1@@Z @ 31 NONAME ; void CIkeData::ConstructL(class CIkeData const *) + ?CopyL@CIkeData@@QAEXPBV1@@Z @ 32 NONAME ; void CIkeData::CopyL(class CIkeData const *) + ?NewL@CIkeData@@SAPAV1@PBV1@@Z @ 33 NONAME ; class CIkeData * CIkeData::NewL(class CIkeData const *) + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikepolparser/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikepolparser/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file provides the information required for building the module. +* +*/ + + + +#include + +PRJ_PLATFORMS + +PRJ_EXPORTS + + +PRJ_MMPFILES +ikepolparser.mmp + +PRJ_TESTMMPFILES + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikepolparser/group/ikepolparser.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikepolparser/group/ikepolparser.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project ikepolparser +* +*/ + + + +#include + +TARGET ikepolparser.dll +TARGETTYPE dll +UID 0x1000008d 0x101fae09 + +CAPABILITY ALL -Tcb +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE ikepolparser.cpp + +USERINCLUDE ../inc + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY euser.lib +LIBRARY insock.lib diff -r 000000000000 -r 33413c0669b9 vpnengine/ikepolparser/inc/ikepolparser.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikepolparser/inc/ikepolparser.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,444 @@ +/* +* Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE policy parser main module +* +*/ + + + +#ifndef __IKEPOLPARSER_H +#define __IKEPOLPARSER_H + +#include +#include +#include + +#define FIRST_SEC_PARSER_VERSION 1 +#define SEC_PARSER_VERSION 3 + +#define IKE_HOST_SEPARATOR _L("[HOST]") +#define IKE_SEPARATOR _L("[IKE]") +#define IKE_HOST_SEPARATOR_LEN 6 +#define IKE_GENERAL_SEPARATOR _L("[GENERAL]") +#define IKE_GENERAL_SEPARATOR_LEN 9 + +#define MAX_INFO_SIZE 1024 +#define PIECE_AVG_LENGTH 2048 + +const TInt KIkePolicyBufferSizeIncrement = 6000; + +const TInt KNokiaNattDefaultPort = 9872; + +//Security Ike Parser Error codes +// NOTE! The error code values below MUST be kept in sync with +// the corresponding error code values defined together by +// vpnapi/data/vpnerr.rss and vpnapi/data/vpnerr.ra +const TInt KSecParserErrMode = -5263; +const TInt KSecParserErrNotify = -5264; +const TInt KSecParserErrCommit = -5265; +const TInt KSecParserErrIpsecExpire = -5266; +const TInt KSecParserErrSendCert = -5267; +const TInt KSecParserErrInitialContact = -5268; +const TInt KSecParserErrResponderLifetime = -5269; +const TInt KSecParserErrReplayStatus = -5270; +const TInt KSecParserErrGroupDesc_II = -5271; +const TInt KSecParserErrProposal = -5272; +const TInt KSecParserErrEncrAlg = -5273; +const TInt KSecParserErrAuthMethod = -5274; +const TInt KSecParserErrHashAlg = -5275; +const TInt KSecParserErrGroupDesc = -5276; +const TInt KSecParserErrGroupType = -5277; +const TInt KSecParserErrLifeBytes = -5278; +const TInt KSecParserErrLifeSecs = -5279; +const TInt KSecParserErrPRF = -5280; +const TInt KSecParserErrPreKey = -5281; +const TInt KSecParserErrPreFormat = -5282; +const TInt KSecParserErrCA = -5283; +const TInt KSecParserErrOwnCerts = -5284; +const TInt KSecParserErrOwnName = -5285; +const TInt KSecParserErrOwnKey = -5286; +const TInt KSecParserErrPeerCerts = -5287; +const TInt KSecParserErrPeerAddr = -5288; +const TInt KSecParserErrPeerMask = -5289; +const TInt KSecParserErrMaxLifetimeSec = -5290; +const TInt KSecParserErrMaxLifetimeKB = -5291; +const TInt KSecParserErrMaxRetrans = -5292; +const TInt KSecParserErrNoSeparator = -5293; +const TInt KSecParserErrCRACKLAMType = -5294; +const TInt KSecParserErrUseIntAddr = -5295; +const TInt KSecParserErrUseNATProbe = -5296; +const TInt KSecParserErrUnknown = -5297; + + + +//Values for the choice lists used in the .RSS +enum {IKE_PARSER_MAIN, + IKE_PARSER_AGGRESSIVE}; //Modes +enum {IKE_PARSER_DES_CBC, + IKE_PARSER_DES3_CBC, + IKE_PARSER_AES_CBC}; +enum {IKE_PARSER_PRE_SHARED, + IKE_PARSER_DSS_SIG, + IKE_PARSER_RSA_SIG, + IKE_PARSER_RSA_ENCR, + IKE_PARSER_RSA_REV_ENCR, + IKE_PARSER_CRACK}; +enum {IKE_PARSER_MD5, + IKE_PARSER_SHA1}; +enum {IKE_PARSER_MODP_768 = 1, + IKE_PARSER_MODP_1024 = 2, + IKE_PARSER_MODP_1536 = 5, + IKE_PARSER_MODP_2048 = 14}; +enum {IKE_PARSER_DEFAULT, + IKE_PARSER_MODP}; +enum {IKE_PARSER_NONE, + IKE_PARSER_DES3_CBC_MAC}; + +//CRACK Legacy Authentication types +#define IKE_PARSER_CRACK_PASSWORD 1 + +//------------------------------------------------------------------------ +// +// IKE Parser +// +//------------------------------------------------------------------------ + +//Data on a single proposal +struct TProposalData +{ + TUint8 iEncrAlg; + TUint8 iAuthMeth; + TUint8 iHashAlg; + TUint8 iGroupDesc; + TUint8 iGroupType; + TUint8 iPRF; + TUint32 iLifetimeKb; + TUint32 iLifetimeSec; + TInt iEncrKeyLth; + + TProposalData *iNext; //Used for chaining + TProposalData *iPrev; //to make easier changing the order + +}; + + +static const TUint KMaxPresharedKeyLength = 256; +enum TKeyFormat +{ + STRING_KEY = 0, + HEX_KEY = 1 +}; + +struct TPresharedKeyData +{ + TBuf iKey; + TKeyFormat iFormat; +}; + +enum TCertFormat +{ + PEM_CERT = 0, + BIN_CERT = 1, + CA_NAME = 2, + KEY_ID = 3, + APPL_UID = 4 +}; + + +//RSA Encryption peer public keys +struct TCertInfo +{ + TCertFormat iFormat; + TFileName iData; +}; + + +enum TIdentityAsRfc822Name + { + EIdentityAsRfc822NameUndefined = 0, + EIdentityAsRfc822NameYes = 1, + EIdentityAsRfc822NameNo = 2 + }; + +//Own certificates +struct TOwnCertInfo +{ + TCertFormat iFormat; + TFileName iData; //File containing the peer RSA public key + TBuf<128> iRfc822NameFqdn; + TIdentityAsRfc822Name iIdentityAsRfc822Name; + TBuf<256> iSubjectDnSuffix; + TInt iPrivateKeyLength; + TInt iOwnCertExists; // 0 = no own cert 1 = own cert exists +}; + +class TStringData +{ + public: + TStringData() :iBfr(NULL) {} + TStringData(HBufC16* aBfr) :iBfr(aBfr) {} + ~TStringData() {delete iBfr;} + static inline TStringData* NewL(TInt aLth) + { + HBufC16* Databfr = HBufC16::NewL(aLth); + TStringData* StringData = new (ELeave)TStringData(Databfr); + return StringData; + } + static inline TStringData* NewL(const TPtrC16& aString) + { + TStringData* Obj = TStringData::NewL(aString.Length()); + Obj->iBfr->Des().Copy(aString); + return Obj; + } + inline TPtrC16 GetData() + { + TPtrC16 DataPtr(NULL, 0); + if ( iBfr ) + DataPtr.Set(iBfr->Des()); + return DataPtr; + } + inline HBufC8* GetAsciiDataL() + { + HBufC8* Bfr8 = NULL; + if ( iBfr ) + { + Bfr8 = HBufC8::NewL(iBfr->Des().Length()); + Bfr8->Des().Copy(iBfr->Des()); + } + return Bfr8; + } + + private: + HBufC16* iBfr; // Variable length data buffer + +}; + + +class CIkeData : public CBase +{ +public: + IMPORT_C static CIkeData* NewL(); + IMPORT_C static CIkeData* NewL(const CIkeData *aData); + IMPORT_C void ConstructL(const CIkeData *aData); + + EXPORT_C ~CIkeData(); + IMPORT_C void CopyL(const CIkeData *aData); + void Empty(); +private: + CIkeData(); +public: + TStringData* iFQDNAddr; //Peer host address in FQDN format + TInetAddr iAddr; //Peer host address + TInetAddr iMask; //Peer host mask + TInetAddr iDnsServer; + TUint8 iMode; + TUint8 iIkeVersion; //Preferred IKE version + TUint8 iIdType; //IKE Phase 1 identity type code. Integer value according to rfc2407 + TUint8 iRemoteIdType; + TBool iSkipRemoteIdCheck; + TBuf<128> iFQDN; + TStringData* iRemoteIdentity; + TBool iAcceptPartialRemoteId; + + TBool iNotify; + TBool iCommit; //COMMIT bit processing + TBool iInitialContact; //INITIAL-CONTACT sending + TBool iResponderLifetime; //RESPONDER_LIFETIME sending + TBool iReplayStatus; //REPLAY_STATUS sending + TBool iIpsecExpires; //IPSEC SAs expire with ISAKMP SAs + TBool iAlwaysSendCert; //Sends a Cert without even if NOT receiving a CR + +// Private IKE extension + TBool iUseInternalAddr; + TBool iUseNatProbing; + TBool iUseXauth; //Use XAUTH defined in + TBool iUseCfgMode; //Use CFG-MODE defined in + TBool iUseMobIke; //Use MOBIKE Ikev2 extension + TInt iEspUdpPort; //Port value for IPSEC ESP encapsulation (= In NAT-traversal) + TInt iNatKeepAlive; //NAT keep alive timeout in seconds (if zero not used) + TUint8 iDscp; //DSCP tag + TInt iDPDHeartBeat; //DPD Heart beat timeout in seconds (if zero not used) + TInt iRekeyingThreshold; //Rekeying threshold value + TUint8 iGroupDesc_II; + TUint8 iCRACKLAMType; //CRACK Legacy Authentication Method type + TStringData* iCRACKLAMUserName; + TStringData* iCRACKLAMPassword; + TStringData* iClientCertType; + TUint8 iEAPProtocol; + TUint8 iEAPReserved; + TBool iEAPHideIdentity; + TStringData* iEAPRealmPrefix; + TStringData* iEAPManualRealm; + TStringData* iEAPManualUserName; + TBool iCARequired; //If RSA based authentication method is used then at least one CA is required + TBool iCAFound; //CAs section + TInt iNumProp; + TProposalData *iPropList; + TPresharedKeyData iPresharedKey; + TCertInfo iCA; // Left for backward compatibility + CArrayFixFlat *iCAList; // For multiple CAs + TOwnCertInfo iOwnCert; + TCertInfo iPrivKey; + TCertInfo iPeerCert; + +}; + + +class CIkeDataArray : public CArrayFixFlat +{ +public: + IMPORT_C static CIkeDataArray* NewL(TInt aGranularity); + IMPORT_C static CIkeDataArray* NewL(CIkeDataArray *aData); + IMPORT_C void ConstructL(CIkeDataArray *aData); + + IMPORT_C ~CIkeDataArray(); + IMPORT_C void CopyL(CIkeDataArray *aData); + IMPORT_C void Empty(); +private: + CIkeDataArray(TInt aGranularity); + CIkeDataArray(CIkeDataArray *aData); +public: + //General Data + TUint32 iMaxLifetimeSec; + TUint32 iMaxLifetimeKB; + TInt iMaxRetrans; + TInt iMaxTraceFileSize; +}; + +class TIkeParser : public TLex +{ +public: + IMPORT_C TIkeParser(); + IMPORT_C TIkeParser(const TDesC &aStr, TInt aVersion = SEC_PARSER_VERSION); + IMPORT_C void MainParseL(CIkeDataArray *aIkeList); + IMPORT_C void ParseL(CIkeData *aConf); + IMPORT_C static TInt MainWrite(CIkeData *aConf, HBufC8*& aPolBfr); + IMPORT_C static TInt GeneralInfoWrite( + TUint32 aMaxLifetimeSec, TUint32 aMaxLifetimeKB, + TInt aMaxRetrans, HBufC8*& aPolBfr); + IMPORT_C static TInt GeneralInfoWrite( + TUint32 aMaxLifetimeSec, TUint32 aMaxLifetimeKB, + TInt aMaxRetrans, TInt aMaxTraceFileSize, HBufC8*& aPolBfr); + IMPORT_C static TInt Write(CIkeData *aConf, HBufC8*& aPolBfr); + IMPORT_C void ParseIKESectionsL(CIkeDataArray *aIkeList); + IMPORT_C static TInt BufferAppend( HBufC8*& aPolBfr, const TDesC8& aText); + +private: + TInt ParseGeneralData(CIkeDataArray *aIkeList); + void ParseIkePieceL(CIkeData *aIkeData, TInt aVersion, TPtrC& aSectionName); + void DoMainParseL(CIkeDataArray *aIkeList, TPtrC& aSectionName); + TInt ParseProposals(CIkeData *aConf); + TInt ParsePresharedKeys(CIkeData *aConf); + TInt ParseCAs(CIkeData *aConf); + TInt ParseCAItem(CIkeData *aConf, TCertInfo *aCA, TPtrC& aToken); + void ParseCAListL(CIkeData *aConf, TInt aCACount, TPtrC& aToken); + TInt ParseOwnCerts(CIkeData *aConf); + TInt ParsePeerCerts(CIkeData *aConf); + TInt CheckPolicy(CIkeData* aConf); + TPtrC GetRestOfLine(); + TInt ParseFileName(TDes& aFileName); + + static TBufC<16> TextMode(const TInt aMode); + static TBufC<16> TextEncrAlg(const TInt aAlg, const TInt aKeyLth); + static TBufC<16> TextAuthMethod(const TInt aMethod); + static TBufC<16> TextHashAlg(const TInt aAlg); + static TBufC<16> TextGroupDesc(const TInt aDesc); + static TBufC<16> TextGroupType(const TInt aType); + static TBufC<16> TextPRF(const TInt aPRF); + static TBufC<16> TextFormat(const TKeyFormat aFormat); + static TBufC<16> CertFormat(TCertFormat aFormat); + static TBufC<16> TextLAMType(const TUint8 aLAMType); +private: + TInt iVersion; +}; + + +class CGeneralData : public CBase +{ +public: + IMPORT_C CGeneralData(); + IMPORT_C CGeneralData(CGeneralData* aData); +public: + TInt iDeactivationTimeout; +}; + + + +//------------------------------------------------------------------------ +//Multiple Security Info combined +class CSecurityPiece : public CBase +{ +public: + IMPORT_C void ConstructL(TInt aSize = 64); //default 64 bytes description + inline HBufC *Info() {return iInfo;} + IMPORT_C void SetInfoL(const TDesC &aDes); //needed to resize it if needed + inline CIkeData *IkeData() {return iIkeData;} + inline CGeneralData *GeneralData(){return iGeneralData;} + IMPORT_C ~CSecurityPiece(); + +private: + HBufC* iInfo; + CIkeData *iIkeData; + CGeneralData *iGeneralData; +}; + +typedef CArrayFixFlat CPiecesList; + +// +// class TSecParser +// + +class TSecParser : public TLex +{ +public: + IMPORT_C TSecParser(const TDesC &aDes); + IMPORT_C TInt ParseL(CSecurityPiece *aPiece_data); + IMPORT_C static TInt Write(CSecurityPiece *aPiece_data, HBufC8*& aPolBfr); + IMPORT_C TInt ParseGeneralData(CGeneralData* aData); +private: + TBool CheckVersion(); + void ParseInfoL(CSecurityPiece *aPiece_data); + void NextTag(); + TInt DoParseL(CSecurityPiece *aPiece_data, TBool aIncludeIKE); + TInt ParseGeneral(CGeneralData *aGeneralData); + + static TInt WriteVersion(HBufC8*& aPolBfr); + static TInt WriteInfo(CSecurityPiece *aPiece_data, HBufC8*& aPolBfr); + static TInt WriteIke(CSecurityPiece *aPiece_data, HBufC8*& aPolBfr); + +private: + TInt iVersion; //File version +}; + +class TGeneralParser : public TLex +{ +public: + IMPORT_C TGeneralParser(const TDesC &aStr); + IMPORT_C TInt Parse(CGeneralData *aData); +}; + +class IkeParser +{ + public: + IMPORT_C static RArray* GetApplUidListL(const TDesC16& aApplUidString); + IMPORT_C static HBufC8* TextToHexOctetsL(const TDesC16& aTextString); + IMPORT_C static TBool TextToHexOctets(const TDesC16& aTextString, TDes8& aHexOctets); + + private: + void static NextHexaDigit(TLex& aUidString); + TBool static DeHex(const TUint16* aUcStr, TInt aStrLen, TUint8* aDstBfr); + TBool static HexVal(TUint8& c); +}; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikepolparser/rom/ikepolparser.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikepolparser/rom/ikepolparser.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Image description file for project ikepolparser +* +*/ + + + + +#ifndef __IKEPOLPARSER_IBY__ +#define __IKEPOLPARSER_IBY__ + +#ifdef SYMBIAN_EXCLUDE_IPSEC + +REM Feature IKEPOLPARSER not included in this rom + +#else + +file=ABI_DIR\BUILD_DIR\ikepolparser.dll SHARED_LIB_DIR\ikepolparser.dll + +#endif // SYMBIAN_EXCLUDE_IPSEC + +#endif // __IKEPOLPARSER_IBY__ diff -r 000000000000 -r 33413c0669b9 vpnengine/ikepolparser/src/ikepolparser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikepolparser/src/ikepolparser.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,2499 @@ +/* +* Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE policy parser main module +* +*/ + + + +#include +#include +#include "ikepolparser.h" + +// +// EXPORTed functions +// + +//--------------------------------------------------------------------------- +// +// IKE Policy Parsing +// +//--------------------------------------------------------------------------- + +// +//CIkeData -> contains the ike data +// +CIkeData::CIkeData() : iIkeVersion(1) + { + } + +EXPORT_C CIkeData* CIkeData::NewL() + { + return new (ELeave) CIkeData(); + } + +EXPORT_C CIkeData* CIkeData::NewL(const CIkeData *aData) + { + CIkeData* self = new (ELeave) CIkeData(); + CleanupStack::PushL(self); + self->ConstructL(aData); + CleanupStack::Pop(self); + return self; + } + +EXPORT_C void CIkeData::ConstructL(const CIkeData *aData) + { + CopyL(aData); + } + +EXPORT_C CIkeData::~CIkeData() + { + delete iRemoteIdentity; + delete iEAPRealmPrefix; + delete iEAPManualRealm; + delete iEAPManualUserName; + delete iCRACKLAMUserName; + delete iCRACKLAMPassword; + delete iClientCertType; + delete iFQDNAddr; + Empty(); + } + +EXPORT_C void CIkeData::CopyL(const CIkeData* aData) + { + if ( aData == NULL ) + { + User::Leave( KErrNoMemory ); + } + + Empty(); //Free the previous info + iAddr = aData->iAddr; //Peer host address + iMask = aData->iMask; //Peer host mask + if (aData->iFQDNAddr) + iFQDNAddr=TStringData::NewL(aData->iFQDNAddr->GetData()); + iMode = aData->iMode; + iNotify = aData->iNotify; + iFQDN.Copy(aData->iFQDN); + iIdType = aData->iIdType; + iGroupDesc_II = aData->iGroupDesc_II; + iAcceptPartialRemoteId = aData->iAcceptPartialRemoteId; + iIkeVersion = aData->iIkeVersion; + iCommit = aData->iCommit; + iIpsecExpires = aData->iIpsecExpires; + iAlwaysSendCert = aData->iAlwaysSendCert; + iInitialContact = aData->iInitialContact; //INITIAL-CONTACT sending + iResponderLifetime = aData->iResponderLifetime; //RESPONDER_LIFETIME sending + iReplayStatus = aData->iReplayStatus; //RESPONDER_LIFETIME sending + iCRACKLAMType = aData->iCRACKLAMType; //CRACK LAM type + if (aData->iCRACKLAMUserName) + iCRACKLAMUserName=TStringData::NewL(aData->iCRACKLAMUserName->GetData()); + if (aData->iCRACKLAMPassword) + iCRACKLAMPassword=TStringData::NewL(aData->iCRACKLAMPassword->GetData()); + iUseInternalAddr = aData->iUseInternalAddr; + iUseNatProbing = aData->iUseNatProbing; + iEspUdpPort = aData->iEspUdpPort; + iNatKeepAlive = aData->iNatKeepAlive; + iDscp = aData->iDscp; + iDPDHeartBeat = aData->iDPDHeartBeat; + iRekeyingThreshold = aData->iRekeyingThreshold; + iUseXauth = aData->iUseXauth; + iUseCfgMode = aData->iUseCfgMode; + iUseMobIke = aData->iUseMobIke; + + iRemoteIdType = aData->iRemoteIdType; + iSkipRemoteIdCheck = aData->iSkipRemoteIdCheck; + if ( aData->iRemoteIdentity ) + iRemoteIdentity = TStringData::NewL(aData->iRemoteIdentity->GetData()); + iEAPProtocol = aData->iEAPProtocol; + iEAPHideIdentity = aData->iEAPHideIdentity; + if ( aData->iEAPRealmPrefix ) + iEAPRealmPrefix = TStringData::NewL( + aData->iEAPRealmPrefix->GetData()); + if ( aData->iEAPManualRealm ) + iEAPManualRealm = TStringData::NewL( + aData->iEAPManualRealm->GetData()); + if ( aData->iEAPManualUserName ) + iEAPManualUserName = TStringData::NewL( + aData->iEAPManualUserName->GetData()); + if (aData->iClientCertType) + iClientCertType = TStringData::NewL(aData->iClientCertType->GetData()); + + iNumProp = aData->iNumProp; + TProposalData* prop = NULL; + TProposalData* prev = NULL; + TProposalData* tmp_prop = aData->iPropList; + for (TInt i=0; i < iNumProp; i++) + { + prop = new (ELeave) TProposalData; + *prop = *tmp_prop; + if (prev) + prev->iNext = prop; + else //first + iPropList = prop; + + prop->iPrev = prev; + prev = prop; + tmp_prop = tmp_prop->iNext; + } + if (prop) + prop->iNext = NULL; + + iPresharedKey = aData->iPresharedKey; + iCA = aData->iCA; + iOwnCert = aData->iOwnCert; + iPrivKey = aData->iPrivKey; + iPeerCert = aData->iPeerCert; + + if ( aData->iCAList ) + { + TInt count( aData->iCAList->Count() ); + iCAList = new (ELeave) CArrayFixFlat(count); + + for ( TInt x(0); x < count; x++ ) + { + TCertInfo* ca_copy = new (ELeave) TCertInfo; + CleanupStack::PushL(ca_copy); + *ca_copy = *(aData->iCAList->At(x)); + iCAList->AppendL(ca_copy); + CleanupStack::Pop(ca_copy); + } + } + } + +void CIkeData::Empty() + { + TProposalData* prop = iPropList; + TProposalData* next_prop; + while (prop) + { + next_prop = prop->iNext; + delete prop; + prop = next_prop; + } + if ( iCAList ) + { + for (TInt i(0); iCount(); ++i) + { + delete iCAList->At(i); + iCAList->At(i) = NULL; + } + iCAList->Reset(); + delete iCAList; + iCAList = NULL; + } + } + + +// +// CIkeDataArray +// +CIkeDataArray::CIkeDataArray(TInt aGranularity) + :CArrayFixFlat(aGranularity) + { + } + +EXPORT_C CIkeDataArray* CIkeDataArray::NewL(TInt aGranularity) + { + ASSERT(aGranularity); + return new (ELeave) CIkeDataArray(aGranularity); + } + +CIkeDataArray::CIkeDataArray(CIkeDataArray* aData) + :CArrayFixFlat(aData ? aData->Count() : 0) + { + } + +EXPORT_C CIkeDataArray* CIkeDataArray::NewL(CIkeDataArray* aData) + { + User::LeaveIfNull(aData); + ASSERT(aData->Count()); + CIkeDataArray* self = new (ELeave) CIkeDataArray(aData); + CleanupStack::PushL(self); + self->ConstructL(aData); + CleanupStack::Pop(self); + return self; + } + +EXPORT_C void CIkeDataArray::ConstructL(CIkeDataArray *aData) + { + CopyL(aData); + } + +EXPORT_C CIkeDataArray::~CIkeDataArray() + { + Empty(); + } + +//Constructs this from the data in aData +EXPORT_C void CIkeDataArray::CopyL(CIkeDataArray* aData) + { + User::LeaveIfNull(aData); + CIkeData* ike_data(NULL); + for (TInt i(0); i < aData->Count(); i++) + { + ike_data = CIkeData::NewL(aData->At(i)); + AppendL(ike_data); + } + iMaxLifetimeKB = aData->iMaxLifetimeKB; + iMaxLifetimeSec = aData->iMaxLifetimeSec; + iMaxRetrans = aData->iMaxRetrans; + iMaxTraceFileSize = aData->iMaxTraceFileSize; + } + +EXPORT_C void CIkeDataArray::Empty() + { + for (TInt i(0); i < Count(); i++) + { + delete At(i); + } + Reset(); + } + + + +// +//TIKEParser -> parses the ike data from a descriptor or writes it to a file +// +// Symbian change - start +#ifdef __VC32__ +#pragma warning(disable : 4097) // typedef-name used as synonym for class-name +#endif +// Symbian change - end +EXPORT_C TIkeParser::TIkeParser() : TLex(), iVersion(0) +{ + +} + +EXPORT_C TIkeParser::TIkeParser(const TDesC &aStr, TInt aVersion) : TLex(aStr), iVersion(aVersion) +{ + +} + +//Parses the Main ike file +EXPORT_C void TIkeParser::MainParseL(CIkeDataArray *aIkeList) +{ + TPtrC ikeHostSeparator = IKE_HOST_SEPARATOR; + DoMainParseL(aIkeList, ikeHostSeparator); +} + +EXPORT_C void TIkeParser::ParseIKESectionsL(CIkeDataArray *aIkeList) +{ + TPtrC ikeSeparator = IKE_SEPARATOR; + DoMainParseL(aIkeList, ikeSeparator); +} + +void TIkeParser::DoMainParseL(CIkeDataArray* aIkeList, TPtrC& aSectionName) +{ + ASSERT( aIkeList ); + + TPtrC token(NULL,0); + + while (!Eos()) + { + token.Set(NextToken()); + if (token.Compare(aSectionName)==0) + { + CIkeData* ike_piece = CIkeData::NewL(); + CleanupStack::PushL(ike_piece); + ParseIkePieceL(ike_piece, SEC_PARSER_VERSION, //Always the latest because is generated by the program itself + aSectionName); + aIkeList->AppendL(ike_piece); + CleanupStack::Pop(ike_piece); + } + else if (token.Compare(IKE_GENERAL_SEPARATOR)==0) + { + //Always the latest because is generated by the program itself + User::LeaveIfError(ParseGeneralData(aIkeList)); + } + } +} + + +//Only 2 sections of general data (max lifetimes) +TInt TIkeParser::ParseGeneralData(CIkeDataArray* aIkeList) +{ + ASSERT(aIkeList); + + TLex sub_num; //Used for number conversion + TInt err = KErrNone; + TPtrC token(NULL,0); + while (!Eos() && err==KErrNone) + { + Mark(); + token.Set(NextToken()); + if (token.CompareF(_L("ISAKMP_SA_MAX_LIFETIME_SEC:")) == 0) //CompareF ignores case + { + sub_num = NextToken(); + if (sub_num.Val(aIkeList->iMaxLifetimeSec,EDecimal)!=KErrNone) + err = KSecParserErrMaxLifetimeSec; + } + else if (token.CompareF(_L("ISAKMP_SA_MAX_LIFETIME_KB:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if (sub_num.Val(aIkeList->iMaxLifetimeKB,EDecimal)!=KErrNone) + err = KSecParserErrMaxLifetimeKB; + } + else if (token.CompareF(_L("ISAKMP_MAX_RETRANS:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if (sub_num.Val(aIkeList->iMaxRetrans)!=KErrNone) + err = KSecParserErrMaxRetrans; + } + else if (token.CompareF(_L("TRACE_FILE_SIZE:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if (sub_num.Val(aIkeList->iMaxTraceFileSize)!=KErrNone) + err = KSecParserErrMaxRetrans; + } + + else if (token.Compare(IKE_HOST_SEPARATOR)==0) //END of general section + { + UnGetToMark(); //Ungets the token + return KErrNone; + } + else if (token.Compare(IKE_GENERAL_SEPARATOR)==0)//END of general section + { + UnGetToMark(); //Ungets the token + return KErrNone; + } + else if (token.Compare(IKE_SEPARATOR)==0)//END of general section + { + UnGetToMark(); //Ungets the token + return KErrNone; + } + //others ignored + } + + return err; +} + +void TIkeParser::ParseIkePieceL(CIkeData* aIkeData, TInt aVersion, TPtrC& aSectionName) +{ + TInt pos = Remainder().Find(aSectionName); + if (pos != KErrNotFound) + { + TPtr ike_ptr((TUint16*)Remainder().Ptr(),pos, pos); //Until the next section + + TIkeParser parser(ike_ptr, aVersion); + parser.ParseL(aIkeData); + Assign(Remainder().Mid(pos)); //rest of the text to parse + } + else //No more tags + { + TIkeParser parser(Remainder(), aVersion); + parser.ParseL(aIkeData); + Assign(Remainder().Mid(Remainder().Length())); + } +} + +EXPORT_C void TIkeParser::ParseL(CIkeData* aConf) +{ + ASSERT(aConf); + + TInt err = KErrNone; + TInt errCA= KErrNone; + TPtrC token(NULL,0); + TLex sub_num; //Used for number conversion + + while (!Eos() && err==KErrNone) + { + //General Data + token.Set(NextToken()); + if (token.CompareF(_L("ADDR:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + + err = aConf->iAddr.Input(token); + if (err != KErrNone) + { + err = KSecParserErrPeerAddr; + aConf->iFQDNAddr = TStringData::NewL(token); + } + if (iVersion >= 2) //Incorporated in version 2 + { + token.Set(NextToken()); + err = aConf->iMask.Input(token); + if (err != KErrNone) + err = KSecParserErrPeerMask; + } + } + else if (token.CompareF(_L("DNS_SERVER:"))==0) + { + token.Set(NextToken()); + + err = aConf->iDnsServer.Input(token); + if (err != KErrNone) + { + err = KSecParserErrUnknown; + } + } + else if (token.CompareF(_L("MODE:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("Main"))==0) + aConf->iMode = IKE_PARSER_MAIN; + else if (token.CompareF(_L("Aggressive"))==0) + aConf->iMode = IKE_PARSER_AGGRESSIVE; + else + err = KSecParserErrMode; + } + else if (token.CompareF(_L("IKE_VERSION:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + sub_num.Val(aConf->iIkeVersion, EDecimal); + if ( aConf->iIkeVersion != 2 ) + aConf->iIkeVersion = 1; // IKE version 1 is currently the default + } + else if (token.CompareF(_L("SEND_NOTIFICATION:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iNotify = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iNotify = EFalse; + else + err = KSecParserErrNotify; + } + else if (token.CompareF(_L("FQDN:"))==0) //CompareF ignores case + { + token.Set(GetRestOfLine()); + aConf->iFQDN.Copy(token); + } + else if (token.CompareF(_L("ID_TYPE:"))==0) //CompareF ignores case + { + // Specifies IKE Phase 1 Identity type. Integer value specified in rfc2407 + sub_num = NextToken(); + if ( sub_num.Val(aConf->iIdType, EDecimal)!= KErrNone ) + aConf->iIdType = 0; // In error situation, set id value to reserved (= Not defined) + } + else if (token.CompareF(_L("REMOTE_ID_TYPE:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if ( sub_num.Val(aConf->iRemoteIdType, EDecimal)!= KErrNone ) + aConf->iRemoteIdType = 0; // In error situation, set id value to reserved (= Not defined) + } + else if (token.CompareF(_L("REMOTE_IDENTITY:"))==0) //CompareF ignores case + { + token.Set(GetRestOfLine()); + aConf->iRemoteIdentity = TStringData::NewL(token); + } + else if (token.CompareF(_L("ACCEPT_PARTIAL_REMOTE_ID:"))==0) //CompareF ignores case + { + aConf->iAcceptPartialRemoteId = EFalse; + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iAcceptPartialRemoteId = ETrue; + } + else if (token.CompareF(_L("SKIP_REMOTE_ID_CHECK:"))==0) //CompareF ignores case + { + aConf->iSkipRemoteIdCheck = EFalse; + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iSkipRemoteIdCheck = ETrue; + } + else if (token.CompareF(_L("GROUP_DESCRIPTION_II:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("MODP_768"))==0) + aConf->iGroupDesc_II = IKE_PARSER_MODP_768; + else if (token.CompareF(_L("MODP_1024"))==0) + aConf->iGroupDesc_II = IKE_PARSER_MODP_1024; + else if (token.CompareF(_L("MODP_1536"))==0) + aConf->iGroupDesc_II = IKE_PARSER_MODP_1536; + else if (token.CompareF(_L("MODP_2048"))==0) + aConf->iGroupDesc_II = IKE_PARSER_MODP_2048; + else + { + err = KSecParserErrGroupDesc_II; + } + } + else if (token.CompareF(_L("USE_COMMIT:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iCommit = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iCommit = EFalse; + else + err = KSecParserErrCommit; + } + else if (token.CompareF(_L("IPSEC_EXPIRE:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iIpsecExpires = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iIpsecExpires = EFalse; + else + err = KSecParserErrIpsecExpire; + } + else if (token.CompareF(_L("SEND_CERT:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iAlwaysSendCert = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iAlwaysSendCert = EFalse; + else + err = KSecParserErrSendCert; + } + else if (token.CompareF(_L("INITIAL_CONTACT:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iInitialContact = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iInitialContact = EFalse; + else + err = KSecParserErrInitialContact; + } + else if (token.CompareF(_L("RESPONDER_LIFETIME:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iResponderLifetime = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iResponderLifetime = EFalse; + else + err = KSecParserErrResponderLifetime; + } + else if (token.CompareF(_L("REPLAY_STATUS:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iReplayStatus = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iReplayStatus = EFalse; + else + err = KSecParserErrReplayStatus; + } + else if (token.CompareF(_L("CRACK_LAM_TYPE:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + + //There is no difference between SECUREID nowadays. So both values are + //mapped to IKE_PARSER_CRACK_PASSWORD + if (token.CompareF(_L("PASSWORD"))==0 || token.CompareF(_L("SECURID"))==0) + aConf->iCRACKLAMType = IKE_PARSER_CRACK_PASSWORD; + else + { + err = KSecParserErrCRACKLAMType; + } + } + else if (token.CompareF(_L("CRACK_LAM_USERNAME:"))==0) //CompareF ignores case + { + token.Set(GetRestOfLine()); + aConf->iCRACKLAMUserName = TStringData::NewL(token); + } + else if (token.CompareF(_L("CRACK_LAM_PASSWORD:"))==0) //CompareF ignores case + { + token.Set(GetRestOfLine()); + aConf->iCRACKLAMPassword = TStringData::NewL(token); + } + else if (token.CompareF(_L("OWN_CERT_TYPE:"))==0) //CompareF ignores case + { + token.Set(GetRestOfLine()); + aConf->iClientCertType = TStringData::NewL(token); + } + else if (token.CompareF(_L("USE_INTERNAL_ADDR:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iUseInternalAddr = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iUseInternalAddr = EFalse; + else + err = KSecParserErrUseIntAddr; + } + else if (token.CompareF(_L("USE_NAT_PROBE:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iUseNatProbing = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iUseNatProbing = EFalse; + else + err = KSecParserErrUseNATProbe; + } + else if (token.CompareF(_L("ESP_UDP_PORT:"))==0) //CompareF ignores case + { + // Specifies port value for IPSEC ESP encapsulation + sub_num = NextToken(); + if ( sub_num.Val(aConf->iEspUdpPort) != KErrNone ) + aConf->iEspUdpPort = 0; // In error situation, set id value to reserved (= Not defined) + } + else if (token.CompareF(_L("NAT_KEEPALIVE:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if ( sub_num.Val(aConf->iNatKeepAlive) != KErrNone ) + aConf->iNatKeepAlive = 0; // In error situation, set id value to reserved (= Not defined) + } + else if (token.CompareF(_L("DSCP_VALUE:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if ( sub_num.Val(aConf->iDscp, EDecimal) != KErrNone ) + aConf->iDscp = 0; // In error situation, set id value to reserved (= Not defined) + aConf->iDscp <<= 2; + } + else if (token.CompareF(_L("DPD_HEARTBEAT:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if ( sub_num.Val(aConf->iDPDHeartBeat) != KErrNone ) + aConf->iDPDHeartBeat = 0; // In error situation, set id value to reserved (= Not defined) + } + else if (token.CompareF(_L("REKEYING_THRESHOLD:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if ( sub_num.Val(aConf->iRekeyingThreshold) != KErrNone ) + aConf->iRekeyingThreshold = 0; // In error situation, set id value to reserved (= Not defined) + } + else if (token.CompareF(_L("USE_XAUTH:"))==0) //CompareF ignores case + { + aConf->iUseXauth = EFalse; + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iUseXauth = ETrue; + } + else if (token.CompareF(_L("USE_MODE_CFG:"))==0) //CompareF ignores case + { + aConf->iUseCfgMode = EFalse; + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iUseCfgMode = ETrue; + } + else if (token.CompareF(_L("USE_MOBIKE:"))==0) //CompareF ignores case + { + aConf->iUseMobIke = EFalse; + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iUseMobIke = ETrue; + } + else if (token.CompareF(_L("EAP_PROTOCOL:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if ( sub_num.Val(aConf->iEAPProtocol, EDecimal)!= KErrNone ) + aConf->iEAPProtocol = 0; // In error situation, set id value to reserved (= Not defined) + } + else if (token.CompareF(_L("EAP_REALM_PREFIX:"))==0) //CompareF ignores case + { + token.Set(GetRestOfLine()); + aConf->iEAPRealmPrefix = TStringData::NewL(token); + } + else if (token.CompareF(_L("EAP_MANUAL_REALM:"))==0) //CompareF ignores case + { + token.Set(GetRestOfLine()); + aConf->iEAPManualRealm = TStringData::NewL(token); + } + else if (token.CompareF(_L("EAP_MANUAL_USERNAME:"))==0) //CompareF ignores case + { + token.Set(GetRestOfLine()); + aConf->iEAPManualUserName = TStringData::NewL(token); + } + else if (token.CompareF(_L("EAP_HIDE_IDENTITY:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iEAPHideIdentity = ETrue; + else aConf->iEAPHideIdentity = EFalse; + } + + else if (token.CompareF(_L("PROPOSALS:"))==0) //CompareF ignores case + err = ParseProposals(aConf); + //Preshared Keys List + else if (token.CompareF(_L("PRESHARED_KEYS:"))==0) //CompareF ignores case + err = ParsePresharedKeys(aConf); + //CAs Data + else if (token.CompareF(_L("CAs:"))==0) //CompareF ignores case + { + err = ParseCAs(aConf); + if (!err) + aConf->iCAFound=ETrue; + } //Own Certs List + else if (token.CompareF(_L("OWN_CERTS:"))==0) //CompareF ignores case + err = ParseOwnCerts(aConf); + //PeerCerts List + else if (token.CompareF(_L("PEER_CERTS:"))==0) //CompareF ignores case + err = ParsePeerCerts(aConf); + } + if ( err == KErrNone ) + errCA=CheckPolicy(aConf); + if (errCA) + err=errCA; + User::LeaveIfError(err); +} + +TInt TIkeParser::CheckPolicy(CIkeData* aConf) +{ + TInt errno=KErrNone; + if (aConf->iCARequired && !aConf->iCAFound) + errno=KSecParserErrCA; + return errno; +} + +EXPORT_C TInt TIkeParser::BufferAppend(HBufC8*& aPolBfr, const TDesC8& aText) +{ + TInt err = KErrNone; + // Make sure that we have enough space for the new text + + TInt spaceLeft = aPolBfr->Des().MaxLength() - aPolBfr->Des().Length(); + if (aText.Length() > spaceLeft) + { + // Allocate enough space for the new text + some additional + // free space so that allocations are not too frequent + + TInt newMaxLength = aPolBfr->Des().MaxLength() + + aText.Length() + KIkePolicyBufferSizeIncrement; + HBufC8* tempBfr = aPolBfr->ReAlloc(newMaxLength); + if (tempBfr) + { + aPolBfr = tempBfr; + } + else + { + return KErrNoMemory; + } + } + aPolBfr->Des().Append(aText); + return err; +} + + +//Writes one Host Info. +EXPORT_C TInt TIkeParser::MainWrite(CIkeData *aConf, HBufC8*& aPolBfr) +{ + + TBuf8 buf; + buf.Copy(IKE_HOST_SEPARATOR); + TInt err = BufferAppend(aPolBfr, buf); + + if (err != KErrNone) + return err; + err = BufferAppend(aPolBfr, (_L8("\n"))); + if (err != KErrNone) + return err; + return Write(aConf, aPolBfr); +} + +//Writes some IKE General Data. ("Old Version" no trace file size) +EXPORT_C TInt TIkeParser::GeneralInfoWrite(TUint32 aMaxLifetimeSec, + TUint32 aMaxLifetimeKB, TInt aMaxRetrans, HBufC8*& aPolBfr) +{ + return GeneralInfoWrite(aMaxLifetimeSec, aMaxLifetimeKB, + aMaxRetrans, 0, aPolBfr); +} + +//Writes some IKE General Data. ("New Version") +EXPORT_C TInt TIkeParser::GeneralInfoWrite(TUint32 aMaxLifetimeSec, + TUint32 aMaxLifetimeKB, TInt aMaxRetrans, + TInt aMaxTraceFileSize, HBufC8*& aPolBfr) +{ + TBuf8<40> line; + + TBuf8 buf; + buf.Copy(IKE_GENERAL_SEPARATOR); + TInt err = BufferAppend(aPolBfr, buf); + + if (err != KErrNone) + return err; + err = BufferAppend(aPolBfr, (_L8("\n"))); + if (err != KErrNone) + return err; + + line.Format(_L8("ISAKMP_SA_MAX_LIFETIME_SEC: %u\n"),aMaxLifetimeSec); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Format(_L8("ISAKMP_SA_MAX_LIFETIME_KB: %u\n"),aMaxLifetimeKB); + err = BufferAppend(aPolBfr, line); + + line.Format(_L8("ISAKMP_MAX_RETRANS: %u\n"),aMaxRetrans); + err = BufferAppend(aPolBfr, line); + + line.Format(_L8("TRACE_FILE_SIZE: %u\n"), aMaxTraceFileSize); + err = BufferAppend(aPolBfr, line); + + return err; + +} + + +EXPORT_C TInt TIkeParser::Write(CIkeData* aConf, HBufC8*& aPolBfr) +{ + ASSERT(aConf); + + TBuf8<1024> line; + TInt err = KErrNone; + TBuf<39> addr_buf; + TBuf<39> mask_buf; + + TBuf8<39> addr8; + TBuf8<39> mask8; + + line.Append(_L8("ADDR: ")); + if (!aConf->iAddr.IsUnspecified()) + aConf->iAddr.OutputWithScope(addr_buf); + else + addr_buf.Copy(_L("0.0.0.0")); + if (!aConf->iMask.IsUnspecified()) + aConf->iMask.OutputWithScope(mask_buf); + else //only happens with version 1 (no mask) + mask_buf.Copy(_L("255.255.255.255")); + + addr8.Copy(addr_buf); + line.Append(addr8); + line.Append(_L(" ")); + mask8.Copy(mask_buf); + line.Append(mask8); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + + + if (!aConf->iDnsServer.IsUnspecified()) + { + aConf->iDnsServer.OutputWithScope(addr_buf); + line = _L8("DNS_SERVER: "); + addr8.Copy(addr_buf); + line.Append(addr8); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + + } + + + + + if ( (aConf->iMode == IKE_PARSER_MAIN) || (aConf->iMode == IKE_PARSER_AGGRESSIVE) ) + { + line.Copy(_L8("MODE: ")); + line.Append(TextMode(aConf->iMode)); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + if ( aConf->iIkeVersion != 0 ) + { + line.Format(_L8("IKE_VERSION: %d\n"), aConf->iIkeVersion); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + line.Copy(_L8("SEND_NOTIFICATION: ")); + if (aConf->iNotify) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + if (aConf->iFQDN.Length() > 0) + { + line.Copy(_L8("FQDN: ")); + line.Append(aConf->iFQDN); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + if (aConf->iIdType != 0) + { + line.Format(_L8("ID_TYPE: %d\n"), aConf->iIdType); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + if ( aConf->iRemoteIdentity ) + { + line.Copy(_L8("REMOTE_IDENTITY: ")); + line.Append(aConf->iRemoteIdentity->GetData()); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + if (aConf->iRemoteIdType != 0) + { + line.Format(_L8("REMOTE_ID_TYPE: %d\n"), aConf->iRemoteIdType); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + line.Copy(_L8("ACCEPT_PARTIAL_REMOTE_ID: ")); + if (aConf->iAcceptPartialRemoteId) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("SKIP_REMOTE_ID_CHECK: ")); + if (aConf->iSkipRemoteIdCheck) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + if (aConf->iGroupDesc_II != 0) + { + line.Copy(_L8("GROUP_DESCRIPTION_II: ")); + line.Append(TextGroupDesc(aConf->iGroupDesc_II)); + line.Append(_L("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + line.Copy(_L8("USE_COMMIT: ")); + if (aConf->iCommit) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("IPSEC_EXPIRE: ")); + if (aConf->iIpsecExpires) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("SEND_CERT: ")); + if (aConf->iAlwaysSendCert) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("INITIAL_CONTACT: ")); + if (aConf->iInitialContact) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("RESPONDER_LIFETIME: ")); + if (aConf->iResponderLifetime) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("REPLAY_STATUS: ")); + if (aConf->iReplayStatus) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + if ( aConf->iCRACKLAMType == IKE_PARSER_CRACK_PASSWORD ) + { + line.Copy(_L8("CRACK_LAM_TYPE: ")); + line.Append(TextLAMType(aConf->iCRACKLAMType)); + line.Append(_L("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + //IKE Private (Nokia VPN specific) extensions + line.Copy(_L8("USE_INTERNAL_ADDR: ")); + if (aConf->iUseInternalAddr) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("USE_NAT_PROBE: ")); + if (aConf->iUseNatProbing) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + if (aConf->iEspUdpPort != 0) + { + line.Format(_L8("ESP_UDP_PORT: %d\n"), aConf->iEspUdpPort); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + line.Format(_L8("NAT_KEEPALIVE: %d\n"), aConf->iNatKeepAlive); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Format(_L8("DSCP_VALUE: %d\n"), aConf->iDscp >> 2); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Format(_L8("DPD_HEARTBEAT: %d\n"), aConf->iDPDHeartBeat); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Format(_L8("REKEYING_THRESHOLD: %d\n"), aConf->iRekeyingThreshold); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("USE_XAUTH: ")); + if (aConf->iUseXauth) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("USE_MODE_CFG: ")); + if (aConf->iUseCfgMode) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("USE_MOBIKE: ")); + if (aConf->iUseMobIke) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + if ( aConf->iCRACKLAMUserName ) + { + line.Copy(_L8("CRACK_LAM_USERNAME: ")); + line.Append(aConf->iCRACKLAMUserName->GetData()); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + if ( aConf->iCRACKLAMPassword ) + { + line.Copy(_L8("CRACK_LAM_PASSWORD: ")); + line.Append(aConf->iCRACKLAMPassword->GetData()); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + if ( aConf->iClientCertType ) + { + line.Copy(_L8("OWN_CERT_TYPE: ")); + line.Append(aConf->iClientCertType->GetData()); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + if ( aConf->iEAPProtocol != 0 ) + { + line.Format(_L8("EAP_PROTOCOL: %d\n"), aConf->iEAPProtocol); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + line.Copy(_L8("EAP_HIDE_IDENTITY: ")); + if (aConf->iEAPHideIdentity) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + if ( aConf->iEAPRealmPrefix ) + { + line.Copy(_L8("EAP_REALM_PREFIX: ")); + line.Append(aConf->iEAPRealmPrefix->GetData()); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + if ( aConf->iEAPManualRealm ) + { + line.Copy(_L8("EAP_MANUAL_REALM: ")); + line.Append(aConf->iEAPManualRealm->GetData()); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + if ( aConf->iEAPManualUserName ) + { + line.Copy(_L8("EAP_MANUAL_USERNAME: ")); + line.Append(aConf->iEAPManualUserName->GetData()); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + //Proposals + line.Format(_L8("PROPOSALS: %d\n"), aConf->iNumProp); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + TProposalData* prop = aConf->iPropList; + for (TInt i=0; iiNumProp; i++) + { + line.Copy(_L8("ENC_ALG: ")); + line.Append(TextEncrAlg(prop->iEncrAlg, prop->iEncrKeyLth)); + line.Append(_L8("\nAUTH_METHOD: ")); + line.Append(TextAuthMethod(prop->iAuthMeth)); + line.Append(_L8("\nHASH_ALG: ")); + line.Append(TextHashAlg(prop->iHashAlg)); + line.Append(_L8("\nGROUP_DESCRIPTION: ")); + line.Append(TextGroupDesc(prop->iGroupDesc)); + line.Append(_L8("\nGROUP_TYPE: ")); + line.Append(TextGroupType(prop->iGroupType)); + line.AppendFormat(_L8("\nLIFETIME_KBYTES: %d"),prop->iLifetimeKb); + line.AppendFormat(_L8("\nLIFETIME_SECONDS: %d"),prop->iLifetimeSec); + line.Append(_L8("\nPRF: ")); + line.Append(TextPRF(prop->iPRF)); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + prop = prop->iNext; + } + + if (aConf->iPresharedKey.iKey.Length() > 0) + { + line.Copy(_L8("PRESHARED_KEYS:\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + line.Copy(_L("FORMAT: ")); + line.Append(TextFormat(aConf->iPresharedKey.iFormat)); + line.AppendFormat(_L8("\nKEY: %d "),aConf->iPresharedKey.iKey.Length()); + line.Append(aConf->iPresharedKey.iKey); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + // + //CAS + //Support for multiple CAs + // + if ( aConf->iCAList ) + { + TInt ca_count = aConf->iCAList->Count(); + line.Copy(_L("CAs: ")); + line.AppendNum(ca_count); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + for (TInt i=0; i < ca_count; i++) + { + line.Copy(_L(" FORMAT: ")); + line.Append(CertFormat(aConf->iCAList->At(i)->iFormat)); + line.Append(_L("\n DATA: ")); + line.Append(aConf->iCAList->At(i)->iData); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + } + + //Own Certs + if (aConf->iOwnCert.iOwnCertExists) + { + line.Copy(_L8("OWN_CERTS:\n")); + if (aConf->iOwnCert.iData.Length() > 0) + { + line.Append(_L8(" FORMAT: ")); + line.Append(CertFormat(aConf->iOwnCert.iFormat)); + line.Append(_L8("\n DATA: ")); + line.Append(aConf->iOwnCert.iData); + line.Append(_L8("\n PRIVATE_KEY_FORMAT: ")); + line.Append(CertFormat(aConf->iPrivKey.iFormat)); + line.Append(_L8("\n PRIVATE_KEY_DATA: ")); + line.Append(aConf->iPrivKey.iData); + line.Append(_L8("\n")); + line.AppendFormat(_L8("\n PRIVATE_KEY_LENGTH: %d"), aConf->iOwnCert.iPrivateKeyLength); + } + + // Always included + line.Append(_L8("\n SUBJECT_DN_SUFFIX: ")); + line.Append(aConf->iOwnCert.iSubjectDnSuffix); + TInt identityType; + if (aConf->iOwnCert.iIdentityAsRfc822Name == EIdentityAsRfc822NameUndefined) + { + identityType = 2; + } + else if (aConf->iOwnCert.iIdentityAsRfc822Name == EIdentityAsRfc822NameNo) + { + identityType = 0; + } + else + { + identityType = 1; + } + line.AppendFormat(_L8("\n IDENTITY_AS_RFC822NAME: %d"), identityType); + + line.Append(_L8("\n RFC822NAME_FQDN: ")); + line.Append(aConf->iOwnCert.iRfc822NameFqdn); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + //Peer Certs + if (aConf->iPeerCert.iData.Length() > 0) + { + line.Format(_L8("PEER_CERTS:")); + line.Append(_L8(" FORMAT: ")); + line.Append(CertFormat(aConf->iPeerCert.iFormat)); + line.Append(_L8("\n DATA: ")); + line.Append(aConf->iPeerCert.iData); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + return KErrNone; +} + +TInt TIkeParser::ParseProposals(CIkeData* aConf) +{ + ASSERT(aConf); + + TLex sub_num = NextToken(); //Used for number conversion + if (sub_num.Val(aConf->iNumProp) != KErrNone) + return KSecParserErrProposal; + + if (aConf->iNumProp == 0) + { + aConf->iPropList = NULL; + return KErrNone; + } + + TPtrC token(NULL,0); + TProposalData* prev_prop = NULL; + TInt err = KErrNone; + TInt authMethodFound=0; + //At least one proposal! + for (TInt i=0; iiNumProp; i++) //All the proposals + { + TProposalData* prop = NULL; + prop = new TProposalData; + if (!prop) + return KErrNoMemory; + + prop->iNext = NULL; + if (i==0) //First proposal + aConf->iPropList = prop; + else + prev_prop->iNext = prop; + + prop->iPrev = prev_prop; + authMethodFound=0; + token.Set(NextToken()); + + if (token.CompareF(_L("ENC_ALG:"))==0) //CompareF ignores case + { + prop->iEncrKeyLth = 0; // = Use Default key length + token.Set(NextToken()); + if (token.CompareF(_L("DES-CBC"))==0) + prop->iEncrAlg = IKE_PARSER_DES_CBC; + else if (token.CompareF(_L("3DES-CBC"))==0) + prop->iEncrAlg = IKE_PARSER_DES3_CBC; + else if (token.CompareF(_L("AES128-CBC"))==0) + { + prop->iEncrKeyLth = 128; + prop->iEncrAlg = IKE_PARSER_AES_CBC; + } + else if (token.CompareF(_L("AES192-CBC"))==0) + { + prop->iEncrKeyLth = 192; + prop->iEncrAlg = IKE_PARSER_AES_CBC; + } + else if (token.CompareF(_L("AES256-CBC"))==0) + { + prop->iEncrKeyLth = 256; + prop->iEncrAlg = IKE_PARSER_AES_CBC; + } + else + { + err = KSecParserErrEncrAlg; + break; + } + } + else + { + err = KSecParserErrEncrAlg; + break; + } + + token.Set(NextToken()); + if (token.CompareF(_L("AUTH_METHOD:"))==0) //CompareF ignores case + { + authMethodFound=1; + token.Set(NextToken()); + if (token.CompareF(_L("RSA_SIGNATURES"))==0) + { + prop->iAuthMeth = IKE_PARSER_RSA_SIG; + aConf->iCARequired=ETrue; + } + else if (token.CompareF(_L("DSS_SIGNATURES"))==0) + { + prop->iAuthMeth = IKE_PARSER_DSS_SIG; + aConf->iCARequired=ETrue; + } + else if (token.CompareF(_L("RSA_ENCRYPT"))==0) + { + prop->iAuthMeth = IKE_PARSER_RSA_ENCR; + aConf->iCARequired=ETrue; + } + else if (token.CompareF(_L("RSA_REV_ENCRYPT"))==0) + { + prop->iAuthMeth = IKE_PARSER_RSA_REV_ENCR; + aConf->iCARequired=ETrue; + } + else if (token.CompareF(_L("PRE-SHARED"))==0) + prop->iAuthMeth = IKE_PARSER_PRE_SHARED; + else if (token.CompareF(_L("IKE-CRACK"))==0) + { + prop->iAuthMeth = IKE_PARSER_CRACK; + aConf->iCARequired=ETrue; + } + else + { + err = KSecParserErrAuthMethod; + break; + //ErrorL(R_PARSE_ERROR_AUTH_METHOD); + } + } + else + { + if (aConf->iEAPProtocol<1) + { + err = KSecParserErrAuthMethod; + break; + } + } + if (aConf->iEAPProtocol>0) + prop->iAuthMeth=IKE_PARSER_PRE_SHARED; + if (authMethodFound==1) + token.Set(NextToken()); + if (token.CompareF(_L("HASH_ALG:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("MD5"))==0) + prop->iHashAlg = IKE_PARSER_MD5; + else if (token.CompareF(_L("SHA1"))==0) + prop->iHashAlg = IKE_PARSER_SHA1; + else + { + err = KSecParserErrHashAlg; + break; + } + } + else + { + err = KSecParserErrHashAlg; + break; + } + token.Set(NextToken()); + if (token.CompareF(_L("GROUP_DESCRIPTION:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("MODP_768"))==0) + prop->iGroupDesc = IKE_PARSER_MODP_768; + else if (token.CompareF(_L("MODP_1024"))==0) + prop->iGroupDesc = IKE_PARSER_MODP_1024; + else if (token.CompareF(_L("MODP_1536"))==0) + prop->iGroupDesc = IKE_PARSER_MODP_1536; + else if (token.CompareF(_L("MODP_2048"))==0) + prop->iGroupDesc = IKE_PARSER_MODP_2048; + else + { + err = KSecParserErrGroupDesc; + break; + } + } + else + { + err = KSecParserErrGroupDesc; + break; + } + + token.Set(NextToken()); + if (token.CompareF(_L("GROUP_TYPE:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("MODP"))==0) + prop->iGroupType = IKE_PARSER_MODP; + else if(token.CompareF(_L("DEFAULT"))==0) + prop->iGroupType = IKE_PARSER_DEFAULT; + else + { + err = KSecParserErrGroupType; + break; + } + } + else + { + err = KSecParserErrGroupType; + break; + } + + token.Set(NextToken()); + if (token.CompareF(_L("LIFETIME_KBYTES:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if (sub_num.Val(prop->iLifetimeKb,EDecimal)!=KErrNone) + { + err = KSecParserErrLifeBytes; + break; + } + token.Set(NextToken()); + } + else + { + prop->iLifetimeKb=0; + } + if (token.CompareF(_L("LIFETIME_SECONDS:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if (sub_num.Val(prop->iLifetimeSec,EDecimal)!=KErrNone) + { + err = KSecParserErrLifeSecs; + break; + } + } + else + { + err = KSecParserErrLifeSecs; + break; + } + + Mark(); + + token.Set(NextToken()); + + // PRF is an optional parameter, so if it doesn't exist, just use + // the default value and unget to mark (so that the rest of the parsing + // won't fail). + if (token.CompareF(_L("PRF:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("3DES-CBC-MAC"))==0) + prop->iPRF = IKE_PARSER_DES3_CBC_MAC; + else if (token.CompareF(_L("NONE"))==0) + prop->iPRF = IKE_PARSER_NONE; + else + { + err = KSecParserErrPRF; + break; + } + } + else + { + prop->iPRF = IKE_PARSER_NONE; + UnGetToMark(); + } + + prev_prop = prop; //Save as previous proposal + } //Proposals loop + + return err; +} + + +TInt TIkeParser::ParsePresharedKeys(CIkeData* aConf) +{ + ASSERT(aConf); + + TPtrC token(NULL, 0); + TLex sub_num; //Used for number conversion + TInt j = 0; + TInt num=0; + + TPresharedKeyData *key = &aConf->iPresharedKey; + token.Set(NextToken()); + + if (token.CompareF(_L("FORMAT:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("HEX_FORMAT"))==0) + key->iFormat = HEX_KEY; + else if (token.CompareF(_L("STRING_FORMAT"))==0) + key->iFormat = STRING_KEY; + else + return KSecParserErrPreFormat; + } + else + return KSecParserErrPreKey; + + token.Set(NextToken()); + if (token.CompareF(_L("KEY:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if (sub_num.Val(num)!=KErrNone) + return KSecParserErrPreKey; + + if (num > KMaxPresharedKeyLength) + { + //Key is too long for our buffer. + return KSecParserErrPreKey; + } + + if (key->iFormat == HEX_KEY && (num % 2) != 0) + { + //HEX encoded keys must contains even number of characters. + //(Because each byte is expressed by two characters.) + return KSecParserErrPreKey; + } + } + else + return KSecParserErrPreKey; + + SkipSpaceAndMark(); + + if (key->iFormat == STRING_KEY) + { + for (j = 0; j < num && (!Eos()) ; j++) //Parse the key char to char because it contains blanks + key->iKey.Append(Get()); + } + else if (key->iFormat == HEX_KEY) + { + //Make sure that key contains a valid hex decim number. + for (j = 0; j < num && (!Eos()) ; j++) + { + TChar c = Get(); + if (c >= TChar('0') && c <= TChar('9') || + c >= TChar('a') && c <= TChar('f') || + c >= TChar('A') && c <= TChar('F')) + { + key->iKey.Append(c); + } + else + { + return KSecParserErrPreKey; + } + + } + } + + if (jiFormat = PEM_CERT; + else if (aToken.CompareF(_L("BIN"))==0) + aCA->iFormat = BIN_CERT; + else if (aToken.CompareF(_L("NAME"))==0) + aCA->iFormat = CA_NAME; + else if (aToken.CompareF(_L("KEYID"))==0) + aCA->iFormat = KEY_ID; + else if (aToken.CompareF(_L("APPLUID"))==0) + aCA->iFormat = APPL_UID; + else + return KSecParserErrCA; + } + else + { + return KSecParserErrCA; + } + + aToken.Set(NextToken()); + if ( aToken.CompareF(_L("DATA:")) == 0) //CompareF ignores case + { + switch(aCA->iFormat) + { + case CA_NAME: //falls through + case APPL_UID: + { + aCA->iData = GetRestOfLine(); //ASCII format CA name or Appl uid list + // Check if data contains empty attributes + if( KErrNotFound != aCA->iData.FindF(_L("=,")) || KErrNotFound != aCA->iData.FindF(_L("=\"\""))) + { + return KSecParserErrCA; + } + } + break; + case BIN_CERT: + return ParseFileName(aCA->iData); + //No break needed + default: + aCA->iData = NextToken(); //PEM cert or Key identifier + break; + } + + return KErrNone; + } + else + { + return KSecParserErrCA; + } +} + +void TIkeParser::ParseCAListL(CIkeData* aConf, TInt aCACount, TPtrC& aToken) +{ + ASSERT(aConf); + + aConf->iCAList = new (ELeave) CArrayFixFlat(aCACount); + + while ( aCACount ) + { + TCertInfo* ca_name = new (ELeave) TCertInfo; + CleanupStack::PushL(ca_name); + User::LeaveIfError(ParseCAItem(aConf, ca_name, aToken)); + aConf->iCAList->AppendL(ca_name); + CleanupStack::Pop(ca_name); + + aCACount--; + if ( aCACount ) + aToken.Set(NextToken()); // Enter to next "FORMAT" tag + } +} + +/**--------------------------------------------------------------- + * + * Parse CAs section in host (=IKE) configuration. + * There is two possibilities: + * CAs: + * FORMAT: BIN + * DATA: jps-SecurID-1_0-ca.cer + * This supports only one CA (This format may be removed later) + * CAs: 2 + * FORMAT: BIN + * DATA: jps-SecurID-1_0-ca.cer + * FORMAT: BIN + * DATA: jps-SecurID-1_1-ca.cer + * This supports several CA:s. Exact CA count is in line CAs: x + * + *----------------------------------------------------------------*/ +TInt TIkeParser::ParseCAs(CIkeData* aConf) +{ + TInt ca_count = 0; + TPtrC token(NULL, 0); + token.Set(NextToken()); + + if ( token.CompareF(_L("FORMAT:")) == 0 ) //CompareF ignores case + { + ca_count = 1; + } + else + { + TLex sub_num = token; + if ( (sub_num.Val(ca_count) != KErrNone) || (ca_count == 0) ) + { + return KSecParserErrCA; + } + token.Set(NextToken()); // Enter to the first "FORMAT" tag + } + + TInt err = KErrNone; + TRAP(err, ParseCAListL(aConf, ca_count, token);) + return err; +} + +TInt TIkeParser::ParseOwnCerts(CIkeData* aConf) +{ + ASSERT(aConf); + + TPtrC token(NULL,0); + + TInt nMandatoryFields=0; + TInt err=KErrNone; + TBool endOfSection=EFalse; + TOwnCertInfo *own_cert = &aConf->iOwnCert; + own_cert->iOwnCertExists = 0; + TCertInfo *priv_key = &aConf->iPrivKey; + + while (!endOfSection && err==KErrNone) + { + Mark(); + token.Set(NextToken()); + + if (token.CompareF(_L("FORMAT:"))==0) //CompareF ignores case + { + nMandatoryFields++; + token.Set(NextToken()); + if (token.CompareF(_L("BIN"))==0) + own_cert->iFormat = BIN_CERT; + else if (token.CompareF(_L("NAME"))==0) + own_cert->iFormat = CA_NAME; + else + err=KSecParserErrOwnCerts; + } + + else if (token.CompareF(_L("DATA:"))==0) //CompareF ignores case + { + nMandatoryFields++; + err = ParseFileName(own_cert->iData); + } + + //Private key part + else if (token.CompareF(_L("PRIVATE_KEY_FORMAT:"))==0) //CompareF ignores case + { + nMandatoryFields++; + token.Set(NextToken()); + if (token.CompareF(_L("PEM"))==0) + priv_key->iFormat = PEM_CERT; + else if (token.CompareF(_L("BIN"))==0) + priv_key->iFormat = BIN_CERT; + else + err=KSecParserErrOwnCerts; + } + + else if (token.CompareF(_L("PRIVATE_KEY_DATA:"))==0) //CompareF ignores case + { + nMandatoryFields++; + err = ParseFileName(priv_key->iData); + } + // new stuff // error codes? + else if (token.CompareF(_L("SUBJECT_DN_SUFFIX:"))==0) //CompareF ignores case + { + nMandatoryFields++; + own_cert->iSubjectDnSuffix = GetRestOfLine(); + // Check if data contains empty attributes + if( KErrNotFound != own_cert->iSubjectDnSuffix.FindF(_L("=,")) || + KErrNotFound != own_cert->iSubjectDnSuffix.FindF(_L("=\"\""))) + { + return KSecParserErrOwnCerts; + } + } + + else if (token.CompareF(_L("IDENTITY_AS_RFC822NAME:"))==0) //CompareF ignores case + { + nMandatoryFields++; + token.Set(NextToken()); + if (token.CompareF(_L("1"))==0) + own_cert->iIdentityAsRfc822Name=EIdentityAsRfc822NameYes; + else if (token.CompareF(_L("0"))==0) + own_cert->iIdentityAsRfc822Name=EIdentityAsRfc822NameNo; + else + own_cert->iIdentityAsRfc822Name=EIdentityAsRfc822NameUndefined; + } + else if (token.CompareF(_L("RFC822NAME_FQDN:"))==0) //CompareF ignores case + { + nMandatoryFields++; + own_cert->iRfc822NameFqdn = NextToken(); + } + + else if (token.CompareF(_L("PRIVATE_KEY_LENGTH:"))==0) //CompareF ignores case + { + nMandatoryFields++; + TLex sub_num = NextToken(); + if (sub_num.Val(own_cert->iPrivateKeyLength)!=KErrNone) + err= KSecParserErrOwnCerts; + } + else + { + UnGetToMark(); // current token didn't belong to this section + endOfSection=ETrue; + } + } + if (nMandatoryFields<1) // Some mandatory fields are missing + { + err= KSecParserErrOwnCerts; + } + else + { + own_cert->iOwnCertExists = 1; // Write Own Certs + } + return err; +} + + +TInt TIkeParser::ParsePeerCerts(CIkeData* aConf) +{ + ASSERT(aConf); + + TPtrC token(NULL, 0); + + TCertInfo *peer_cert = &aConf->iPeerCert; + token.Set(NextToken()); + if (token.CompareF(_L("FORMAT:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("PEM"))==0) + peer_cert->iFormat = PEM_CERT; + else if (token.CompareF(_L("BIN"))==0) + peer_cert->iFormat = BIN_CERT; + else + return KSecParserErrPreFormat; + } + else + return KSecParserErrPreKey; + + token.Set(NextToken()); + if (token.CompareF(_L("DATA:"))==0) //CompareF ignores case + peer_cert->iData = NextToken(); //Filename or PEM cert + else + return KSecParserErrPreKey; + + return KErrNone; +} + +TBufC<16> TIkeParser::TextMode(const TInt aMode) +{ + TBufC<16> ret; + + switch (aMode) + { + case IKE_PARSER_MAIN: + ret=_L("Main"); + break; + case IKE_PARSER_AGGRESSIVE: + ret=_L("Aggressive"); + break; + default: + break; + } + + return ret; +} + +TBufC<16> TIkeParser::TextEncrAlg(const TInt aAlg, const TInt aKeyLth) +{ + TBufC<16> ret; + + switch (aAlg) + { + case IKE_PARSER_DES_CBC: + ret=_L("DES-CBC"); + break; + case IKE_PARSER_DES3_CBC: + ret=_L("3DES-CBC"); + break; + case IKE_PARSER_AES_CBC: + if ( aKeyLth == 256 ) + ret=_L("AES256-CBC"); + else if ( aKeyLth == 192 ) + ret=_L("AES192-CBC"); + else ret=_L("AES128-CBC"); + break; + default: + break; + } + + return ret; +} + +TBufC<16> TIkeParser::TextAuthMethod(const TInt aMethod) +{ + TBufC<16> ret; + + switch (aMethod) + { + case IKE_PARSER_RSA_SIG: + ret=_L("RSA_SIGNATURES"); + break; + case IKE_PARSER_DSS_SIG: + ret=_L("DSS_SIGNATURES"); + break; + case IKE_PARSER_RSA_ENCR: + ret=_L("RSA_ENCRYPT"); + break; + case IKE_PARSER_RSA_REV_ENCR: + ret=_L("RSA_REV_ENCRYPT"); + break; + case IKE_PARSER_PRE_SHARED: + ret=_L("PRE-SHARED"); + break; + case IKE_PARSER_CRACK: + ret=_L("IKE-CRACK"); + break; + default: + break; + } + + return ret; +} + +TBufC<16> TIkeParser::TextHashAlg(const TInt aAlg) +{ + TBufC<16> ret; + + switch (aAlg) + { + case IKE_PARSER_MD5: + ret=_L("MD5"); + break; + case IKE_PARSER_SHA1: + ret=_L("SHA1"); + break; + default: + break; + } + + return ret; +} + +TBufC<16> TIkeParser::TextGroupDesc(const TInt aDesc) +{ + TBufC<16> ret; + + switch (aDesc) + { + case IKE_PARSER_MODP_768: + ret=_L("MODP_768"); + break; + case IKE_PARSER_MODP_1024: + ret=_L("MODP_1024"); + break; + case IKE_PARSER_MODP_1536: + ret=_L("MODP_1536"); + break; + case IKE_PARSER_MODP_2048: + ret=_L("MODP_2048"); + break; + default: + break; + } + return ret; +} + +TBufC<16> TIkeParser::TextGroupType(const TInt aType) +{ + TBufC<16> ret; + + switch (aType) + { + case IKE_PARSER_DEFAULT: + ret=_L("DEFAULT"); + break; + case IKE_PARSER_MODP: + ret=_L("MODP"); + break; + default: + break; + } + return ret; +} + +TBufC<16> TIkeParser::TextPRF(const TInt aPRF) +{ + TBufC<16> ret; + + switch (aPRF) + { + case IKE_PARSER_NONE: + ret=_L("NONE"); + break; + case IKE_PARSER_DES3_CBC_MAC: + ret=_L("3DES-CBC-MAC"); + break; + default: + break; + } + return ret; +} + +TBufC<16> TIkeParser::TextFormat(const TKeyFormat aFormat) +{ + TBufC<16> ret; + + switch (aFormat) + { + case HEX_KEY: + ret=_L("HEX_FORMAT"); + break; + case STRING_KEY: + default: + ret=_L("STRING_FORMAT"); + break; + } + return ret; +} + +TBufC<16> TIkeParser::CertFormat(TCertFormat aFormat) +{ + TBufC<16> ret; + + switch (aFormat) + { + case PEM_CERT: + ret=_L("PEM"); + break; + case BIN_CERT: + ret=_L("BIN"); + break; + case CA_NAME: + ret=_L("NAME"); + break; + case KEY_ID: + ret=_L("KEYID"); + break; + case APPL_UID: + ret=_L("APPLUID"); + break; + default: + break; + } + + return ret; +} + +TBufC<16> TIkeParser::TextLAMType(const TUint8 aLAMType) +{ + TBufC<16> ret; + + switch (aLAMType) + { + case IKE_PARSER_CRACK_PASSWORD: + ret=_L("PASSWORD"); + break; + default: + break; + } + + return ret; +} + + +TPtrC TIkeParser::GetRestOfLine() +{ + TChar chr=Get(); + while(chr.IsSpace() && chr!='\n' && chr!='\r') + chr=Get(); + UnGet(); + Mark(); + chr=Get(); // Fix for empty rest of line + while(!Eos() && chr!='\n' && chr!='\r') + chr=Get(); + if (!Eos()) + UnGet(); + return MarkedToken(); +} + + +TInt TIkeParser::ParseFileName(TDes& aFileName) +{ + //Get the rest of the line + //Trim trailing white spaces from the file name + TPtrC fileName = GetRestOfLine(); + HBufC* fileNameCopy = fileName.Alloc(); + if (fileNameCopy == NULL) + { + return KErrNoMemory; + } + fileNameCopy->Des().TrimRight(); + fileName.Set(fileName.Left(fileNameCopy->Length())); + delete fileNameCopy; + + aFileName = fileName; + + return KErrNone; +} + + +TBool TSecParser::CheckVersion() +{ + TPtrC token(NULL, 0); + TLex version_num; + + token.Set(NextToken()); + if (token.Compare(_L("SECURITY_FILE_VERSION:"))==0) + { + version_num = NextToken(); + if (version_num.Val(iVersion)!=KErrNone) + return EFalse; + if ((iVersion < FIRST_SEC_PARSER_VERSION) || (iVersion > SEC_PARSER_VERSION)) + return EFalse; + } + else + return EFalse; + + return ETrue; +} + +void TSecParser::ParseInfoL(CSecurityPiece* aPiece_data) +{ + ASSERT(aPiece_data); + + HBufC* buf = HBufC::NewLC(MAX_INFO_SIZE); + TPtr ptr = buf->Des(); + TChar ch = Get(); + TInt i=0; + + ch = Get(); + while (((ch==' ') || (ch=='\n')) && (!Eos())) + ch = Get(); + while ((ch!='[') && (!Eos()) && i < MAX_INFO_SIZE) + { + ptr.Append(ch); + i++; + ch = Get(); + } + + if (i == MAX_INFO_SIZE) //The rest is ignored + { + ch = Get(); + while ( (ch != '[') && (!Eos()) ) + ch = Get(); + } + + if (ch =='[') + { + UnGet(); // the '[' + if (ptr.Length() > 0) //If empty no \n + ptr.SetLength(ptr.Length() - 1); //eliminates the \n at the end + } + aPiece_data->SetInfoL(ptr); + CleanupStack::PopAndDestroy(buf); +} + +TInt TSecParser::ParseGeneral(CGeneralData *aGeneralData) +{ + TInt err; + TInt pos = Remainder().Find(_L("[")); //The segment is until the next tag or Eos() + if (pos!=KErrNotFound) + { + + TPtr gen_ptr((TUint16 *)Remainder().Ptr(),pos, pos); //Until the next section + + TGeneralParser parser(gen_ptr); + err = parser.Parse(aGeneralData); + Assign(Remainder().Mid(pos)); //rest of the text to parse + } + else //No more tags + { + TGeneralParser parser(Remainder()); + err = parser.Parse(aGeneralData); + } + + return (err); +} + + +void TSecParser::NextTag() +{ + while (!Eos()) + if (Get() == '[' ) + { + UnGet(); //Next tag found + return; + } + +} + +//Puts the security file data into string format to be saved to disk. +EXPORT_C TInt TSecParser::Write(CSecurityPiece *aPiece_data, HBufC8*& aPolBfr) +{ + TInt err; + + err = WriteVersion(aPolBfr); + if (err != KErrNone) + return err; + + err = WriteInfo(aPiece_data, aPolBfr); + if (err != KErrNone) + return err; + + return err = WriteIke(aPiece_data, aPolBfr); +} + +TInt TSecParser::WriteVersion(HBufC8*& aPolBfr) +{ + TBuf8<32> buf; + buf.Format(_L8("SECURITY_FILE_VERSION: %d\n"), SEC_PARSER_VERSION); + return TIkeParser::BufferAppend(aPolBfr, buf); +} + +TInt TSecParser::WriteInfo(CSecurityPiece* aPiece_data, HBufC8*& aPolBfr) +{ + ASSERT(aPiece_data); + + TInt err; + + TBuf8 buf = _L8("[INFO]\n"); + err = TIkeParser::BufferAppend(aPolBfr, buf); + if (err != KErrNone) + return err; + + buf.Copy(aPiece_data->Info()->Des()); + err = TIkeParser::BufferAppend(aPolBfr, buf); + if (err != KErrNone) + return err; + return TIkeParser::BufferAppend(aPolBfr, (_L8("\n"))); +} + +TInt TSecParser::WriteIke(CSecurityPiece* aPiece_data, HBufC8*& aPolBfr) +{ + ASSERT(aPiece_data); + + TBuf8<6> buf = _L8("[IKE]\n"); + TInt err = TIkeParser::BufferAppend(aPolBfr, buf); + if (err != KErrNone) + return err; + return TIkeParser::Write(aPiece_data->IkeData(), aPolBfr); +} + + +// +//CSecurityPiece +// + +EXPORT_C void CSecurityPiece::ConstructL(TInt aSize) +{ + iInfo = HBufC::NewL(aSize); + iIkeData = CIkeData::NewL(); + iGeneralData = new (ELeave) CGeneralData(); +} + +EXPORT_C void CSecurityPiece::SetInfoL(const TDesC &aDes) +{ + if (aDes.Length() > iInfo->Des().MaxLength()) + iInfo = iInfo->ReAllocL(aDes.Length()); //ReAllocs if needed + + iInfo->Des().Copy(aDes); +} + +EXPORT_C CSecurityPiece::~CSecurityPiece() +{ + delete iInfo; + delete iIkeData; + delete iGeneralData; +} + + + + +EXPORT_C CGeneralData::CGeneralData() +{ +} + +EXPORT_C CGeneralData::CGeneralData(CGeneralData* aData) +{ + ASSERT(aData); + iDeactivationTimeout = aData->iDeactivationTimeout; +} + +EXPORT_C TGeneralParser::TGeneralParser(const TDesC &aStr) : TLex(aStr) + { + } + +EXPORT_C TInt TGeneralParser::Parse(CGeneralData* aData) +{ + ASSERT(aData); + + TLex sub_num; //Used for number conversion + TInt err = KErrNone; + TPtrC token(NULL,0); + while (!Eos() && err==KErrNone) + { + Mark(); + token.Set(NextToken()); + if (token.CompareF(_L("POLICY_AUTO_DEACTIVATION_TIMEOUT:")) == 0) //CompareF ignores case + { + sub_num = NextToken(); + if (sub_num.Val(aData->iDeactivationTimeout)!=KErrNone) + err = KErrGeneral; //change ?? + } + } + return err; +} + + +EXPORT_C TInt TSecParser::ParseGeneralData(CGeneralData* aData) +{ + TPtrC token(NULL, 0); + TInt ret; + + if (!CheckVersion()) + return KErrNotSupported; //Invalid file or version + while (!Eos()) + { + token.Set(NextToken()); + if (token.Compare(_L("[GENERAL]"))==0) + { + ret = ParseGeneral(aData); + if (ret !=KErrNone) + return ret; + } + else //Unknown Tag Ignored + NextTag(); + + } + + return KErrNone; +} + +// +// IkeParser +// +EXPORT_C RArray* IkeParser::GetApplUidListL( + const TDesC16& aApplUidString) + { + // + // Build application UID array from Application Uid text string + // + RArray* applUidList = new (ELeave) RArray(1); + CleanupStack::PushL( applUidList ); + TLex ApplUids(aApplUidString); + TUint32 Uid; + TUid ApplUid; + IkeParser::NextHexaDigit(ApplUids); + + while ( !ApplUids.Eos() ) + { + if ( ApplUids.Val(Uid, EHex) != KErrNone ) + { + break; // Error + } + ApplUid.iUid = Uid; + User::LeaveIfError( applUidList->Append(ApplUid) ); + IkeParser::NextHexaDigit(ApplUids); + } + CleanupStack::Pop( applUidList ); + return applUidList; + } + +EXPORT_C HBufC8* IkeParser::TextToHexOctetsL(const TDesC16& aTextString) +{ + TInt Lth = (aTextString.Length() + 1)/2; + HBufC8* HexOctets = HBufC8::NewL((Lth | 3) + 1); + if ( DeHex(aTextString.Ptr(), aTextString.Length(), (TUint8*)HexOctets->Ptr()) ) + HexOctets->Des().SetLength(Lth); + + return HexOctets; +} + +EXPORT_C TBool IkeParser::TextToHexOctets(const TDesC16& aTextString, TDes8& aHexOctets) +{ + TBool Status; + TInt Lth = ((aTextString.Length() + 1)/2); + if ( aHexOctets.MaxLength() >= Lth ) + { + Status = DeHex(aTextString.Ptr(), aTextString.Length(), (TUint8*)aHexOctets.Ptr()); + if ( !Status ) + Lth = 0; + } + else + { + Status = EFalse; + Lth = 0; + } + aHexOctets.SetLength(Lth); + + return Status; +} + +TBool IkeParser::DeHex(const TUint16* aUcStr, TInt aStrLen, TUint8* aDstBfr) +{ + TBool Status = ETrue; + TUint8 d1, d2; + + while ( (aStrLen > 0) && Status ) + { + d1 = (TUint8)(*aUcStr & 0xff); + Status &= HexVal(d1); + aUcStr ++; + if ( aStrLen > 1 ) + { + d2 = (TUint8)(*aUcStr & 0xff); + Status &= HexVal(d2); + } + else d2 = 0; + aUcStr ++; + aStrLen -= 2; + *aDstBfr++ = (TUint8)(d1 * 16 + d2); + } + return Status; +} + +TBool IkeParser::HexVal(TUint8& c) +{ + TBool Status = ( c >= 'a' && c <= 'f'); + if ( Status ) + c = (TUint8)(c - 'a' + 10); + else + { + Status = (c >= 'A' && c <= 'F'); + if ( Status ) + c = (TUint8)(c - 'A' + 10); + else + { + Status = (c >= '0' && c <= '9'); + if ( Status ) + c = (TUint8)(c - '0'); + } + } + return Status; +} + +void IkeParser::NextHexaDigit(TLex& aUidString) +{ + TChar ch; + + while ( !aUidString.Eos() ) + { + ch = aUidString.Peek(); + if ( ch.IsHexDigit() ) + { + break; + } + aUidString.Inc(); + } +} diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/bwins/ikesocketu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/bwins/ikesocketu.def Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?NewL@CIkeConnectionInterface@@SAPAV1@AAVMIkeDebug@@@Z @ 1 NONAME ; class CIkeConnectionInterface * CIkeConnectionInterface::NewL(class MIkeDebug &) + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/eabi/ikesocketu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/eabi/ikesocketu.def Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,7 @@ +EXPORTS + _ZN23CIkeConnectionInterface4NewLER9MIkeDebug @ 1 NONAME + _ZTI13CDataTransfer @ 2 NONAME ; ## + _ZTI23CIkeConnectionInterface @ 3 NONAME ; ## + _ZTV13CDataTransfer @ 4 NONAME ; ## + _ZTV23CIkeConnectionInterface @ 5 NONAME ; ## + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file provides the information required for building. +* +*/ + + +#include + +PRJ_PLATFORMS + +PRJ_EXPORTS + +PRJ_MMPFILES + +#ifdef VPNCLIENT_USE_STUBS +ikesocket_test.mmp +#else +ikesocket.mmp +#endif + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/group/ikesocket.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/group/ikesocket.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project ikesocket +* +*/ + + + +#include + +TARGET ikesocket.dll +TARGETTYPE dll +UID 0x1000008d 0x20000407 + +CAPABILITY All -Tcb +VENDORID VID_DEFAULT + +SOURCEPATH ../src + +SOURCE connobserver.cpp +SOURCE datatransfer.cpp +SOURCE ikeconnectioninterface.cpp +SOURCE ikeconnection.cpp +SOURCE localaddressresolver.cpp +SOURCE receivequeueitem.cpp +SOURCE receiver.cpp +SOURCE sender.cpp + +USERINCLUDE ../inc +USERINCLUDE ../../ikev2lib/inc +USERINCLUDE ../../kmdserver/inc +USERINCLUDE ../../ikeutils/inc + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY euser.lib +LIBRARY esock.lib +LIBRARY insock.lib +LIBRARY commdb.lib +LIBRARY extendedconnpref.lib +LIBRARY netmeta.lib diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/group/ikesocket_test.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/group/ikesocket_test.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Test project definition file for project ikesocket +* +*/ + + + +#include + +TARGET ikesocket.dll +TARGETTYPE dll +UID 0x1000008d 0x20000407 + +CAPABILITY All -Tcb +VENDORID VID_DEFAULT + +SOURCEPATH ../src + +SOURCE connobserver.cpp +SOURCE datatransfer.cpp +SOURCE ikeconnectioninterface.cpp +SOURCE ikeconnection.cpp +SOURCE localaddressresolver.cpp +SOURCE receivequeueitem.cpp +SOURCE receiver.cpp +SOURCE sender.cpp + +USERINCLUDE ../inc +USERINCLUDE ../../ikev2lib/inc +USERINCLUDE ../../kmdserver/inc +USERINCLUDE ../../ikeutils/inc + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY ikesocket_proxy.lib +LIBRARY euser.lib +LIBRARY esock.lib +LIBRARY insock.lib +LIBRARY commdb.lib +LIBRARY extendedconnpref.lib +LIBRARY netmeta.lib diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/inc/connobserver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/inc/connobserver.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,138 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Link connection status observer +* +*/ + +#ifndef C_CONNOBSERVER_H +#define C_CONNOBSERVER_H + +// INCLUDES +#include + +// FORWARD DECLARATIONS + +class MIkeDebug; +class RConnection; + +/** + * Link disconnection callback interface. + * + * Callback interface for notifying about link disconnection. + * + * @lib ikesocket.lib + */ +NONSHARABLE_CLASS( MConnObserverCallback ) + { +public: + /** + * Notifies about link disconnection. + * + * @param aStatus Link disconnection status + */ + virtual void LinkDisconnected( const TInt aStatus ) = 0; + }; + +/** + * Link connection status observer. + * + * This class provides functionality for observing when link connection has + * been disconnected. + * + * @lib ikesocket.lib + */ +NONSHARABLE_CLASS( CConnObserver ) : private CActive + { +public: + /** + * Two-phased constructor. + * + * @param aConnection Connection which is used for observing + * @param aCallback Callback interface + * @param aDebug Debug trace interface + */ + static CConnObserver* NewL( RConnection& aConnection, + MConnObserverCallback& aCallback, + MIkeDebug& aDebug ); + + /** + * Destructor. + */ + ~CConnObserver(); + + /** + * Requests notification about link disconnection. Link disconnection will + * be notified via MConnObserverCallback callback interface, when link has + * been disconnected. + */ + void NotifyDisconnect(); + + /** + * Cancels link disconnection notification request. + */ + void CancelNotify(); + +private: + +// from base class CActive + + /** + * From CActive. + * Handles an active object's request completion event about link + * disconnection progress notification. Notifies client about link + * disconnection via callback interface. Does not leave. + */ + void RunL(); + + /** + * From CActive. + * Implements cancellation of a link disconnection progress notification. + */ + void DoCancel(); + +private: + CConnObserver( RConnection& aConnection, + MConnObserverCallback& aCallback, + MIkeDebug& aDebug ); + + void ConstructL(); + +private: // data + /** + * Connection used for observing link disconnection. + * Not own. + */ + RConnection& iConnection; + + /** + * Buffer for Network Interface Progress. + * Own. + */ + TNifProgressBuf iProgressBuf; + + /** + * Callback interface for notifying link disconnection. + * Not own. + */ + MConnObserverCallback& iCallback; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + }; + + +#endif // C_CONNOBSERVER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/inc/datatransfer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/inc/datatransfer.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,431 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Data transfer functionality +* +*/ + + +#ifndef C_DATATRANSFER_H +#define C_DATATRANSFER_H + +#include +#include "ikedatainterface.h" +#include "sender.h" +#include "receiver.h" +#include "receivequeueitem.h" +#include "ikesocketdefs.h" + +// FORWARD DECLARATIONS + +class CLocalAddressResolver; +class MIkeDebug; + +/** + * Data transfer callback interface. + * + * Callback interface for informing fatal error in data transfer. + * + * @lib ikesocket.lib + */ +NONSHARABLE_CLASS( MDataTransferCallback ) + { +public: + enum TErrorType + { + ESendError, + EReceiveError + }; + + /** + * Notifies that data transfer error has occured. + * + * @param aError Error value + * @param aErrorType Error type + */ + virtual void DataTransferError( const TInt aError, + const TErrorType aErrorType ) = 0; + }; + +/** + * Data transfer class. + * + * This class provides functionality for transferring UDP data. This class + * implements data interface (MIkeDataInterface) which can be used + * by the client of data interface to send and receive UDP data. Received data + * is queued until client reads received data. + * + * Before instance of this class can be used for transferring data, owner of + * the instance must set IKE major version and request opening of sockets. + * When data transferring is no more needed, owner can request closing of + * sockets. Fatal data transfer errors are notified to owner through + * error callback interface (MDataTransferCallback). + * + * This class owns sockets for local ports 500 and 4500 which are used for + * both sending and receiving UDP data. This class owns also third socket + * which is used if the client of data interface sends Nokia NAT keepalive + * packet. + * + * @lib ikesocket.lib + */ +class CDataTransfer : public CBase, + public MIkeDataInterface, + public MSenderCallback, + public MReceiverCallback + { +public: + + /** + * Two-phased constructor. + * @param aSocketServer Socket server + * @param aConnection Connection + * @param aCallback Error callback interface + * @param aDebug Debug trace interface + */ + static CDataTransfer* NewL( RSocketServ& aSocketServer, + RConnection& aConnection, + CLocalAddressResolver& aLocalAddressResolver, + MDataTransferCallback& aCallback, + MIkeDebug& aDebug ); + + /** + * Destructor. + */ + ~CDataTransfer(); + + /** + * Sets IKE major version. IKE major version must be set before data + * interface is used for data transfer. + * + * @param aIkeMajorVersion IKE major version + */ + void SetIkeMajorVersion( const IkeSocket::TIkeMajorVersion aIkeMajorVersion ); + + /** + * Sets IP version. IP version must be set before data interface is used + * for getting local IP address. + * + * @param aIpVersion IP version + */ + void SetIpVersion( const IkeSocket::TIpVersion aIpVersion ); + + /** + * Opens sockets. Sockets for ports 500 and 4500 are bound to specified + * local IP address. + * + * @param aLocalIp Local IP address which is used to bind sockets (for ports + * 500 and 4500). + */ + TInt OpenSockets( const TInetAddr& aLocalIp ); + + /** + * Closes sockets. + */ + void CloseSockets(); + +// from base class MIkeDataInterface + + /** + * Sends UDP data. + * + * @param aLocalPort Local port + * @param aDestAddr Destination IP address/port + * @param aUdpData UDP data + * @param aDscp DSCP value + * @param aStatus Completion status (returned) + * -KErrArgument if local port is neither 500 or 4500, and + * destination port does not equal local port + * (equal when Nokia NAT keepalive packet + * sent) + * -KErrDisconnected if connection is disconnected + */ + void SendUdpData( const TInt aLocalPort, + const TInetAddr& aDestAddr, + const TDesC8& aUdpData, + const TUint aDscp, + TRequestStatus& aStatus ); + + /** + * Cancels sending. + */ + void CancelSend(); + + /** + * Starts to receive UDP data. Completes when data is available or error + * has occured. + * + * @param aUdpData Received UDP data (returned) + * @param aSrcAddr Source IP address/port (returned) + * @param aLocalPort Local port (returned) + * @param aStatus Completion status (returned) + * -KErrDisconnected if connection is disconnected + */ + void ReceiveUdpData( HBufC8*& aUdpData, + TInetAddr& aSrcAddr, + TInt& aLocalPort, + TRequestStatus& aStatus ); + + /** + * Cancels receive request. + */ + void CancelReceive(); + + /** + * Clears data which has been received. + */ + void ClearReceivedData(); + + /** + * Stops receiving. Clears data which has been received. + */ + void StopReceive(); + + /** + * Gets local IP address of interface. + * + * @param aLocalIp Local IP address (returned) + * @return Error status. KErrNotFound if address is not found. + */ + TInt GetLocalAddress( TInetAddr& aLocalIp ); + +// from base class MSenderCallback + + /** + * Notification about completed send. + */ + void SendCompleted( const TInt aStatus ); + +// from base class MReceiverCallback + + /** + * Notification that data has been received. Receiving is continued + * automatically by receiver. + * + * @param aUdpData Received UDP data. Ownership transferred. + * @param aSrcAddr Source address + * @param aLocalPort Local port + */ + void DataReceived( HBufC8* aUdpData, + const TInetAddr& aSrcAddr, + const TInt aLocalPort ); + + /** + * Notification about receive error. Receiving has been stopped by receiver. + * + * @param aStatus Error status + */ + void ReceiveError( const TInt aStatus ); + +private: + + CDataTransfer( RSocketServ& aSocketServer, + RConnection& aConnection, + CLocalAddressResolver& aLocalAddressResolver, + MDataTransferCallback& aCallback, + MIkeDebug& aDebug ); + + void ConstructL(); + + /** + * Opens specified socket. + * + * @param aSocket Socket + * @return Error value + */ + TInt OpenSocket( RSocket& aSocket ); + + /** + * Binds specified socket to local IP address/port. + * @param aSocket Socket + * @param aLocalIp Local IP address + * @param aLocalPort Local port + * @return Error value + */ + TInt BindSocket( RSocket& aSocket, + const TInetAddr& aLocalIp, + const TInt aLocalPort ); + + /** + * Cancels sending. + * + * @param aCompletionStatus Client completion status + */ + void DoCancelSend( const TInt aCompletionStatus = KErrCancel ); + + /** + * Cancels receiving. + * + * @param aCompletionStatus Client completion status + */ + void DoCancelReceive( const TInt aCompletionStatus = KErrCancel ); + + /** + * Completes send to client. + * + * @param aStatus Send status + */ + void CompleteSendToClient( const TInt aStatus ); + + /** + * Completes receive to client. + * + * @param aStatus Receive status + */ + void CompleteReceiveToClient( const TInt aStatus ); + + /** + * Receives more data if receiving not requested to be stopped. + */ + void ReceiveData(); + + /** + * Cleans up data from receive queue. + */ + void CleanupReceiveQueue(); + +private: // data + + /** + * Socket server. + * Not own. + */ + RSocketServ& iSocketServer; + + /** + * Connection used for data transfer. + * Not own. + */ + RConnection& iConnection; + + /** + * Pointer to client's request status for sending + * Not own. + */ + TRequestStatus* iClientStatusSend; + + /** + * Pointer to client's request status for receiving. + * Not own. + */ + TRequestStatus* iClientStatusReceive; + + /** + * Pointer to client's heap descriptor pointer (HBufC8*) variable. Variable + * will contain received message data, after receive has been completed + * successfully to client. + * Not own. + */ + HBufC8** iClientMsgReceive; + + /** + * Pointer to client's address variable. Variable will contain source + * address from which data has been received, after receive has been + * completed successfully to client. + * Not own. + */ + TInetAddr* iClientSrcAddrReceive; + + /** + * Pointer to client's address variable. Variable will contain local + * port from which data has been received, after receive has been + * completed successfully to client. + * Not own. + */ + TInt* iClientLocalPort; + + /** + * Socket for port 500. + * Own. + */ + RSocket iSocket; + + /** + * Socket for port 4500. + * Own. + */ + RSocket iSocketNAT; + + /** + * Socket for Nokia NAT port. + * Own. + */ + RSocket iSocketNokiaNAT; + + /** + * Local Nokia NAT port. + * Own. + */ + TInt iLocalNokiaNATPort; + + /** + * Informs if sockets are open or not. + * Own. + */ + TBool iSocketsOpen; + + /** + * Informs if receiving is stopped or not. + * Own. + */ + TBool iReceivingStopped; + + /** + * Receiver for port 500. + * Own. + */ + CReceiver* iReceiver; + + /** + * Receiver for port 4500. + * Own. + */ + CReceiver* iReceiverNAT; + + /** + * Sender. + * Own. + */ + CSender* iSender; + + /** + * Queue containing received data. + * Own. + */ + RArray iReceiveQueue; + + /** + * Local address resolver. + * Not own. + */ + CLocalAddressResolver& iLocalAddressResolver; + + /** + * IP version. + * Own. + */ + IkeSocket::TIpVersion iIpVersion; + + /** + * Error callback interface. + * Not own. + */ + MDataTransferCallback& iErrorCallback; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + }; + +#endif // C_DATATRANSFER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/inc/ikeconnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/inc/ikeconnection.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,291 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE connection +* +*/ + + +#ifndef C_IKECONNECTION_H +#define C_IKECONNECTION_H + +#include +#include +#include +#include +#include "connobserver.h" +#include "datatransfer.h" +#include "ikeconnectioninterface.h" + +// FORWARD DECLARATIONS +class CConnObserver; +class CDataTransfer; +class CLocalAddressResolver; +class MIkeDebug; +class RSocketServ; + +/** + * IKE socket connection class. + * + * This class provides functionality for managing VPN AP's real network + * connection. This class implements IKE socket connection interface + * (CIkeConnectionInterface). + * + * This class owns data transfer object, which implements data interface + * (MIkeDataInterface). Possible fatal data transfer errors are handled + * in this class. + * + * @lib ikesocket.lib + */ +NONSHARABLE_CLASS( CIkeConnection ) : public CIkeConnectionInterface, + public MDataTransferCallback, + public MConnObserverCallback + { +public: + /** + * Two-phased constructor. + * @param aDebug Debug trace interface + */ + static CIkeConnection* NewL( MIkeDebug& aDebug ); + + /** + * Destructor. + */ + ~CIkeConnection(); + + /** + * Opens data interface. + * + * @param aIkeMajorVersion IKE major version + * @param aIpVersion IP protocol version + * @return Data interface + */ + MIkeDataInterface& OpenDataInterfaceL( const TIkeMajorVersion aIkeMajorVersion, + const TIpVersion aIpVersion ); + +// from base class MIkeConnectionInterface + + void StartConnection( const TUint32 aIapId, + const TUint32 aSnapId, + TRequestStatus& aStatus, + const TBool aForcedRoaming = EFalse ); + void CancelStartConnection(); + void StopConnection(); + void ResolveFQDNAddress( const TDesC& aFQDN, + TNameEntry& aNameEntry, + TRequestStatus& aStatus ); + void CancelResolveFQDNAddress(); + void NotifyDisconnect( TRequestStatus& aStatus ); + void CancelNotifyDisconnect(); + TUint32 IapId() const; + TUint32 NetId() const; + TUint32 SnapId() const; + TInt GetLocalAddress( const TIpVersion aIpVersion, + TInetAddr& aLocalIp ); + +// from base class MDataTransferCallback + + /** + * Notification about fatal data transfer error. + * + * @param aError Error value + * @param aErrorType Error type + */ + void DataTransferError( const TInt aError, + const TErrorType aErrorType ); + +// from base class MConnObserverCallback + + /** + * Notification about link disconnection. + * + * @param aStatus Link disconnection status + */ + void LinkDisconnected( const TInt aStatus ); + +private: + + enum TConnectionState + { + EIdle, + EConnecting, + EResolvingFQDN, + EConnected + }; + + CIkeConnection( MIkeDebug& aDebug ); + + void ConstructL(); + + /** + * Creates connection preferences for SNAP usage. + * @param aSnapId SNAP id + * @param aForcedRoaming Indicates whether forced roaming is enabled or + * disabled for SNAP + */ + void CreateSnapPreferencesL( const TUint32 aSnapId, + const TBool aForcedRoaming ); + + /** + * Cleans connection preferences created for SNAP usage. + */ + void CleanSnapPreferences(); + + /** + * Updates IAP id and NET id. + */ + void UpdateRealIapData(); + + /** + * Handles completion of asynchronous request in EConnecting state. + */ + void DoStateAfterConnecting(); + + /** + * Handles completion of asynchronous request in EResolvingFQDN state. + */ + void DoStateAfterResolvingFQDN(); + + /** + * Implements cancellation of connection starting. + */ + void DoCancelStartConnection(); + + /** + * Implements cancellation of FQDN address resolving. + */ + void DoCancelResolveFQDNAddress(); + + // from base class CActive + + /** + * From CActive. + * Handles an active object's request completion event. + */ + void RunL(); + + /** + * From CActive. + * Implements cancellation of an active request. + */ + void DoCancel(); + +private: // data + + /** + * Connection state. + * Own. + */ + TConnectionState iState; + + /** + * Socket server. + * Own. + */ + RSocketServ iSocketServer; + + /** + * Network connection. + * Own. + */ + RConnection iConnection; + + /** + * Host resolver. + * Own. + */ + RHostResolver iResolver; + + /** + * IP version. + * Own. + */ + TIpVersion iIpVersion; + + /** + * IAP id. + * Own. + */ + TUint32 iIapId; + + /** + * NET id. + * Own. + */ + TUint32 iNetId; + + /** + * SNAP id. + * Own. + */ + TUint32 iSnapId; + + /** + * Connection preferences. + * Own. + */ + TCommDbConnPref iPrefs; + + /** + * Extended connection preferences. + * Own. + */ + TExtendedConnPref iExtendedPrefs; + + /** + * Connection preferences list. + * Own. + */ + TConnPrefList iConnPrefList; + + /** + * Pointer to client's request status. Used for starting connection and + * resolving FQDN address. + * Not own. + */ + TRequestStatus* iClientStatus; + + /** + * Pointer to client's request status. Used for requesting disconnect + * notification. + * Not own. + */ + TRequestStatus* iClientStatusNotifyDisconnect; + + /** + * Data transfer object. + * Own. + */ + CDataTransfer* iDataTransfer; + + /** + * Link status observer. + * Own. + */ + CConnObserver* iLinkObserver; + + /** + * Local address resolver. + * Own. + */ + CLocalAddressResolver* iLocalAddressResolver; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + + }; + +#endif // C_IKECONNECTION_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/inc/ikeconnectioninterface.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/inc/ikeconnectioninterface.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,164 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE socket connection interface +* +*/ + + +#ifndef C_IKECONNECTIONINTERFACE_H +#define C_IKECONNECTIONINTERFACE_H + +#include +#include +#include "ikesocketdefs.h" + +using namespace IkeSocket; + +// FORWARD DECLARATIONS +class MIkeDebug; +class MIkeDataInterface; +class RSocketServer; + +/** + * IKE socket connection interface. + * + * This interface defines functionality for managing VPN AP's real network + * connection. + * + * Data interface (MIkeDataInterface) needs to be opened via this class. Data + * interface is closed automatically, when instance of connection interface + * (this interface) is deleted. + * + * @lib ikesocket.lib + */ + +class CIkeConnectionInterface : protected CActive + { +public: + /** + * Two-phased constructor. + * @param aDebug Debug trace interface + */ + IMPORT_C static CIkeConnectionInterface* NewL( MIkeDebug& aDebug ); + + /** + * Destructor. + */ + virtual ~CIkeConnectionInterface(); + + /** + * Opens data interface. + * + * @param aIkeMajorVersion IKE major version + * @param aIpVersion IP protocol version + * @return Data interface + */ + virtual MIkeDataInterface& OpenDataInterfaceL( const TIkeMajorVersion aIkeMajorVersion, + const TIpVersion aIpVersion ) = 0; + + /** + * Establishes connection for specified SNAP (destination) or IAP. + * + * @param aIapId IAP id + * @param aSnapId SNAP id + * @param aStatus Completion status (returned) + * @param aForcedRoaming Indicates whether forced roaming is enabled or + * disabled for SNAP + */ + virtual void StartConnection( const TUint32 aIapId, + const TUint32 aSnapId, + TRequestStatus& aStatus, + const TBool aForcedRoaming = EFalse ) = 0; + + /** + * Cancels connection establishment. + * + */ + virtual void CancelStartConnection() = 0; + + /** + * Closes the connection. + * + */ + virtual void StopConnection() = 0; + + /** + * Resolves an IP address from FQDN address. + * + * @param aFQDN Fully Qualified Domain Name + * @param aNameEntry Result of name resolution (returned) + * @param aStatus Completion status (returned) + */ + virtual void ResolveFQDNAddress( const TDesC& aFQDN, + TNameEntry& aNameEntry, + TRequestStatus& aStatus ) = 0; + + /** + * Cancels FQDN address resolving. + * + */ + virtual void CancelResolveFQDNAddress() = 0; + + /** + * Starts listening disconnect notification. + * + * @param aStatus Disconnection status (returned) + */ + virtual void NotifyDisconnect( TRequestStatus& aStatus ) = 0; + + /** + * Cancels notifying of disconnect indication. + * + */ + virtual void CancelNotifyDisconnect() = 0; + + /** + * Returns IAP id. + * + * @return IAP id + */ + virtual TUint32 IapId() const = 0; + + /** + * Returns NET id. + * + * @return NET id + */ + virtual TUint32 NetId() const = 0; + + /** + * Returns SNAP id. + * + * @return SNAP id + */ + virtual TUint32 SnapId() const = 0; + + /** + * Gets local IP address of interface. + * + * @param aIpVersion IP version of local IP address + * @param aLocalIp Local IP address (returned) + * @return Error status. KErrNotFound if address is not found. + */ + virtual TInt GetLocalAddress( const TIpVersion aIpVersion, + TInetAddr& aLocalIp ) = 0; + +protected: + + CIkeConnectionInterface( TInt aPriority ); + + }; + + +#endif // C_IKECONNECTIONINTERFACE_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/inc/ikedatainterface.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/inc/ikedatainterface.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,104 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE socket data interface +* +*/ + + +#ifndef M_IKEDATAINTERFACE_H +#define M_IKEDATAINTERFACE_H + +#include + +/** + * IKE socket data transfer interface. + * + * This interface defines functionality for sending and receiving UDP data. + * + * After client has started receiving, data is queued to receive queue. Queud + * data will be cleared, when clients stops receiving, or connection has been + * disconnected. + * + * @lib ikesocket.lib + */ +class MIkeDataInterface + { +public: + + /** + * Sends UDP data. + * + * @param aLocalPort Local port + * @param aDestAddr Destination IP address/port + * @param aUdpData UDP data + * @param aDscp DSCP value + * @param aStatus Completion status (returned) + * -KErrArgument if local port is neither 500 or 4500, and + * destination port does not equal local port + * (equal when Nokia NAT keepalive packet + * sent) + * -KErrDisconnected if connection is disconnected + */ + virtual void SendUdpData( const TInt aLocalPort, + const TInetAddr& aDestAddr, + const TDesC8& aUdpData, + const TUint aDscp, + TRequestStatus& aStatus ) = 0; + + /** + * Cancels sending. + */ + virtual void CancelSend() = 0; + + /** + * Starts to receive UDP data. Completes when data is available or error + * has occured. + * + * @param aUdpData Received UDP data (returned) + * @param aSrcAddr Source IP address/port (returned) + * @param aLocalPort Local port (returned) + * @param aStatus Completion status (returned) + * -KErrDisconnected if connection is disconnected + */ + virtual void ReceiveUdpData( HBufC8*& aUdpData, + TInetAddr& aSrcAddr, + TInt& aLocalPort, + TRequestStatus& aStatus ) = 0; + + /** + * Cancels receive request. + */ + virtual void CancelReceive() = 0; + + /** + * Clears data which has been received. + */ + virtual void ClearReceivedData() = 0; + + /** + * Stops receiving. Clears data which has been received. + */ + virtual void StopReceive() = 0; + + /** + * Gets local IP address of interface. + * + * @param aLocalIp Local IP address (returned) + * @return Error status. KErrNotFound if address is not found. + */ + virtual TInt GetLocalAddress( TInetAddr& aLocalIp ) = 0; + }; + + +#endif // M_IKEDATAINTERFACE_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/inc/ikesocketassert.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/inc/ikesocketassert.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Special assert macros for IKE socket +* +*/ + + +#ifndef IKESOCKETASSERT_H +#define IKESOCKETASSERT_H + +#include "ikedebug.h" + +#ifdef _DEBUG + +#define IKESOCKET_ASSERT(cond) if(!(cond)){ DEBUG_LOG(_L("ASSERTION FAILED")); DEBUG_LOG1(_L("%s, "), __FILE__); DEBUG_LOG1(_L("%d"), __LINE__); User::Invariant();} +#define IKESOCKET_INVARIANT() DEBUG_LOG(_L("ASSERTION FAILED")); DEBUG_LOG1(_L("%s, "), __FILE__); DEBUG_LOG1(_L("%d"), __LINE__); User::Invariant() + +#else + +#define IKESOCKET_ASSERT(cond) +#define IKESOCKET_INVARIANT() + +#endif + +#endif // IKESOCKETASSERT_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/inc/ikesocketdefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/inc/ikesocketdefs.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE socket definitions +* +*/ + + +#ifndef IKESOCKETDEFS_H +#define IKESOCKETDEFS_H + +namespace IkeSocket + { + const TInt KIkePort500( 500 ); + const TInt KIkePort4500( 4500 ); + + enum TIkeMajorVersion + { + EIkeMajorV1 = 1, + EIkeMajorV2 = 2 + }; + + enum TIpVersion + { + EIPv4 = 4, + EIPv6 = 6 + }; + } + +#endif // IKESOCKETDEFS_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/inc/localaddressresolver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/inc/localaddressresolver.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,159 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Local address resolver +* +*/ + + +#ifndef C_LOCALADDRRESOLVER_H +#define C_LOCALADDRRESOLVER_H + +#include +#include "ikesocketdefs.h" + +// FORWARD DECLARATIONS +class MIkeDebug; + +/** + * Local address resolver. + * + * This class resolves local IP addresses (IPv4 and/or IPv6) for network + * connection (RConnection). + * + * @lib ikesocket.lib + */ +NONSHARABLE_CLASS( CLocalAddressResolver ) : public CBase + { +public: + /** + * Two-phased constructor. + * @param aSocketServer Socket server + * @param aConnection RConnection which is used for resolving + * @param aDebug Debug trace interface + */ + static CLocalAddressResolver* NewL( RSocketServ& aSocketServer, + RConnection& aConnection, + MIkeDebug& aDebug); + + /** + * Destructor. + */ + ~CLocalAddressResolver(); + + /** + * Returns information about whether local IP address has been resolved. + * @param aIpVersion IP version of local address (IPv4/IPv6) + * @return Local IP address resolved or not. + */ + TBool HasIPAddr( const IkeSocket::TIpVersion aIpVersion ) const; + + /** + * Returns resolved local IP address. + * @param aIpVersion IP version of local address (IPv4/IPv6) + * @return Local IP address. + */ + const TInetAddr& IPAddr( const IkeSocket::TIpVersion aIpVersion ) const; + + /** + * Refreshes local IP addresses (IPv4 and/or IPv6). + * @param aIpVersion IP version of local address (IPv4/IPv6) + * @return Local IP address. + */ + TInt RefreshLocalAddresses(); + + /** + * Gets local IP address of interface. + * + * @param aIpVersion IP version of local IP address + * @param aLocalIp Local IP address (returned) + * @return Error status. KErrNotFound if address is not found. + */ + TInt GetLocalAddress( const IkeSocket::TIpVersion aIpVersion, + TInetAddr& aLocalIp ); + +private: + + CLocalAddressResolver( RSocketServ& aSocketServer, + RConnection& aConnection, + MIkeDebug& aDebug ); + + void ConstructL(); + + /** + * Mathches information of an interface and the connection. + * @param aInfo Information of interface + * @return aQuery Query for interface + */ + TBool Match( const TSoInetInterfaceInfo& aInfo, + const TSoInetIfQuery& aQuery) const; + + /** + * Sets local IP address if not yet set. + * @param aAddr IP address + */ + void SetAddressIfNotSet( const TInetAddr& aAddr ); + + /** + * Sets local IPv4 address if not yet set. + * @param aAddr IP address + */ + void SetIPv4AddressIfNotSet( const TInetAddr& aAddr ); + + /** + * Sets local IPv6 address if not yet set. + * @param aAddr IP address + */ + void SetIPv6AddressIfNotSet( const TInetAddr& aAddr ); + +private: // data + /** + * IAP id of the connection. + * Own. + */ + TUint32 iIapId; + + /** + * Socket server. + * Not own. + */ + RSocketServ& iSocketServer; + + /** + * Connection. + * Not own. + */ + RConnection& iConnection; + + /** + * Local IPv4 address. + * Own. + */ + TInetAddr iIPv4Addr; + + /** + * Local IPv6 address. + * Own. + */ + TInetAddr iIPv6Addr; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + }; + +#endif // C_LOCALADDRRESOLVER_H + + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/inc/receivequeueitem.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/inc/receivequeueitem.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,91 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Receive queue item +* +*/ + + +#ifndef T_RECEIVEQUEUEITEM_H +#define T_RECEIVEQUEUEITEM_H + +#include + +/** + * Item in receive queue + * + * Item contains information related to received UDP data. Items are stored + * in receive queue while they are waiting to be read by the client. + * + * @lib ikesocket.lib + */ +class TReceiveQueueItem + { +public: + + /** + * Constructor. + * + * @param aUdpData UDP data + * @param aSrcAddr Source IP address/port + * @param aLocalPort Local port + */ + TReceiveQueueItem( HBufC8* aUdpData, + const TInetAddr& aSrcAddr, + const TInt aLocalPort ); + + /** + * Returns UDP data. + * + * @return Udp data + */ + HBufC8* UdpData() const; + + /** + * Returns source address. + * + * @return Source address + */ + const TInetAddr& SrcAddr() const; + + /** + * Returns local port. + * + * @return Local port + */ + TInt LocalPort() const; + +private: + + /** + * Udp data + * Own. + */ + HBufC8* iUdpData; + + /** + * Source address + * Own. + */ + TInetAddr iSrcAddr; + + /** + * Local port + * Own. + */ + TInt iLocalPort; + + }; + + +#endif // T_RECEIVEQUEUEITEM_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/inc/receiver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/inc/receiver.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,235 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Receiver for UDP data +* +*/ + + +#ifndef C_RECEIVER_H +#define C_RECEIVER_H + +#include +#include +#include "ikesocketdefs.h" + +// FORWARD DECLARATIONS +class MIkeDebug; + +/** + * Receiver callback interface. + * + * Callback interface for informing that data has been received or error + * has occured. + * + * @lib ikesocket.lib + */ +NONSHARABLE_CLASS( MReceiverCallback ) + { +public: + /** + * Notifies that data has been received. Receiving is continued + * automatically. + * + * @param aUdpData Received UDP data. Ownership transferred. + * @param aSrcAddr Source address + * @param aLocalPort Local port + */ + virtual void DataReceived( HBufC8* aUdpData, + const TInetAddr& aSrcAddr, + const TInt aLocalPort ) = 0; + + /** + * Notifies about receive error. Receiving has been stopped. + * + * @param aStatus Error status + */ + virtual void ReceiveError( const TInt aStatus ) = 0; + }; + +/** + * Receiver of UDP data. + * + * This class provides functionality for receiving UDP data from specified + * socket (RSocket). Notification that data has been received and unhandled + * errors in receiving are notified via MReceiverCallback callback interface. + * Received data will be ignored, if data does not correspond to specified + * IKE major version. + * + * @lib ikesocket.lib + */ +NONSHARABLE_CLASS( CReceiver ) : private CActive + { +public: + /** + * Two-phased constructor. + * @param aSocket Socket which is used for receiving + * @param aCallback Callback interface + * @param aDebug Debug trace interface + */ + static CReceiver* NewL( RSocket& aSocket, + MReceiverCallback& aCallback, + MIkeDebug& aDebug ); + + /** + * Destructor. + */ + ~CReceiver(); + + /** + * Sets IKE major version. + * + * @param aIkeMajorVersion IKE major version + */ + void SetIkeMajorVersion( const IkeSocket::TIkeMajorVersion aIkeMajorVersion ); + + /** + * Starts receiving UDP data. Notification that data has been received or + * notification about unhandled errors will be done via MReceiverCallback + * callback interface. + * + * IKE major version must be set before receiving is started. Received data + * will be ignored, if data does not correspond to specified IKE major + * version. + */ + void Receive(); + + /** + * Cancels receiving. + */ + void CancelReceive(); + +private: + + enum TReceiverState + { + EIdle, // Idle + EWaitingData, // Waiting data to become available for reading + EReceiving // Receiving data + }; + + CReceiver( RSocket& aSocket, + MReceiverCallback& aCallback, + MIkeDebug& aDebug ); + + void ConstructL(); + + /** + * Waits for data to become available for reading. + */ + void WaitDataAvailable(); + + /** + * Receives data from socket. + */ + void ReceiveDataL(); + + /** + * Handles received data. + */ + void HandleDataReceivedL(); + + /** + * Handles error in receiving. + */ + void HandleError( const TInt aStatus ); + + /** + * Notifies client that data has been received. + */ + void NotifyDataReceived(); + + +// from base class CActive + + /** + * From CActive. + * Handles a leave occurring in RunL(). + * + * @param aError The leave code + */ + TInt RunError( TInt aError ); + + /** + * From CActive. + * Handles an active object's request completion event about available data + * or received data. + */ + void RunL(); + + /** + * From CActive. + * Implements cancellation of an active request. + */ + void DoCancel(); + +private: // data + + /** + * Receiver state. + * Own. + */ + TReceiverState iState; + + /** + * Message data. + * Own. + */ + HBufC8* iMsg; + + /** + * Message pointer. + * Own. + */ + TPtr8 iMsgPtr; + + /** + * Flags for Ioctl command. + * Own. + */ + TPckgBuf< TUint > iFlags; + + /** + * Source address. + * Own. + */ + TInetAddr iSrcAddr; + + /** + * IKE major version. + * Own. + */ + TUint iIkeMajorVersion; + + /** + * Socket. + * Not own. + */ + RSocket& iSocket; + + /** + * Callback for completing receiving. + * Not own. + */ + MReceiverCallback& iCallback; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + }; + + +#endif // C_RECEIVER_H + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/inc/sender.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/inc/sender.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,161 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Sender for UDP data +* +*/ + + +#ifndef C_SENDER_H +#define C_SENDER_H + +#include +#include + +// FORWARD DECLARATIONS + +class MIkeDebug; + +/** + * Sender callback interface. + * + * Callback interface for informing completion of sending. + * + * @lib ikesocket.lib + */ +NONSHARABLE_CLASS( MSenderCallback ) + { +public: + /** + * Notifies about completed sending. + * + * @param aStatus Completion status + */ + virtual void SendCompleted( const TInt aStatus ) = 0; + }; + +/** + * Sender of UDP data. + * + * This class provides functionality for sending UDP data. Completion of + * sending is notified via MSenderCallback callback interface. + * + * @lib ikesocket.lib + */ +NONSHARABLE_CLASS( CSender ) : public CActive + { +public: + /** + * Two-phased constructor. + * @param aSocket Socket for local port 500 + * @param aSocketNAT Socket for local port 4500 + * @param aSocketNokiaNAT Socket for Nokia NAT port + * @param aCallback Callback interface + * @param aDebug Debug trace interface + */ + static CSender* NewL( RSocket& aSocket, + RSocket& aSocketNAT, + RSocket& aSocketNokiaNAT, + MSenderCallback& aCallback, + MIkeDebug& aDebug ); + + /** + * Destructor. + */ + ~CSender(); + + /** + * Sends UDP data. + * + * @param aLocalPort Local port + * @param aDestAddr Destination IP address/port + * @param aUdpData UDP data + * @param aDscp DSCP value + * @return Error value + */ + TInt SendUdpData( const TInt aLocalPort, + const TInetAddr& aDestAddr, + const TDesC8& aUdpData, + const TUint aDscp ); + +// from base class CActive + + /** + * From CActive. + * Handles an active object's request completion event about sending. + */ + void RunL(); + + /** + * From CActive. + * Implements cancellation of sending. + */ + void DoCancel(); + +private: + + CSender( RSocket& aSocket, + RSocket& aSocketNAT, + RSocket& aSocketNokiaNAT, + MSenderCallback& aCallback, + MIkeDebug& aDebug ); + + void ConstructL(); + + +private: // data + + /** + * Socket for port 500. + * Not own. + */ + RSocket& iSocket; + + /** + * Socket for port 4500. + * Not own. + */ + RSocket& iSocketNAT; + + /** + * Socket for Nokia NAT port. + * Not own. + */ + RSocket& iSocketNokiaNAT; + + /** + * Local port used for sending. + * Own. + */ + TInt iLocalPort; + + /** + * Destination address used for sending. + * Own. + */ + TInetAddr iDestAddr; + + /** + * Sender callback for completing sending. + * Not own. + */ + MSenderCallback& iCallback; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + }; + +#endif // C_SENDER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/rom/ikesocket.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/rom/ikesocket.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Image description file for project ikesocket +* +*/ + + + +#ifndef __IKESOCKET_IBY__ +#define __IKESOCKET_IBY__ + +#ifdef SYMBIAN_EXCLUDE_IPSEC + +REM Feature IKESOCKET not included in this rom + +#else + +file=ABI_DIR\BUILD_DIR\ikesocket.dll SHARED_LIB_DIR\ikesocket.dll + +#endif // SYMBIAN_EXCLUDE_IPSEC +#endif \ No newline at end of file diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/src/connobserver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/src/connobserver.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,124 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Link connection status observer +* +*/ + + +// INCLUDE FILES +#include "connobserver.h" +#include "ikedebug.h" +#include "ikesocketassert.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CConnObserver* CConnObserver::NewL( RConnection& aConnection, + MConnObserverCallback& aCallback, + MIkeDebug& aDebug ) + { + CConnObserver* self = new (ELeave) CConnObserver( aConnection, + aCallback, + aDebug ); + + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CConnObserver::~CConnObserver() + { + DEBUG_LOG( _L("CConnObserver::~CConnObserver") ); + Cancel(); + } + +// --------------------------------------------------------------------------- +// Requests notification about link disconnection. +// --------------------------------------------------------------------------- +// +void CConnObserver::NotifyDisconnect() + { + IKESOCKET_ASSERT( !IsActive() ); + + iConnection.ProgressNotification( iProgressBuf, + iStatus, + KLinkLayerClosed ); + DEBUG_LOG( _L("RConnection::ProgressNotification() started") ); + SetActive(); + } + +// --------------------------------------------------------------------------- +// Cancels link disconnection notification request. +// --------------------------------------------------------------------------- +// +void CConnObserver::CancelNotify() + { + Cancel(); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CConnObserver::CConnObserver( RConnection& aConnection, + MConnObserverCallback& aCallback, + MIkeDebug& aDebug ) + :CActive(EPriorityStandard), + iConnection( aConnection ), + iCallback( aCallback ), + iDebug( aDebug ) + { + CActiveScheduler::Add(this); //Added to the Active Scheduler + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CConnObserver::ConstructL() + { + DEBUG_LOG( _L("CConnObserver::ConstructL") ); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles completion of progress notification. +// --------------------------------------------------------------------------- +// +void CConnObserver::RunL() + { + DEBUG_LOG1( _L("CConnObserver::RunL(), iStatus=%d"), iStatus.Int() ); + iCallback.LinkDisconnected( iStatus.Int() ); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Cancels progress notification. +// --------------------------------------------------------------------------- +// +void CConnObserver::DoCancel() + { + iConnection.CancelProgressNotification(); + DEBUG_LOG( _L("RConnection::CancelProgressNotification() called") ); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/src/datatransfer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/src/datatransfer.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,577 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Data transfer functionality +* +*/ + + +#include "datatransfer.h" +#include "ikemsgheader.h" +#include "ikev2const.h" +#include "localaddressresolver.h" +#include "ikedebug.h" +#include "ikesocketassert.h" + +using namespace IkeSocket; + +const TInt KReceiveQueueMaxCount( 10 ); + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CDataTransfer* CDataTransfer::NewL( RSocketServ& aSocketServer, + RConnection& aConnection, + CLocalAddressResolver& aLocalAddressResolver, + MDataTransferCallback& aCallback, + MIkeDebug& aDebug ) + { + CDataTransfer* self = new (ELeave) CDataTransfer( aSocketServer, + aConnection, + aLocalAddressResolver, + aCallback, + aDebug ); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CDataTransfer::~CDataTransfer() + { + DEBUG_LOG( _L("CDataTransfer::~CDataTransfer") ); + + CloseSockets(); + iReceiveQueue.Close(); + + delete iSender; + delete iReceiver; + delete iReceiverNAT; + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CDataTransfer::CDataTransfer( RSocketServ& aSocketServer, + RConnection& aConnection, + CLocalAddressResolver& aLocalAddressResolver, + MDataTransferCallback& aCallback, + MIkeDebug& aDebug ) + : iSocketServer( aSocketServer ), + iConnection( aConnection ), + iLocalNokiaNATPort( 0 ), + iLocalAddressResolver( aLocalAddressResolver ), + iErrorCallback( aCallback ), + iDebug( aDebug ) + { + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CDataTransfer::ConstructL() + { + DEBUG_LOG( _L("CDataTransfer::ConstructL") ); + + iSender = CSender::NewL( iSocket, + iSocketNAT, + iSocketNokiaNAT, + *this, + iDebug ); + iReceiver = CReceiver::NewL( iSocket, + *this, + iDebug ); + + iReceiverNAT = CReceiver::NewL( iSocketNAT, + *this, + iDebug ); + } + +// --------------------------------------------------------------------------- +// Sets IKE major version to receivers. +// --------------------------------------------------------------------------- +// +void CDataTransfer::SetIkeMajorVersion( const TIkeMajorVersion aIkeMajorVersion ) + { + IKESOCKET_ASSERT( iReceiver ); + IKESOCKET_ASSERT( iReceiverNAT ); + + iReceiver->SetIkeMajorVersion( aIkeMajorVersion ); + iReceiverNAT->SetIkeMajorVersion( aIkeMajorVersion ); + } + +// --------------------------------------------------------------------------- +// Sets IP version. +// --------------------------------------------------------------------------- +// +void CDataTransfer::SetIpVersion( const IkeSocket::TIpVersion aIpVersion ) + { + iIpVersion = aIpVersion; + } + +// --------------------------------------------------------------------------- +// Opens sockets and binds sockets for ports 500 and 4500. +// --------------------------------------------------------------------------- +// +TInt CDataTransfer::OpenSockets( const TInetAddr& aLocalIp ) + { + IKESOCKET_ASSERT( !iSocketsOpen ); + + // Open sockets + TInt err = OpenSocket( iSocket ); + + if ( err == KErrNone ) + { + err = OpenSocket( iSocketNAT ); + + if ( err == KErrNone ) + { + err = OpenSocket( iSocketNokiaNAT ); + } + } + + // Bind sockets for ports 500 and 4500 + if ( err == KErrNone ) + { + err = BindSocket( iSocket, aLocalIp, KIkePort500 ); + + if ( err == KErrNone ) + { + err = BindSocket( iSocketNAT, aLocalIp, KIkePort4500 ); + } + } + + if ( err == KErrNone ) + { + iSocketsOpen = ETrue; + } + else + { + // Close sockets if error + iSocket.Close(); + iSocketNAT.Close(); + iSocketNokiaNAT.Close(); + iSocketsOpen = EFalse; + } + + DEBUG_LOG1( _L("CDataTransfer::OpenSockets, err=%d"), err ); + return err; + } + +// --------------------------------------------------------------------------- +// Closes sockets. +// --------------------------------------------------------------------------- +// +void CDataTransfer::CloseSockets() + { + DEBUG_LOG1( _L("CDataTransfer::CloseSockets, sockets open=%d"), + iSocketsOpen ); + + if ( iSocketsOpen ) + { + // Cancel send and receive. + DoCancelSend( KErrDisconnected ); + DoCancelReceive( KErrDisconnected ); + + // Stop receiving. + StopReceive(); + + // Close sockets. + iSocket.Close(); + iSocketNAT.Close(); + iSocketNokiaNAT.Close(); + + iSocketsOpen = EFalse; + } + } + +// --------------------------------------------------------------------------- +// Sends UDP data. +// --------------------------------------------------------------------------- +// +void CDataTransfer::SendUdpData( const TInt aLocalPort, + const TInetAddr& aDestAddr, + const TDesC8& aUdpData, + const TUint aDscp, + TRequestStatus& aStatus ) + { + TInt err( KErrNone ); + + IKESOCKET_ASSERT( iClientStatusSend == NULL ); + IKESOCKET_ASSERT( iSender ); + + iClientStatusSend = &aStatus; + *iClientStatusSend = KRequestPending; + + if ( !iSocketsOpen ) + { + err = KErrDisconnected; + } + + if ( err == KErrNone ) + { + if ( ( aLocalPort != KIkePort500 ) && + ( aLocalPort != KIkePort4500 ) ) + { + // Nokia NAT keepalive packet. + if ( aLocalPort == aDestAddr.Port() ) + { + if ( iLocalNokiaNATPort == 0 ) + { + // Set Nokia NAT Port if not set. + err = iSocketNokiaNAT.SetLocalPort( aLocalPort ); + + if ( err == KErrNone ) + { + iLocalNokiaNATPort = aLocalPort; + } + } + else if ( iLocalNokiaNATPort != aLocalPort ) + { + // Nokia NAT port cannot be changed + // during connection. + err = KErrArgument; + } + else + { + err = KErrNone; + } + } + else + { + // Local port does not match destination port. + err = KErrArgument; + } + } + } + + if ( err == KErrNone ) + { + err = iSender->SendUdpData( aLocalPort, + aDestAddr, + aUdpData, + aDscp ); + } + + if ( err ) + { + CompleteSendToClient( err ); + } + } + + +// --------------------------------------------------------------------------- +// Cancels sending. +// --------------------------------------------------------------------------- +// +void CDataTransfer::CancelSend() + { + DoCancelSend(); + } + +// --------------------------------------------------------------------------- +// Receives UDP data. +// --------------------------------------------------------------------------- +// +void CDataTransfer::ReceiveUdpData( HBufC8*& aUdpData, + TInetAddr& aSrcAddr, + TInt& aLocalPort, + TRequestStatus& aStatus ) + { + IKESOCKET_ASSERT( iClientStatusReceive == NULL ); + IKESOCKET_ASSERT( iClientMsgReceive == NULL ); + IKESOCKET_ASSERT( iClientSrcAddrReceive == NULL ); + IKESOCKET_ASSERT( iClientLocalPort == NULL ); + + // Store client data. + iClientStatusReceive = &aStatus; + *iClientStatusReceive = KRequestPending; + iClientMsgReceive = &aUdpData; + iClientSrcAddrReceive = &aSrcAddr; + iClientLocalPort = &aLocalPort; + + if ( !iSocketsOpen ) + { + CompleteReceiveToClient( KErrDisconnected ); + return; + } + + iReceivingStopped = EFalse; + + TInt count = iReceiveQueue.Count(); + if ( count < KReceiveQueueMaxCount ) + { + ReceiveData(); + } + + if ( count ) + { + // Data is already available. + CompleteReceiveToClient( KErrNone ); + } + } + +// --------------------------------------------------------------------------- +// Cancels receive request. +// --------------------------------------------------------------------------- +// +void CDataTransfer::CancelReceive() + { + if ( iClientStatusReceive ) + { + CompleteReceiveToClient( KErrCancel ); + } + } + +// --------------------------------------------------------------------------- +// Clears available data. +// --------------------------------------------------------------------------- +// +void CDataTransfer::ClearReceivedData() + { + DEBUG_LOG( _L("CDataTransfer::ClearReceivedData") ); + + CleanupReceiveQueue(); + ReceiveData(); + } + +// --------------------------------------------------------------------------- +// Stops receiving. Available data is cleared. +// --------------------------------------------------------------------------- +// +void CDataTransfer::StopReceive() + { + DEBUG_LOG( _L("CDataTransfer::StopReceive") ); + + CleanupReceiveQueue(); + DoCancelReceive( KErrCancel ); + iReceivingStopped = ETrue; + } + +// --------------------------------------------------------------------------- +// Gets local IP address. +// --------------------------------------------------------------------------- +// +TInt CDataTransfer::GetLocalAddress( TInetAddr& aLocalIp ) + { + IKESOCKET_ASSERT( iIpVersion == EIPv4 || iIpVersion == EIPv6 ); + return iLocalAddressResolver.GetLocalAddress( iIpVersion, aLocalIp ); + } + +// --------------------------------------------------------------------------- +// Notification about completed send from sender. +// --------------------------------------------------------------------------- +// +void CDataTransfer::SendCompleted( const TInt aStatus ) + { + CompleteSendToClient( aStatus ); + } + +// --------------------------------------------------------------------------- +// Notification that data has been received. +// --------------------------------------------------------------------------- +// +void CDataTransfer::DataReceived( HBufC8* aUdpData, + const TInetAddr& aSrcAddr, + const TInt aLocalPort ) + { + // Store message to receive queue. + TReceiveQueueItem item( aUdpData, // Ownership transferred. + aSrcAddr, + aLocalPort ); + TInt err = iReceiveQueue.Append( item ); + + if ( iReceiveQueue.Count() >= KReceiveQueueMaxCount ) + { + // Queue is full. Cancel receiving. + iReceiver->CancelReceive(); + iReceiverNAT->CancelReceive(); + } + + if ( iClientStatusReceive ) + { + CompleteReceiveToClient( KErrNone ); + } + } + +// --------------------------------------------------------------------------- +// Notification about receive error. +// --------------------------------------------------------------------------- +// +void CDataTransfer::ReceiveError( const TInt aStatus ) + { + if ( iClientStatusReceive ) + { + CompleteReceiveToClient( aStatus ); + } + + StopReceive(); + + iErrorCallback.DataTransferError( aStatus, + MDataTransferCallback::EReceiveError ); + } + +// --------------------------------------------------------------------------- +// Opens socket. +// --------------------------------------------------------------------------- +// +TInt CDataTransfer::OpenSocket( RSocket& aSocket ) + { + TInt err = aSocket.Open( iSocketServer, + KAfInet, + KSockDatagram, + KProtocolInetUdp, + iConnection ); + if ( err == KErrNone ) + { + // Enable multiple binds to same port + err = aSocket.SetOpt( KSoReuseAddr, KSolInetIp, 1 ); + } + + return err; + } + +// --------------------------------------------------------------------------- +// Binds socket. +// --------------------------------------------------------------------------- +// +TInt CDataTransfer::BindSocket( RSocket& aSocket, + const TInetAddr& aLocalIp, + const TInt aLocalPort ) + { + TInt err( KErrNone ); + TInetAddr localAddr( aLocalIp ); + + localAddr.SetPort( aLocalPort ); + err = aSocket.Bind( localAddr ); + +#ifdef _DEBUG + TBuf<100> txt_addr; + aLocalIp.Output( txt_addr ); + DEBUG_LOG3( _L("Bind socket, address:port=%S:%d, err=%d"), + &txt_addr, aLocalPort, err ); +#endif + + return err; + } + +// --------------------------------------------------------------------------- +// Cancels sending. +// --------------------------------------------------------------------------- +// +void CDataTransfer::DoCancelSend( const TInt aCompletionStatus ) + { + iSender->Cancel(); + + if ( iClientStatusSend ) + { + CompleteSendToClient( aCompletionStatus ); + } + } + +// --------------------------------------------------------------------------- +// Cancels receiving. +// --------------------------------------------------------------------------- +// +void CDataTransfer::DoCancelReceive( const TInt aCompletionStatus ) + { + iReceiver->CancelReceive(); + iReceiverNAT->CancelReceive(); + + if ( iClientStatusReceive ) + { + CompleteReceiveToClient( aCompletionStatus ); + } + } + +// --------------------------------------------------------------------------- +// Completes send to client. +// --------------------------------------------------------------------------- +// +void CDataTransfer::CompleteSendToClient( const TInt aStatus ) + { + IKESOCKET_ASSERT( iClientStatusSend ); + + User::RequestComplete( iClientStatusSend, aStatus ); + iClientStatusSend = NULL; + } + +// --------------------------------------------------------------------------- +// Completes receive to client. +// --------------------------------------------------------------------------- +// +void CDataTransfer::CompleteReceiveToClient( const TInt aStatus ) + { + IKESOCKET_ASSERT( iClientStatusReceive ); + IKESOCKET_ASSERT( iClientMsgReceive ); + IKESOCKET_ASSERT( iClientSrcAddrReceive ); + IKESOCKET_ASSERT( iClientLocalPort ); + + TInt count = iReceiveQueue.Count(); + + if ( ( aStatus == KErrNone ) && count ) + { + // Get oldest item from receive queue. + TReceiveQueueItem item = iReceiveQueue[0]; + iReceiveQueue.Remove( 0 ); + *iClientMsgReceive = item.UdpData(); // Transfer ownership. + *iClientSrcAddrReceive = item.SrcAddr(); + *iClientLocalPort = item.LocalPort(); + + // Need to receive more data if queue was full. + ReceiveData(); + } + + // Complete receive. + User::RequestComplete( iClientStatusReceive, aStatus ); + iClientStatusReceive = NULL; + iClientMsgReceive = NULL; + iClientSrcAddrReceive = NULL; + iClientLocalPort = NULL; + } + +// --------------------------------------------------------------------------- +// Receives more data if receiving not requested to be stopped. +// --------------------------------------------------------------------------- +// +void CDataTransfer::ReceiveData() + { + if ( !iReceivingStopped ) + { + iReceiver->Receive(); + iReceiverNAT->Receive(); + } + } + +// --------------------------------------------------------------------------- +// Cleans up data from receive queue. +// --------------------------------------------------------------------------- +// +void CDataTransfer::CleanupReceiveQueue() + { + while ( iReceiveQueue.Count() ) + { + delete iReceiveQueue[0].UdpData(); + iReceiveQueue.Remove( 0 ); + } + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/src/ikeconnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/src/ikeconnection.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,551 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE socket connection +* +*/ + + +#include "ikeconnection.h" +#include "datatransfer.h" +#include "localaddressresolver.h" +#include "ikedebug.h" +#include "ikesocketassert.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CIkeConnection* CIkeConnection::NewL( MIkeDebug& aDebug ) + { + CIkeConnection* self = new (ELeave) CIkeConnection( aDebug ); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CIkeConnection::~CIkeConnection() + { + DEBUG_LOG1( _L("CIkeConnection::~CIkeConnection this=0x%x"), this ); + + if ( iDataTransfer ) + { + iDataTransfer->CloseSockets(); + } + + DoCancelResolveFQDNAddress(); + DoCancelStartConnection(); + + delete iLocalAddressResolver; + delete iDataTransfer; + delete iLinkObserver; + + iConnection.Close(); + iSocketServer.Close(); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CIkeConnection::CIkeConnection( MIkeDebug& aDebug ) + : CIkeConnectionInterface( EPriorityStandard ), + iState( EIdle ), + iExtendedPrefs(), + iDebug( aDebug ) + { + CActiveScheduler::Add( this ); // Added to the Active Scheduler + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CIkeConnection::ConstructL() + { + DEBUG_LOG1( _L("CIkeConnection::ConstructL, this=0x%x"), this ); + + User::LeaveIfError( iSocketServer.Connect() ); + iLocalAddressResolver = CLocalAddressResolver::NewL( iSocketServer, + iConnection, + iDebug ); + iDataTransfer = CDataTransfer::NewL( iSocketServer, + iConnection, + *iLocalAddressResolver, + *this, + iDebug ); + iLinkObserver = CConnObserver::NewL( iConnection, + *this, + iDebug ); + } + +// --------------------------------------------------------------------------- +// Opens data interface. +// --------------------------------------------------------------------------- +// +MIkeDataInterface& CIkeConnection::OpenDataInterfaceL( const TIkeMajorVersion aIkeMajorVersion, + const TIpVersion aIpVersion ) + { + IKESOCKET_ASSERT( aIpVersion == EIPv4 || aIpVersion == EIPv6 ); + DEBUG_LOG2( _L("CIkeConnection::OpenDataInterfaceL, IKE version=%d, IP version=%d"), + aIkeMajorVersion, aIpVersion ); + + // Store IP version. + iIpVersion = aIpVersion; + + // Get local IP address. + User::LeaveIfError( iLocalAddressResolver->RefreshLocalAddresses() ); + TBool hasIPAddr = iLocalAddressResolver->HasIPAddr( aIpVersion ); + if ( !hasIPAddr ) + { + User::Leave( KErrNotFound ); + } + TInetAddr localIp = iLocalAddressResolver->IPAddr( aIpVersion ); + + // Open sockets. + User::LeaveIfError( iDataTransfer->OpenSockets( localIp ) ); + + // Set IKE major version. + iDataTransfer->SetIkeMajorVersion( aIkeMajorVersion ); + + // Set IP version + iDataTransfer->SetIpVersion( aIpVersion ); + + DEBUG_LOG( _L("Data interface open.") ); + + // Return data interface. + return *iDataTransfer; + } + +// --------------------------------------------------------------------------- +// Starts connection. +// --------------------------------------------------------------------------- +// +void CIkeConnection::StartConnection( const TUint32 aIapId, + const TUint32 aSnapId, + TRequestStatus& aStatus, + const TBool aForcedRoaming ) + { + IKESOCKET_ASSERT( iState == EIdle ); + IKESOCKET_ASSERT( iClientStatus == NULL ); + + DEBUG_LOG3( _L("CIkeConnection::StartConnection, IAP id=%d, SNAP id=%d, forced roaming=%d"), + aIapId, aSnapId, aForcedRoaming ); + + iState = EConnecting; + + iClientStatus = &aStatus; + *iClientStatus = KRequestPending; + iIapId = aIapId; + iSnapId = aSnapId; + + TInt err( iConnection.Open( iSocketServer ) ); + + if ( err == KErrNone ) + { + // Start connection. + if ( iSnapId ) // SNAP + { + TRAP( err, CreateSnapPreferencesL( iSnapId, + aForcedRoaming ) ); + if ( err == KErrNone ) + { + iConnection.Start( iConnPrefList, iStatus ); + } + } + else // IAP + { + // Create preference overrides. + iPrefs.SetDialogPreference( ECommDbDialogPrefDoNotPrompt ); + iPrefs.SetIapId( iIapId ); + iConnection.Start( iPrefs, iStatus ); + } + } + + if ( err != KErrNone ) + { + TRequestStatus* ownStatus = &iStatus; + *ownStatus = KRequestPending; + SetActive(); + + User::RequestComplete( ownStatus, err ); + return; + } + + SetActive(); + } + +// --------------------------------------------------------------------------- +// Cancels connection starting. +// --------------------------------------------------------------------------- +// +void CIkeConnection::CancelStartConnection() + { + DEBUG_LOG( _L("CIkeConnection::CancelStartConnection") ); + + DoCancelStartConnection(); + } + +// --------------------------------------------------------------------------- +// Stops connection. +// --------------------------------------------------------------------------- +// +void CIkeConnection::StopConnection() + { + IKESOCKET_ASSERT( iLinkObserver ); + IKESOCKET_ASSERT( iDataTransfer ); + + DEBUG_LOG( _L("CIkeConnection::StopConnection") ); + + iLinkObserver->CancelNotify(); + + CancelResolveFQDNAddress(); + CancelStartConnection(); + + iDataTransfer->CloseSockets(); + iConnection.Close(); + + iState = EIdle; + } + +// --------------------------------------------------------------------------- +// Resolves FQDN address. +// --------------------------------------------------------------------------- +// +void CIkeConnection::ResolveFQDNAddress( const TDesC& aFQDN, + TNameEntry& aNameEntry, + TRequestStatus& aStatus ) + { + IKESOCKET_ASSERT( iState == EConnected ); + DEBUG_LOG1( _L("CIkeConnection::ResolveAddress, aFQDN=%S"), &aFQDN ); + + iState = EResolvingFQDN; + + iClientStatus = &aStatus; + *iClientStatus = KRequestPending; + + TInt err = iResolver.Open( iSocketServer, + KAfInet, + KProtocolInetUdp, + iConnection ); + + if ( err ) + { + TRequestStatus* ownStatus = &iStatus; + *ownStatus = KRequestPending; + SetActive(); + + User::RequestComplete( ownStatus, err ); + return; + } + + iResolver.GetByName( aFQDN, aNameEntry, iStatus ); + SetActive(); + } + +// --------------------------------------------------------------------------- +// Cancels FQDN address resolving. +// --------------------------------------------------------------------------- +// +void CIkeConnection::CancelResolveFQDNAddress() + { + DEBUG_LOG( _L("CIkeConnection::CancelResolveFQDNAddress") ); + + DoCancelResolveFQDNAddress(); + } + +// --------------------------------------------------------------------------- +// Request notification about disconnection. +// --------------------------------------------------------------------------- +// +void CIkeConnection::NotifyDisconnect( TRequestStatus& aStatus ) + { + IKESOCKET_ASSERT( iClientStatusNotifyDisconnect == NULL ); + DEBUG_LOG( _L("CIkeConnection::NotifyDisconnect") ); + + iClientStatusNotifyDisconnect = &aStatus; + *iClientStatusNotifyDisconnect = KRequestPending; + } + +// --------------------------------------------------------------------------- +// Cancels disconnect notification request. +// --------------------------------------------------------------------------- +// +void CIkeConnection::CancelNotifyDisconnect() + { + IKESOCKET_ASSERT( iClientStatusNotifyDisconnect ); + DEBUG_LOG( _L("CIkeConnection::CancelNotifyDisconnect") ); + + User::RequestComplete( iClientStatusNotifyDisconnect, KErrCancel ); + iClientStatusNotifyDisconnect = NULL; + } + +// --------------------------------------------------------------------------- +// Returns IAP id. +// --------------------------------------------------------------------------- +// +TUint32 CIkeConnection::IapId() const + { + return iIapId; + } + +// --------------------------------------------------------------------------- +// Returns Net id. +// --------------------------------------------------------------------------- +// +TUint32 CIkeConnection::NetId() const + { + return iNetId; + } + +// --------------------------------------------------------------------------- +// Returns SNAP id. +// --------------------------------------------------------------------------- +// +TUint32 CIkeConnection::SnapId() const + { + return iSnapId; + } + +// --------------------------------------------------------------------------- +// Gets local IP address. +// --------------------------------------------------------------------------- +// +TInt CIkeConnection::GetLocalAddress( const TIpVersion aIpVersion, + TInetAddr& aLocalIp ) + { + IKESOCKET_ASSERT( aIpVersion == EIPv4 || aIpVersion == EIPv6 ); + return iLocalAddressResolver->GetLocalAddress( aIpVersion, aLocalIp ); + } + +// --------------------------------------------------------------------------- +// Creates connection preferences for SNAP usage. Connection preferences +// list is constructed. +// --------------------------------------------------------------------------- +// +void CIkeConnection::CreateSnapPreferencesL( const TUint32 aSnapId, + const TBool aForcedRoaming ) + { + CleanSnapPreferences(); + + iExtendedPrefs.SetSnapId( aSnapId ); + iExtendedPrefs.SetForcedRoaming( aForcedRoaming ); + + iConnPrefList.AppendL( &iExtendedPrefs ); + } + +// --------------------------------------------------------------------------- +// Cleans connection preferences created for SNAP usage. +// --------------------------------------------------------------------------- +// +void CIkeConnection::CleanSnapPreferences() + { + while( iConnPrefList.Count() > 0 ) + { + iConnPrefList.Remove( 0 ); + } + } + +// --------------------------------------------------------------------------- +// Updates IAP id and NET id. +// --------------------------------------------------------------------------- +// +void CIkeConnection::UpdateRealIapData() + { + _LIT( KIapId, "IAP\\Id" ); + _LIT( KNetId, "IAP\\IAPNetwork" ); + + iConnection.GetIntSetting( KIapId, iIapId ); + iConnection.GetIntSetting( KNetId, iNetId ); + + DEBUG_LOG2( _L("CIkeConnection::UpdateRealIapData, IAP id=%d, NET id=%d"), + iIapId, iNetId ); + } + +// --------------------------------------------------------------------------- +// Handles completion of asynchronous request in EConnecting state. +// --------------------------------------------------------------------------- +// +void CIkeConnection::DoStateAfterConnecting() + { + IKESOCKET_ASSERT( iLinkObserver ); + IKESOCKET_ASSERT( iState == EConnecting ); + + CleanSnapPreferences(); + + TInt err( iStatus.Int() ); + + if ( err == KErrNone ) + { + // Update IAP and Net ids. + UpdateRealIapData(); + + // Start observing when link is disconnected. + iLinkObserver->NotifyDisconnect(); + + iState = EConnected; + } + else + { + iConnection.Close(); + iState = EIdle; + } + + User::RequestComplete( iClientStatus, err ); + iClientStatus = NULL; + } + +// --------------------------------------------------------------------------- +// Handles completion of asynchronous request in EResolvingFQDN state. +// --------------------------------------------------------------------------- +// +void CIkeConnection::DoStateAfterResolvingFQDN() + { + IKESOCKET_ASSERT( iState == EResolvingFQDN ); + + // Back to connected state. + iState = EConnected; + iResolver.Close(); + + User::RequestComplete( iClientStatus, iStatus.Int() ); + iClientStatus = NULL; + } + +// --------------------------------------------------------------------------- +// Implements cancellation of connection starting. +// --------------------------------------------------------------------------- +// +void CIkeConnection::DoCancelStartConnection() + { + if ( iState == EConnecting ) + { + IKESOCKET_ASSERT( iClientStatus ); + + Cancel(); + + iState = EIdle; + iConnection.Close(); + + CleanSnapPreferences(); + + User::RequestComplete( iClientStatus, KErrCancel ); + iClientStatus = NULL; + } + } + +// --------------------------------------------------------------------------- +// Implements cancellation of FQDN address resolving. +// --------------------------------------------------------------------------- +// +void CIkeConnection::DoCancelResolveFQDNAddress() + { + if ( iState == EResolvingFQDN ) + { + IKESOCKET_ASSERT( iClientStatus ); + + Cancel(); + + iState = EConnected; + iResolver.Close(); + + User::RequestComplete( iClientStatus, KErrCancel ); + iClientStatus = NULL; + } + } + +// --------------------------------------------------------------------------- +// From CActive +// Handles request completion event about asynchronous connection starting or +// FQDN address resolving. +// --------------------------------------------------------------------------- +// +void CIkeConnection::RunL() + { + DEBUG_LOG2( _L("CIkeConnection::RunL, iState=%d, iStatus=%d"), + iState, iStatus.Int() ); + + switch ( iState ) + { + case EConnecting: + DoStateAfterConnecting(); + break; + case EResolvingFQDN: + DoStateAfterResolvingFQDN(); + break; + default: + IKESOCKET_ASSERT( EFalse ); + break; + } + } + +// --------------------------------------------------------------------------- +// From CActive +// Implements cancellation of asynchronous connection starting or FQDN address +// resolving. +// --------------------------------------------------------------------------- +// +void CIkeConnection::DoCancel() + { + DEBUG_LOG1( _L("CIkeConnection::DoCancel, iState=%d"), + iState ); + + switch ( iState ) + { + case EConnecting: + iConnection.Stop(); + break; + case EResolvingFQDN: + iResolver.Cancel(); + break; + default: + IKESOCKET_ASSERT( EFalse ); + break; + } + } + +// --------------------------------------------------------------------------- +// Handles notifcation about fatal data transfer error. +// --------------------------------------------------------------------------- +// +void CIkeConnection::DataTransferError( const TInt aError, + const TErrorType /*aErrorType*/ ) + { + DEBUG_LOG1( _L("CIkeConnection::DataTransferError, aError=%d"), + aError ); + + // Disconnect link and notify client about disconnection. + LinkDisconnected( aError ); + } + +// --------------------------------------------------------------------------- +// Handles notifcation about link disconnection. +// --------------------------------------------------------------------------- +// +void CIkeConnection::LinkDisconnected( const TInt aStatus ) + { + // Stop connection. + StopConnection(); + + if ( iClientStatusNotifyDisconnect ) + { + User::RequestComplete( iClientStatusNotifyDisconnect, aStatus ); + iClientStatusNotifyDisconnect = NULL; + } + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/src/ikeconnectioninterface.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/src/ikeconnectioninterface.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE socket connection interface +* +*/ + + +#include +#include "ikeconnectioninterface.h" +#include "ikeconnection.h" + +// ======== MEMBER FUNCTIONS ======== + +EXPORT_C CIkeConnectionInterface* CIkeConnectionInterface::NewL( MIkeDebug& aDebug ) + { + return CIkeConnection::NewL( aDebug ); + } + +CIkeConnectionInterface::~CIkeConnectionInterface() + { + } + +CIkeConnectionInterface::CIkeConnectionInterface( TInt aPriority ) + : CActive( aPriority ) + { + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/src/localaddressresolver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/src/localaddressresolver.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,299 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Local address resolver +* +*/ + + +// INCLUDE FILES +#include "localaddressresolver.h" +#include "ikedebug.h" +#include "ikesocketassert.h" + +using namespace IkeSocket; + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CLocalAddressResolver* CLocalAddressResolver::NewL( RSocketServ& aSocketServer, + RConnection& aConnection, + MIkeDebug& aDebug ) + { + CLocalAddressResolver* self = + new ( ELeave ) CLocalAddressResolver( aSocketServer, + aConnection, + aDebug ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CLocalAddressResolver::~CLocalAddressResolver() + { + DEBUG_LOG( _L("CLocalAddressResolver::~CLocalAddressResolver") ); + } + +// --------------------------------------------------------------------------- +// Constructor +// --------------------------------------------------------------------------- +// +CLocalAddressResolver::CLocalAddressResolver( RSocketServ& aSocketServer, + RConnection& aConnection, + MIkeDebug& aDebug ) + : iSocketServer( aSocketServer ), + iConnection( aConnection ), + iDebug( aDebug ) + { + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CLocalAddressResolver::ConstructL() + { + DEBUG_LOG( _L("CLocalAddressResolver::ConstructL") ); + } + +// --------------------------------------------------------------------------- +// Return information whether local IP address has been resolved or not. +// --------------------------------------------------------------------------- +// +TBool CLocalAddressResolver::HasIPAddr( const TIpVersion aIpVersion ) const + { + IKESOCKET_ASSERT( aIpVersion == EIPv4 || aIpVersion == EIPv6 ); + + TBool hasIPAddr( EFalse ); + + if ( aIpVersion == EIPv4 && + !iIPv4Addr.IsUnspecified() ) + { + hasIPAddr = ETrue; + } + else if ( aIpVersion == EIPv6 && + !iIPv6Addr.IsUnspecified() ) + { + hasIPAddr = ETrue; + } + return hasIPAddr; + } + +// --------------------------------------------------------------------------- +// Returns local IP address. +// --------------------------------------------------------------------------- +// +const TInetAddr& CLocalAddressResolver::IPAddr( const TIpVersion aIpVersion ) const + { + IKESOCKET_ASSERT( aIpVersion == EIPv4 || aIpVersion == EIPv6 ); + + if ( aIpVersion == EIPv4) + { + return iIPv4Addr; + } + + return iIPv6Addr; + } + +// --------------------------------------------------------------------------- +// Refreshes local IP addresses for the connection +// --------------------------------------------------------------------------- +// +TInt CLocalAddressResolver::RefreshLocalAddresses() + { + // Get IAP Id of the connection + _LIT( KIapId, "IAP\\Id" ); + TInt ret = iConnection.GetIntSetting( KIapId, iIapId ) ; + + if ( ret == KErrNone ) + { + RSocket socket; + ret = socket.Open( iSocketServer, + KAfInet, + KSockDatagram, + KProtocolInetUdp, + iConnection ); + + // Initialize IP addresses + iIPv4Addr.Init( KAfInet ); + iIPv6Addr.Init( KAfInet ); + + if ( ret == KErrNone ) + { + // Begin enumeration of network interfaces. + TInt err = socket.SetOpt( KSoInetEnumInterfaces, + KSolInetIfCtrl ); + if ( err == KErrNone ) + { + // Return details of the first interface in the enumeration. + TPckgBuf details; + err = socket.GetOpt( KSoInetNextInterface, + KSolInetIfCtrl, + details ); + + while ( err == KErrNone ) + { + // Query IAP for the interface. + TPckgBuf query; + query().iName = details().iName; + err = socket.GetOpt( KSoInetIfQueryByName, + KSolInetIfQuery, + query ); + + if ( err == KErrNone ) + { + // Match information of the interface with the + // connection. + if ( Match( details(), query() ) ) + { + // Match found. Set local IP address if not yet + // set. + SetAddressIfNotSet( details().iAddress ); + } + } + // Return details of the next interface. If the interface + // has multiple addresses then details for each address + // are returned separately in the enumeration. + err = socket.GetOpt( KSoInetNextInterface, + KSolInetIfCtrl, + details ); + } + } + socket.Close(); + } + } + + DEBUG_LOG1( _L("CLocalAddressResolver::RefreshLocalAddresses, ret=%d"), ret ); + return ret; + } + +// --------------------------------------------------------------------------- +// Gets local IP address. +// --------------------------------------------------------------------------- +// +TInt CLocalAddressResolver::GetLocalAddress( const TIpVersion aIpVersion, + TInetAddr& aLocalIp ) + { + IKESOCKET_ASSERT( aIpVersion == EIPv4 || aIpVersion == EIPv6 ); + DEBUG_LOG1( _L("CLocalAddressResolver::GetLocalAddress, aIpVersion=%d"), + aIpVersion); + + TInt ret = RefreshLocalAddresses(); + + if ( ret ) + { + return ret; + } + + if ( HasIPAddr( aIpVersion ) ) + { + aLocalIp = IPAddr( aIpVersion ); + } + else + { + ret = KErrNotFound; + } + return ret; + } + +// --------------------------------------------------------------------------- +// Mathches information of an interface and the connection. +// --------------------------------------------------------------------------- +// +TBool CLocalAddressResolver::Match( + const TSoInetInterfaceInfo& aInfo, + const TSoInetIfQuery& aQuery ) const + { + TBool match = EFalse; + if ( !aInfo.iAddress.IsUnspecified() && + !aInfo.iAddress.IsLoopback() && + !aInfo.iAddress.IsLinkLocal() && + aQuery.iZone[1] == iIapId ) // Match IAPs of interface and connection + { + match = ETrue; + } + return match; + } + +// --------------------------------------------------------------------------- +// Sets local IP address if not set. +// --------------------------------------------------------------------------- +// +void CLocalAddressResolver::SetAddressIfNotSet( const TInetAddr& aAddr ) + { + TInetAddr addr = aAddr; + + if ( addr.Family() == KAfInet ) // IPv4 address + { + SetIPv4AddressIfNotSet( addr ); + } + else if ( addr.Family() == KAfInet6 ) + { + if ( addr.IsV4Mapped() ) // IPv4 mapped address + { + addr.ConvertToV4(); + SetIPv4AddressIfNotSet( addr ); + } + else // IPv6 address + { + SetIPv6AddressIfNotSet( addr ); + } + } + } + +// --------------------------------------------------------------------------- +// Sets local IPv4 address if not set. +// --------------------------------------------------------------------------- +// +void CLocalAddressResolver::SetIPv4AddressIfNotSet( const TInetAddr& aAddr ) + { + if ( iIPv4Addr.IsUnspecified() ) + { +#ifdef _DEBUG + TBuf<100> txt_addr; + aAddr.Output( txt_addr ); + DEBUG_LOG1( _L("CLocalAddressResolver::SetIPv4AddressIfNotSet, address=%S"), + &txt_addr ); +#endif + + iIPv4Addr = aAddr; + } + } + +// --------------------------------------------------------------------------- +// Sets local IPv6 address if not set. +// --------------------------------------------------------------------------- +// +void CLocalAddressResolver::SetIPv6AddressIfNotSet( const TInetAddr& aAddr ) + { + if ( iIPv6Addr.IsUnspecified() ) + { +#ifdef _DEBUG + TBuf<100> txt_addr; + aAddr.Output( txt_addr ); + DEBUG_LOG1( _L("CLocalAddressResolver::SetIPv6AddressIfNotSet, address=%S"), + &txt_addr ); +#endif + + iIPv6Addr = aAddr; + } + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/src/receivequeueitem.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/src/receivequeueitem.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Receive queue item +* +*/ + + +// INCLUDE FILES +#include "receivequeueitem.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Constructor +// --------------------------------------------------------------------------- +// +TReceiveQueueItem::TReceiveQueueItem( HBufC8* aUdpData, + const TInetAddr& aSrcAddr, + const TInt aLocalPort ) + : iUdpData( aUdpData ), + iSrcAddr( aSrcAddr ), + iLocalPort( aLocalPort ) + { + } + +// --------------------------------------------------------------------------- +// Returns UDP data. +// --------------------------------------------------------------------------- +// +HBufC8* TReceiveQueueItem::UdpData() const + { + return iUdpData; + } + +// --------------------------------------------------------------------------- +// Returns source address. +// --------------------------------------------------------------------------- +// +const TInetAddr& TReceiveQueueItem::SrcAddr() const + { + return iSrcAddr; + } + +// --------------------------------------------------------------------------- +// Returns local port. +// --------------------------------------------------------------------------- +// +TInt TReceiveQueueItem::LocalPort() const + { + return iLocalPort; + } + + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/src/receiver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/src/receiver.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,365 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Receiver for UDP data +* +*/ + + +#include +#include "receiver.h" +#include "ikemsgheader.h" +#include "ikev2const.h" +#include "ikesocketdefs.h" +#include "ikedebug.h" +#include "ikesocketassert.h" + +using namespace IkeSocket; + +const TInt KMaxIkePacketSize( 65536 ); // Maximum size for UDP packet + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CReceiver* CReceiver::NewL( RSocket& aSocket, + MReceiverCallback& aCallback, + MIkeDebug& aDebug ) + { + CReceiver* self = new (ELeave) CReceiver( aSocket, + aCallback, + aDebug ); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CReceiver::~CReceiver() + { + DEBUG_LOG( _L("CReceiver::~CReceiver") ); + Cancel(); + delete iMsg; + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CReceiver::CReceiver( RSocket& aSocket, + MReceiverCallback& aCallback, + MIkeDebug& aDebug ) + : CActive( EPriorityStandard ), + iState( EIdle ), + iMsgPtr( 0, 0, 0 ), + iSocket( aSocket ), + iCallback( aCallback ), + iDebug( aDebug ) + { + CActiveScheduler::Add( this ); // Added to the Active Scheduler + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CReceiver::ConstructL() + { + DEBUG_LOG( _L("CReceiver::ConstructL") ); + } + +// --------------------------------------------------------------------------- +// Sets IKE major version. +// --------------------------------------------------------------------------- +// +void CReceiver::SetIkeMajorVersion( const TIkeMajorVersion aIkeMajorVersion ) + { + IKESOCKET_ASSERT( aIkeMajorVersion == EIkeMajorV1 || + aIkeMajorVersion == EIkeMajorV2 ); + + iIkeMajorVersion = aIkeMajorVersion; + } + +// --------------------------------------------------------------------------- +// Starts receive. +// --------------------------------------------------------------------------- +// +void CReceiver::Receive() + { + IKESOCKET_ASSERT( iIkeMajorVersion == EIkeMajorV1 || + iIkeMajorVersion == EIkeMajorV2 ); + + if ( iState == EIdle ) + { + WaitDataAvailable(); + } + } + +// --------------------------------------------------------------------------- +// Cancels receive. +// --------------------------------------------------------------------------- +// +void CReceiver::CancelReceive() + { + Cancel(); + + delete iMsg; + iMsg = NULL; + iMsgPtr.Set( 0, 0, 0 ); + + iState = EIdle; + } + +// --------------------------------------------------------------------------- +// Waits for data to become available for reading. +// --------------------------------------------------------------------------- +// +void CReceiver::WaitDataAvailable() + { + IKESOCKET_ASSERT( iState == EIdle ); + IKESOCKET_ASSERT( !IsActive() ); + + iState = EWaitingData; + delete iMsg; + iMsg = NULL; + + iFlags() = KSockSelectRead | KSockSelectExcept; + + iSocket.Ioctl( KIOctlSelect, + iStatus, + &iFlags, + KSOLSocket ); + SetActive(); + } + +// --------------------------------------------------------------------------- +// Receives data from socket. +// --------------------------------------------------------------------------- +// +void CReceiver::ReceiveDataL() + { + IKESOCKET_ASSERT( !IsActive() ); + + iState = EReceiving; + + TInt bytesPending( 0 ); + TInt err = iSocket.GetOpt( KSOReadBytesPending, + KSOLSocket, + bytesPending ); + + User::LeaveIfError( err ); + + if ( bytesPending > KMaxIkePacketSize ) + { + // KMaxIkePacketSize (65536) is max message size supported. + bytesPending = KMaxIkePacketSize; + } + + iMsg = HBufC8::NewL( bytesPending ); + iMsgPtr.Set( iMsg->Des() ); + + iSocket.RecvFrom( iMsgPtr, + iSrcAddr, + 0, + iStatus ); + SetActive(); + } + +// --------------------------------------------------------------------------- +// Handles receive of data. +// --------------------------------------------------------------------------- +// +void CReceiver::HandleDataReceivedL() + { +#ifdef _DEBUG + TBuf<100> txt_addr; + iSrcAddr.Output( txt_addr ); + TUint32 port = iSrcAddr.Port(); + DEBUG_LOG3( _L("CReceiver::HandleDataReceivedL, local port=%d, src address:port=%S:%d"), + iSocket.LocalPort(), &txt_addr, port ); +#endif + + TInt msgLength = iMsgPtr.Length(); + if ( msgLength <= TInt(ISAKMP_HDR_SIZE) ) + { + // Message size smaller than header size. + User::Leave( KErrArgument ); + } + + // Check if is in the beginning of IKE message. + // is related to the NAT traversal and it should + // exist only if IKE messages received through port 4500. + // However, we accept also in IKE message + // received through normal IKE port (500). + const ThdrISAKMP* ikeHdr = ThdrISAKMP::Ptr( iMsgPtr ); + TUint32 octets = BigEndian::Get32( (TUint8*)(ikeHdr) ); + TBool nonEspMarker = ( octets == NON_ESP_MARKER ); + if ( nonEspMarker ) + { + ikeHdr = ikeHdr->GotoOffset( NON_ESP_MARKER_SIZE ); + msgLength -= NON_ESP_MARKER_SIZE; + if ( msgLength <= TInt(ISAKMP_HDR_SIZE) ) + { + // Message size smaller than header size. + User::Leave( KErrArgument ); + } + } + + // Because the received data can be any UDP data transmitted to + // IKE port(s), some checks are done before packet is processed. Length + // value read from header must be greater than ISAKMP_HDR_SIZE. + TInt ikeMsgLength = ikeHdr->GetLength(); + if ( ikeMsgLength <= TInt(ISAKMP_HDR_SIZE) ) + { + User::Leave( KErrArgument ); + } + + // IKE major version in packet MUST be as client expects (1 or 2). + TUint8 majorVersion = ikeHdr->GetMajorVersion(); + if ( majorVersion != iIkeMajorVersion ) + { + User::Leave( KErrArgument ); + } + + NotifyDataReceived(); + } + +// --------------------------------------------------------------------------- +// Handles error in receiving. +// --------------------------------------------------------------------------- +// +void CReceiver::HandleError( const TInt aStatus ) + { + DEBUG_LOG1( _L("CReceiver::HandleError, aStatus=%d"), aStatus ); + + delete iMsg; + iMsg = NULL; + iMsgPtr.Set( 0, 0, 0 ); + iState = EIdle; + + if ( aStatus == KErrDied || + aStatus == KErrServerTerminated || + aStatus == KErrNoMemory ) + { + // Fatal error. Notify client. + iCallback.ReceiveError( aStatus ); + } + else + { + // Error is not fatal. Restart receiving + Receive(); + } + } + +// --------------------------------------------------------------------------- +// Notifies client that data has been received. +// --------------------------------------------------------------------------- +// +void CReceiver::NotifyDataReceived() + { + TInetAddr srcAddr = iSrcAddr; + TInt localPort = iSocket.LocalPort(); + HBufC8* msg = iMsg; + + iMsg = NULL; + iMsgPtr.Set( 0, 0, 0 ); + iState = EIdle; + + // Continue receiving. + Receive(); + + iCallback.DataReceived( msg, // Ownership transferred + srcAddr, + localPort ); + } + +// --------------------------------------------------------------------------- +// From CActive +// Handles a leave occurring in RunL(). +// --------------------------------------------------------------------------- +// +TInt CReceiver::RunError( TInt aError ) + { + HandleError( aError ); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// From CActive +// Handles request completion event about available data or received data. +// --------------------------------------------------------------------------- +// +void CReceiver::RunL() + { + IKESOCKET_ASSERT( iState == EWaitingData || + iState == EReceiving ); + DEBUG_LOG2( _L("CReceiver::RunL, iState=%d, iStatus=%d"), + iState, iStatus.Int() ); + + if ( iStatus.Int() ) + { + HandleError( iStatus.Int() ); + return; + } + + switch ( iState ) + { + case EWaitingData: + { + ReceiveDataL(); + break; + } + case EReceiving: + { + HandleDataReceivedL(); + break; + } + default: + break; + } + } + +// --------------------------------------------------------------------------- +// From CActive +// Implements cancellation of an active request. +// --------------------------------------------------------------------------- +// +void CReceiver::DoCancel() + { + IKESOCKET_ASSERT( iState == EWaitingData || + iState == EReceiving ); + DEBUG_LOG1( _L("CReceiver::DoCancel, iState=%d"), + iState ); + + switch ( iState ) + { + case EWaitingData: + { + iSocket.CancelIoctl(); + break; + } + case EReceiving: + { + iSocket.CancelRecv(); + break; + } + default: + break; + } + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikesocket/src/sender.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikesocket/src/sender.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,171 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Sender for UDP data +* +*/ + + +#include "sender.h" +#include "ikesocketdefs.h" +#include "ikedebug.h" + +using namespace IkeSocket; + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CSender* CSender::NewL( RSocket& aSocket, + RSocket& aSocketNAT, + RSocket& aSocketNokiaNAT, + MSenderCallback& aCallback, + MIkeDebug& aDebug ) + { + CSender* self = new (ELeave) CSender( aSocket, + aSocketNAT, + aSocketNokiaNAT, + aCallback, + aDebug ); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CSender::~CSender() + { + DEBUG_LOG( _L("CSender::~CSender") ); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CSender::CSender( RSocket& aSocket, + RSocket& aSocketNAT, + RSocket& aSocketNokiaNAT, + MSenderCallback& aCallback, + MIkeDebug& aDebug ) + : CActive( EPriorityStandard ), + iSocket( aSocket ), + iSocketNAT( aSocketNAT ), + iSocketNokiaNAT( aSocketNokiaNAT ), + iCallback( aCallback ), + iDebug( aDebug ) + { + CActiveScheduler::Add( this ); // Added to the Active Scheduler + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CSender::ConstructL() + { + DEBUG_LOG( _L("CSender::ConstructL") ); + } + +// --------------------------------------------------------------------------- +// Sends UDP data. +// --------------------------------------------------------------------------- +// +TInt CSender::SendUdpData( const TInt aLocalPort, + const TInetAddr& aDestAddr, + const TDesC8& aUdpData, + const TUint aDscp ) + { + RSocket* socket = NULL; + iLocalPort = aLocalPort; + iDestAddr = aDestAddr; + + if ( iLocalPort == 500 ) + { + socket = &iSocket; + } + else if ( iLocalPort == 4500 ) + { + socket = &iSocketNAT; + } + else + { + socket = &iSocketNokiaNAT; + } + + TInt err = socket->SetOpt( KSoIpTOS, KSolInetIp, aDscp ); + + if ( err == KErrNone ) + { + err = socket->SetOpt( KSoUdpSynchronousSend, KSolInetUdp, 1 ); + } + + if ( err == KErrNone ) + { + socket->SendTo( aUdpData, iDestAddr, 0, iStatus ); + SetActive(); + } + +#ifdef _DEBUG + TBuf<100> txt_addr; + iDestAddr.Output( txt_addr ); + TUint32 port = iDestAddr.Port(); + DEBUG_LOG3( _L("Sending UDP data, local port=%d, dest address:port=%S:%d"), + iLocalPort, &txt_addr, port ); + DEBUG_LOG2( _L(" DSCP=%d, err=%d"), aDscp, err ); +#endif + + return err; + } + +// --------------------------------------------------------------------------- +// From CActive +// Handles request completion event about sending. +// --------------------------------------------------------------------------- +// +void CSender::RunL() + { + DEBUG_LOG1( _L("CSender::RunL, iStatus=%d"), + iStatus.Int() ); + + iCallback.SendCompleted( iStatus.Int() ); + } + +// --------------------------------------------------------------------------- +// From CActive +// Implements cancellation of sending. +// --------------------------------------------------------------------------- +// +void CSender::DoCancel() + { + DEBUG_LOG1( _L("CSender::DoCancel, iLocalPort=%d"), + iLocalPort ); + + if ( iLocalPort == KIkePort500 ) + { + iSocket.CancelSend(); + } + else if ( iLocalPort == KIkePort4500 ) + { + iSocketNAT.CancelSend(); + } + else + { + iSocketNokiaNAT.CancelSend(); + } + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/bwins/ikeutilsu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/bwins/ikeutilsu.def Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,31 @@ +EXPORTS + ?CopyL@CInternalAddress@@QAEXABV1@@Z @ 1 NONAME ; void CInternalAddress::CopyL(class CInternalAddress const &) + ?Match@TIkeSendQueueItem@@SAHABV1@0@Z @ 2 NONAME ; int TIkeSendQueueItem::Match(class TIkeSendQueueItem const &, class TIkeSendQueueItem const &) + ?AddSAL@CPFKeySocketIf@@QAEXABVTIpsecSAData@@@Z @ 3 NONAME ; void CPFKeySocketIf::AddSAL(class TIpsecSAData const &) + ?NewL@CInternalAddress@@SAPAV1@ABV1@@Z @ 4 NONAME ; class CInternalAddress * CInternalAddress::NewL(class CInternalAddress const &) + ??0TIpsecSAData@@QAE@XZ @ 5 NONAME ; TIpsecSAData::TIpsecSAData(void) + ?UdpData@TIkeSendQueueItem@@QAEPAVHBufC8@@XZ @ 6 NONAME ; class HBufC8 * TIkeSendQueueItem::UdpData(void) + ?Dscp@TIkeSendQueueItem@@QBEEXZ @ 7 NONAME ; unsigned char TIkeSendQueueItem::Dscp(void) const + ?UpdateSAL@CPFKeySocketIf@@QAEXABVTIpsecSAData@@@Z @ 8 NONAME ; void CPFKeySocketIf::UpdateSAL(class TIpsecSAData const &) + ??0CIpsecSaSpecList@@QAE@XZ @ 9 NONAME ; CIpsecSaSpecList::CIpsecSaSpecList(void) + ??4TIpsecSALifetime@@QAEAAV0@ABV0@@Z @ 10 NONAME ; class TIpsecSALifetime & TIpsecSALifetime::operator=(class TIpsecSALifetime const &) + ?Address@TPfkeyAddress@@QBEABVTInetAddr@@XZ @ 11 NONAME ; class TInetAddr const & TPfkeyAddress::Address(void) const + ??0CInternalAddress@@QAE@H@Z @ 12 NONAME ; CInternalAddress::CInternalAddress(int) + ?NewL@CIpsecPolicyUtil@@SAPAV1@XZ @ 13 NONAME ; class CIpsecPolicyUtil * CIpsecPolicyUtil::NewL(void) + ?BuildVPNAddrInfo@VPNAddrInfo@@SAXPBVCInternalAddress@@ABVTInetAddr@@AAVTVPNAddress@@AAVMIkeDebug@@@Z @ 14 NONAME ; void VPNAddrInfo::BuildVPNAddrInfo(class CInternalAddress const *, class TInetAddr const &, class TVPNAddress &, class MIkeDebug &) + ?NewL@CPFKeySocketIf@@SAPAV1@PAVMPFKeyMessageListener@@AAVMIkeDebug@@@Z @ 15 NONAME ; class CPFKeySocketIf * CPFKeySocketIf::NewL(class MPFKeyMessageListener *, class MIkeDebug &) + ?BuildUdpEncExtensionData@PFKeyExtDataUtil@@SAXAAVTDes8@@KHHGGABVTInetAddr@@1@Z @ 16 NONAME ; void PFKeyExtDataUtil::BuildUdpEncExtensionData(class TDes8 &, unsigned long, int, int, unsigned short, unsigned short, class TInetAddr const &, class TInetAddr const &) + ??0TIpsecSALifetime@@QAE@KAB_J00@Z @ 17 NONAME ; TIpsecSALifetime::TIpsecSALifetime(unsigned long, long long const &, long long const &, long long const &) + ??0TIkeSendQueueItem@@QAE@PAVHBufC8@@@Z @ 18 NONAME ; TIkeSendQueueItem::TIkeSendQueueItem(class HBufC8 *) + ?SelectorCount@TPfkeyTs@@QBEHXZ @ 19 NONAME ; int TPfkeyTs::SelectorCount(void) const + ?GetIpsecSaSpi@CIpsecSaSpiRetriever@@QAEXKEABVTInetAddr@@0@Z @ 20 NONAME ; void CIpsecSaSpiRetriever::GetIpsecSaSpi(unsigned long, unsigned char, class TInetAddr const &, class TInetAddr const &) + ??0TIkeSendQueueItem@@QAE@PAVHBufC8@@ABVTInetAddr@@HE@Z @ 21 NONAME ; TIkeSendQueueItem::TIkeSendQueueItem(class HBufC8 *, class TInetAddr const &, int, unsigned char) + ?AcquireSAError@CPFKeySocketIf@@QAEXABVTIpsecSAData@@H@Z @ 22 NONAME ; void CPFKeySocketIf::AcquireSAError(class TIpsecSAData const &, int) + ?DeleteSA@CPFKeySocketIf@@QAEXKABVTInetAddr@@0E@Z @ 23 NONAME ; void CPFKeySocketIf::DeleteSA(unsigned long, class TInetAddr const &, class TInetAddr const &, unsigned char) + ?Selector@TPfkeyTs@@QBEABVTPfKeySelector@@H@Z @ 24 NONAME ; class TPfKeySelector const & TPfkeyTs::Selector(int) const + ?LocalPort@TIkeSendQueueItem@@QBEHXZ @ 25 NONAME ; int TIkeSendQueueItem::LocalPort(void) const + ?FlushSAs@CPFKeySocketIf@@QAEXXZ @ 26 NONAME ; void CPFKeySocketIf::FlushSAs(void) + ?NewL@CIpsecSaSpiRetriever@@SAPAV1@AAVMIpsecSaSpiRetrieverCallback@@AAVCPFKeySocketIf@@@Z @ 27 NONAME ; class CIpsecSaSpiRetriever * CIpsecSaSpiRetriever::NewL(class MIpsecSaSpiRetrieverCallback &, class CPFKeySocketIf &) + ?GetIpseSaSpecListLC@CIpsecPolicyUtil@@QAEPAVCIpsecSaSpecList@@VTInetAddr@@000HK@Z @ 28 NONAME ; class CIpsecSaSpecList * CIpsecPolicyUtil::GetIpseSaSpecListLC(class TInetAddr, class TInetAddr, class TInetAddr, class TInetAddr, int, unsigned long) + ?DestAddr@TIkeSendQueueItem@@QAEABVTInetAddr@@XZ @ 29 NONAME ; class TInetAddr const & TIkeSendQueueItem::DestAddr(void) + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/eabi/ikeutilsu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/eabi/ikeutilsu.def Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,49 @@ +EXPORTS + _ZN11VPNAddrInfo16BuildVPNAddrInfoEPK16CInternalAddressRK9TInetAddrR11TVPNAddressR9MIkeDebug @ 1 NONAME + _ZN12TIpsecSADataC1Ev @ 2 NONAME + _ZN12TIpsecSADataC2Ev @ 3 NONAME + _ZN14CPFKeySocketIf14AcquireSAErrorERK12TIpsecSADatai @ 4 NONAME + _ZN14CPFKeySocketIf4NewLEP21MPFKeyMessageListenerR9MIkeDebug @ 5 NONAME + _ZN14CPFKeySocketIf6AddSALERK12TIpsecSAData @ 6 NONAME + _ZN14CPFKeySocketIf8DeleteSAEmRK9TInetAddrS2_h @ 7 NONAME + _ZN14CPFKeySocketIf8FlushSAsEv @ 8 NONAME + _ZN14CPFKeySocketIf9UpdateSALERK12TIpsecSAData @ 9 NONAME + _ZN16CInternalAddress4NewLERKS_ @ 10 NONAME + _ZN16CInternalAddress5CopyLERKS_ @ 11 NONAME + _ZN16CInternalAddressC1Ei @ 12 NONAME + _ZN16CInternalAddressC2Ei @ 13 NONAME + _ZN16CIpsecPolicyUtil19GetIpseSaSpecListLCE9TInetAddrS0_S0_S0_im @ 14 NONAME + _ZN16CIpsecPolicyUtil4NewLEv @ 15 NONAME + _ZN16CIpsecSaSpecListC1Ev @ 16 NONAME + _ZN16CIpsecSaSpecListC2Ev @ 17 NONAME + _ZN16PFKeyExtDataUtil24BuildUdpEncExtensionDataER5TDes8miittRK9TInetAddrS4_ @ 18 NONAME + _ZN16TIpsecSALifetimeC1EmRKxS1_S1_ @ 19 NONAME + _ZN16TIpsecSALifetimeC2EmRKxS1_S1_ @ 20 NONAME + _ZN16TIpsecSALifetimeaSERKS_ @ 21 NONAME + _ZN17TIkeSendQueueItem5MatchERKS_S1_ @ 22 NONAME + _ZN17TIkeSendQueueItem7UdpDataEv @ 23 NONAME + _ZN17TIkeSendQueueItem8DestAddrEv @ 24 NONAME + _ZN17TIkeSendQueueItemC1EP6HBufC8 @ 25 NONAME + _ZN17TIkeSendQueueItemC1EP6HBufC8RK9TInetAddrih @ 26 NONAME + _ZN17TIkeSendQueueItemC2EP6HBufC8 @ 27 NONAME + _ZN17TIkeSendQueueItemC2EP6HBufC8RK9TInetAddrih @ 28 NONAME + _ZN20CIpsecSaSpiRetriever13GetIpsecSaSpiEmhRK9TInetAddrS2_ @ 29 NONAME + _ZN20CIpsecSaSpiRetriever4NewLER28MIpsecSaSpiRetrieverCallbackR14CPFKeySocketIf @ 30 NONAME + _ZNK13TPfkeyAddress7AddressEv @ 31 NONAME + _ZNK17TIkeSendQueueItem4DscpEv @ 32 NONAME + _ZNK17TIkeSendQueueItem9LocalPortEv @ 33 NONAME + _ZNK8TPfkeyTs13SelectorCountEv @ 34 NONAME + _ZNK8TPfkeyTs8SelectorEi @ 35 NONAME + _ZTI14CPFKeySocketIf @ 36 NONAME + _ZTI16CInternalAddress @ 37 NONAME + _ZTI16CIpsecPolicyUtil @ 38 NONAME + _ZTI19TPfkeySupportedAuth @ 39 NONAME + _ZTI20CIpsecSaSpiRetriever @ 40 NONAME + _ZTI22TPfkeySupportedEncrypt @ 41 NONAME + _ZTV14CPFKeySocketIf @ 42 NONAME + _ZTV16CInternalAddress @ 43 NONAME + _ZTV16CIpsecPolicyUtil @ 44 NONAME + _ZTV19TPfkeySupportedAuth @ 45 NONAME + _ZTV20CIpsecSaSpiRetriever @ 46 NONAME + _ZTV22TPfkeySupportedEncrypt @ 47 NONAME + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Build information file + +* +*/ + + + +#include + + + +PRJ_PLATFORMS + + + +PRJ_EXPORTS + + + +PRJ_MMPFILES + +ikeutils.mmp + + + +PRJ_TESTMMPFILES + + + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/group/ikeutils.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/group/ikeutils.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project ikeutils +* +*/ + +#include + +TARGET ikeutils.dll +TARGETTYPE dll + +UID 0x1000008d 0x2001E609 +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE ikesendqueueitem.cpp +SOURCE internaladdress.cpp +SOURCE ipsecpolicyutil.cpp +SOURCE ipsecsadata.cpp +SOURCE ipsecsalifetime.cpp +SOURCE ipsecsalist.cpp +SOURCE ipsecsaspiretriever.cpp +SOURCE pfkeyextdatautil.cpp +SOURCE pfkeymsg.cpp +SOURCE pfkeysocketif.cpp +SOURCE vpnaddrinfo.cpp + +USERINCLUDE . +USERINCLUDE ../inc +USERINCLUDE ../../kmdserver/inc +USERINCLUDE ../../vpnmanager/inc + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY esock.lib +LIBRARY euser.lib +LIBRARY insock.lib +LIBRARY ipsecpolapi.lib +LIBRARY lib_pfkey.lib +LIBRARY random.lib + +CAPABILITY ALL -Tcb diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/inc/dhparameters.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/inc/dhparameters.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,146 @@ +/* +* Copyright (c) 2003-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Prime and generator values for modular Diffie-Hellman groups +* +*/ + + + +#ifndef _DH_PARAMETERS_H_ +#define _DH_PARAMETERS_H_ + +#include + + +//Group 1 +//Equivalent to FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 +// 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD +// EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 +// E485B576 625E7EC6 F44C42E9 A63A3620 FFFFFFFF FFFFFFFF +#define MODP_768_PRIME_LENGTH 96 //bytes TUint8 (2 hex each) + +const TUint8 MODP_768_PRIME[MODP_768_PRIME_LENGTH] = + {255,255,255,255, 255,255,255,255, 201,15,218,162, 33,104,194,52, + 196,198,98,139, 128,220,28,209, 41,2,78,8, 138,103,204,116, + 2,11,190,166, 59,19,155,34, 81,74,8,121, 142,52,4,221, + 239,149,25,179, 205,58,67,27, 48,43,10,109, 242,95,20,55, + 79,225,53,109, 109,81,194,69, 228,133,181,118, 98,94,126,198, + 244,76,66,233, 166,58,54,32, 255,255,255,255, 255,255,255,255}; + +#define MODP_768_GENERATOR_LENGTH 1 //TUint characters +const TUint8 MODP_768_GENERATOR[MODP_768_GENERATOR_LENGTH]={2}; + + +//Group 2 +//Equivalent to FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 +// 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD +// EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 +// E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED +// EE386bFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 +// FFFFFFFF FFFFFFFF +#define MODP_1024_PRIME_LENGTH 128 //bytes TUint8 (2 hex each) + +const TUint8 MODP_1024_PRIME[MODP_1024_PRIME_LENGTH] = + {0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF ,0xC9,0x0F,0xDA,0xA2 + ,0x21,0x68,0xC2,0x34 ,0xC4,0xC6,0x62,0x8B ,0x80,0xDC,0x1C,0xD1 + ,0x29,0x02,0x4E,0x08 ,0x8A,0x67,0xCC,0x74 ,0x02,0x0B,0xBE,0xA6 + ,0x3B,0x13,0x9B,0x22 ,0x51,0x4A,0x08,0x79 ,0x8E,0x34,0x04,0xDD + ,0xEF,0x95,0x19,0xB3 ,0xCD,0x3A,0x43,0x1B ,0x30,0x2B,0x0A,0x6D + ,0xF2,0x5F,0x14,0x37 ,0x4F,0xE1,0x35,0x6D ,0x6D,0x51,0xC2,0x45 + ,0xE4,0x85,0xB5,0x76 ,0x62,0x5E,0x7E,0xC6 ,0xF4,0x4C,0x42,0xE9 + ,0xA6,0x37,0xED,0x6B ,0x0B,0xFF,0x5C,0xB6 ,0xF4,0x06,0xB7,0xED + ,0xEE,0x38,0x6b,0xFB ,0x5A,0x89,0x9F,0xA5 ,0xAE,0x9F,0x24,0x11 + ,0x7C,0x4B,0x1F,0xE6 ,0x49,0x28,0x66,0x51 ,0xEC,0xE6,0x53,0x81 + ,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF }; + +#define MODP_1024_GENERATOR_LENGTH 1 //TUint characters +const TUint8 MODP_1024_GENERATOR[MODP_1024_GENERATOR_LENGTH]={2}; + + +//Group 5 +//Equivalent to FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 +// 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD +// EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 +// E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED +// EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D +// C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F +// 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D +// 670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF +#define MODP_1536_PRIME_LENGTH 192 //bytes TUint8 (2 hex each) + +const TUint8 MODP_1536_PRIME[MODP_1536_PRIME_LENGTH] = + {0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF ,0xC9,0x0F,0xDA,0xA2 + ,0x21,0x68,0xC2,0x34 ,0xC4,0xC6,0x62,0x8B ,0x80,0xDC,0x1C,0xD1 + ,0x29,0x02,0x4E,0x08 ,0x8A,0x67,0xCC,0x74 ,0x02,0x0B,0xBE,0xA6 + ,0x3B,0x13,0x9B,0x22 ,0x51,0x4A,0x08,0x79 ,0x8E,0x34,0x04,0xDD + ,0xEF,0x95,0x19,0xB3 ,0xCD,0x3A,0x43,0x1B ,0x30,0x2B,0x0A,0x6D + ,0xF2,0x5F,0x14,0x37 ,0x4F,0xE1,0x35,0x6D ,0x6D,0x51,0xC2,0x45 + ,0xE4,0x85,0xB5,0x76 ,0x62,0x5E,0x7E,0xC6 ,0xF4,0x4C,0x42,0xE9 + ,0xA6,0x37,0xED,0x6B ,0x0B,0xFF,0x5C,0xB6 ,0xF4,0x06,0xB7,0xED + ,0xEE,0x38,0x6b,0xFB ,0x5A,0x89,0x9F,0xA5 ,0xAE,0x9F,0x24,0x11 + ,0x7C,0x4B,0x1F,0xE6 ,0x49,0x28,0x66,0x51 ,0xEC,0xE4,0x5B,0x3D + ,0xC2,0x00,0x7C,0xB8 ,0xA1,0x63,0xBF,0x05 ,0x98,0xDA,0x48,0x36 + ,0x1C,0x55,0xD3,0x9A ,0x69,0x16,0x3F,0xA8 ,0xFD,0x24,0xCF,0x5F + ,0x83,0x65,0x5D,0x23 ,0xDC,0xA3,0xAD,0x96 ,0x1C,0x62,0xF3,0x56 + ,0x20,0x85,0x52,0xBB ,0x9E,0xD5,0x29,0x07 ,0x70,0x96,0x96,0x6D + ,0x67,0x0C,0x35,0x4E ,0x4A,0xBC,0x98,0x04 ,0xF1,0x74,0x6C,0x08 + ,0xCA,0x23,0x73,0x27, 0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF }; + +#define MODP_1536_GENERATOR_LENGTH 1 //TUint characters +const TUint8 MODP_1536_GENERATOR[MODP_1536_GENERATOR_LENGTH]={2}; + + +//Group 14 +//Equivalent to FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 +// 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD +// EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 +// E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED +// EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D +// C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F +// 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D +// 670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B +// E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 +// DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510 +// 15728E5A 8AACAA68 FFFFFFFF FFFFFFFF +#define MODP_2048_PRIME_LENGTH 256 + +const TUint8 MODP_2048_PRIME[MODP_2048_PRIME_LENGTH] = + {0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF ,0xC9,0x0F,0xDA,0xA2 + ,0x21,0x68,0xC2,0x34 ,0xC4,0xC6,0x62,0x8B ,0x80,0xDC,0x1C,0xD1 + ,0x29,0x02,0x4E,0x08 ,0x8A,0x67,0xCC,0x74 ,0x02,0x0B,0xBE,0xA6 + ,0x3B,0x13,0x9B,0x22 ,0x51,0x4A,0x08,0x79 ,0x8E,0x34,0x04,0xDD + ,0xEF,0x95,0x19,0xB3 ,0xCD,0x3A,0x43,0x1B ,0x30,0x2B,0x0A,0x6D + ,0xF2,0x5F,0x14,0x37 ,0x4F,0xE1,0x35,0x6D ,0x6D,0x51,0xC2,0x45 + ,0xE4,0x85,0xB5,0x76 ,0x62,0x5E,0x7E,0xC6 ,0xF4,0x4C,0x42,0xE9 + ,0xA6,0x37,0xED,0x6B ,0x0B,0xFF,0x5C,0xB6 ,0xF4,0x06,0xB7,0xED + ,0xEE,0x38,0x6B,0xFB ,0x5A,0x89,0x9F,0xA5 ,0xAE,0x9F,0x24,0x11 + ,0x7C,0x4B,0x1F,0xE6 ,0x49,0x28,0x66,0x51 ,0xEC,0xE4,0x5B,0x3D + ,0xC2,0x00,0x7C,0xB8 ,0xA1,0x63,0xBF,0x05 ,0x98,0xDA,0x48,0x36 + ,0x1C,0x55,0xD3,0x9A ,0x69,0x16,0x3F,0xA8 ,0xFD,0x24,0xCF,0x5F + ,0x83,0x65,0x5D,0x23 ,0xDC,0xA3,0xAD,0x96 ,0x1C,0x62,0xF3,0x56 + ,0x20,0x85,0x52,0xBB ,0x9E,0xD5,0x29,0x07 ,0x70,0x96,0x96,0x6D + ,0x67,0x0C,0x35,0x4E ,0x4A,0xBC,0x98,0x04 ,0xF1,0x74,0x6C,0x08 + ,0xCA,0x18,0x21,0x7C ,0x32,0x90,0x5E,0x46 ,0x2E,0x36,0xCE,0x3B + ,0xE3,0x9E,0x77,0x2C ,0x18,0x0E,0x86,0x03 ,0x9B,0x27,0x83,0xA2 + ,0xEC,0x07,0xA2,0x8F ,0xB5,0xC5,0x5D,0xF0 ,0x6F,0x4C,0x52,0xC9 + ,0xDE,0x2B,0xCB,0xF6 ,0x95,0x58,0x17,0x18 ,0x39,0x95,0x49,0x7C + ,0xEA,0x95,0x6A,0xE5 ,0x15,0xD2,0x26,0x18 ,0x98,0xFA,0x05,0x10 + ,0x15,0x72,0x8E,0x5A ,0x8A,0xAC,0xAA,0x68 ,0xFF,0xFF,0xFF,0xFF + ,0xFF,0xFF,0xFF,0xFF }; + +#define MODP_2048_GENERATOR_LENGTH 1 +const TUint8 MODP_2048_GENERATOR[MODP_2048_GENERATOR_LENGTH]={2}; + + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/inc/ikemsgheader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/inc/ikemsgheader.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,165 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE message header class +* +*/ + +#ifndef _IKE_MSG_HEADER_H_ +#define _IKE_MSG_HEADER_H_ + +#include + +#define ISAKMP_COOKIE_SIZE 8 +#define IKEV2_SPI_SIZE 8 +typedef TBuf8 TCookie; +typedef TBuf8 TIkeSPI; + +#define ISAKMP_HDR_SIZE sizeof(ThdrISAKMP) +#define IKEV2_HDR_SIZE sizeof(ThdrISAKMP) + +#define IKE_PORT 500 +#define FLOATED_IKE_PORT 4500 +#define NON_ESP_MARKER 0x0 +#define NON_ESP_MARKER_SIZE 4 // Corresponds IPSEC SPI size + +// +// NAT flags +// +#define LOCAL_END_NAT 0x1 +#define REMOTE_END_NAT 0x2 +#define MOBIKE_USED 0x4 + +// +// These macro definitions takes care of 16- and 32-bit data packing and +// unpacking. +// The following assumptions are in use for macros: +// -- The connection memory is a little-endian configured (= Intel format) +// -- A macro does always an unconditional conversion for the parameter data +// PUTxx(d, s) = Source data is supposed to be in "Network order". Data +// is stored to *p as little-endian. +// GETxx(s) = Source data is supposed to be in memory as little-endian. +// Macro return data in "Network order" +// +#define PUT16(d, s) \ + (*(unsigned char*)((unsigned char*)(d)+1)) = (unsigned char)((s) & 0xff);\ + (*(unsigned char*)(d)) = (unsigned char)(((s) >> 8 ) & 0xff) + +#define PUT32(d, s) \ + (*(unsigned char*)((unsigned char*)(d)+3)) = (unsigned char)((s) & 0xff);\ + (*(unsigned char*)((unsigned char*)(d)+2)) = (unsigned char)(((s) >> 8 ) & 0xff);\ + (*(unsigned char*)((unsigned char*)(d)+1)) = (unsigned char)(((s) >> 16) & 0xff);\ + (*(unsigned char*)(d)) = (unsigned char)(((s) >> 24) & 0xff) + +#define GET16(s) \ + (((unsigned short)(*((unsigned char*)(s)+1))) | \ + ((unsigned short)(*(unsigned char*)(s)) << 8 )) + +#define GET32(s) \ + (((unsigned int)(*((unsigned char*)(s)+3))) | \ + (((unsigned int)(*((unsigned char*)(s)+2))) << 8 ) | \ + (((unsigned int)(*((unsigned char*)(s)+1))) << 16 ) | \ + ((unsigned int)(*(unsigned char*)(s)) << 24 )) + + +// +// IKEv2 MESSAGE FIXED HEADER +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! IKE_SA Initiator's SPI ! +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! IKE_SA Responder's SPI ! +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Next Payload ! MjVer ! MnVer ! Exchange Type ! Flags ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Message ID ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Length ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +// IKEv1 MESSAGE FIXED HEADER +// +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Initiator ! +// ! Cookie ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Responder ! +// ! Cookie ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Next Payload ! MjVer ! MnVer ! Exchange Type ! Flags ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Message ID ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Length ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +class ThdrISAKMP +{ +public: + static inline const ThdrISAKMP* Ptr(const TDes8& aMsg, TInt aOffset) { return (ThdrISAKMP*)(aMsg.Ptr() + aOffset); } + static inline const ThdrISAKMP* Ptr(const TDes8& aMsg) { return (ThdrISAKMP*)aMsg.Ptr(); } + static inline TInt Size() { return sizeof(ThdrISAKMP); } + inline const ThdrISAKMP* GotoOffset(TUint8 aOffset) const { return (const ThdrISAKMP*)((char*)this + aOffset); } + inline TUint8* Next() const { return (TUint8*)((char*)this + sizeof(ThdrISAKMP)); } + inline TCookie GetCookieI() const + { TCookie c; + c.Copy(&u.iData8[0],ISAKMP_COOKIE_SIZE); + return c; + } + inline void GetSPI_I(TIkeSPI& aSPI) const { aSPI.Copy(&u.iData8[0], IKEV2_SPI_SIZE); } + inline TUint32 GetSPI_I_Low32() const { return GET32(&u.iData32[1]); } + inline TUint32 GetNegotiationID_I() const { return GET32(&u.iData32[0]); } + inline TCookie GetCookieR() const + { TCookie c; + c.Copy(&u.iData8[8],ISAKMP_COOKIE_SIZE); + return c; + } + inline void GetSPI_R(TIkeSPI& aSPI) const { aSPI.Copy(&u.iData8[8], IKEV2_SPI_SIZE); } + inline TUint32 GetSPI_R_Low32() const { return GET32(&u.iData32[3]); } + inline TUint32 GetNegotiationID_R() const { return GET32(&u.iData32[2]); } + inline void SetCookieI(const TCookie& aCookie) + { Mem::Copy(&u.iData8[0], aCookie.Ptr(), ISAKMP_COOKIE_SIZE); } + inline void SetSPI_I(const TIkeSPI& aSPI) {Mem::Copy(&u.iData8[0],aSPI.Ptr(),IKEV2_SPI_SIZE); } + inline void SetCookieR(const TCookie& aCookie) + { Mem::Copy(&u.iData8[8],aCookie.Ptr(),ISAKMP_COOKIE_SIZE); } + inline void SetSPI_R(const TIkeSPI& aSPI) { Mem::Copy(&u.iData8[8],aSPI.Ptr(),IKEV2_SPI_SIZE); } + inline TUint8 GetPayload() const { return u.iData8[16]; } + inline void SetPayload(TUint8 aPayload) { u.iData8[16] = aPayload; } + inline TUint8 GetVersion() const { return u.iData8[17]; } + inline TUint8 GetMajorVersion() const { return (TUint8)(u.iData8[17] >> 4); } + inline TUint8 GetMinorVersion() const { return (TUint8)(u.iData8[17] & 0xf); } + inline void SetVersion(TUint8 aVersion) { u.iData8[17] = aVersion; } + inline TUint8 GetExchange() const { return u.iData8[18]; } + inline void SetExchange(TUint8 aType) { u.iData8[18] = aType; } + inline TUint8 GetFlags() const { return u.iData8[19]; } + inline void SetFlags(TUint8 aFlags) { u.iData8[19] = aFlags; } + inline TUint32 GetMessageId() const { return GET32(&u.iData32[5]); } + inline void SetMessageId(TUint32 aId) { PUT32(&u.iData32[5], aId); } + inline TUint32 GetLength() const { return GET32(&u.iData32[6]); } + inline void SetLength(TUint32 aLength) { PUT32(&u.iData32[6], aLength); } +private: + union + { + TUint32 iData32[7]; + TUint16 iData16[14]; + TUint8 iData8[28]; + } u; +}; + + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/inc/ikesendqueueitem.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/inc/ikesendqueueitem.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,119 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE send queue item +* +*/ + + +#ifndef T_IKESENDQUEUEITEM_H +#define T_IKESENDQUEUEITEM_H + +// INCLUDES +#include + +/** + * Item in send queue + * + * Item contains information needed to send a UDP data. Items are stored + * in send queue while they are waiting for sending. + * + * @lib ikeutils.lib + */ +class TIkeSendQueueItem + { +public: + + /** + * Constructor. + * + * @param aUdpData UDP data + * @param aDestAddr Destination IP address + * @param aLocalPort Local port + * @param aDscp DSCP value + */ + IMPORT_C TIkeSendQueueItem( HBufC8* aUdpData, + const TInetAddr& aDestAddr, + TInt aLocalPort, + TUint8 aDscp ); + + /** + * Constructor with message identification parameter. Constructs object + * which should be used for matching with Match() method. + * @param aUdpData UDP data + */ + IMPORT_C TIkeSendQueueItem( HBufC8* aUdpData ); + + /** + * Determines whether two objects match. Items match if their + * message identification is same. + * @param aItemOne First item + * @param aItemTwo Second item + * @return Match or not + */ + IMPORT_C static TBool Match( const TIkeSendQueueItem& aItemOne, + const TIkeSendQueueItem& aItemTwo ); + + /** + * Gets UDP data. + * @return UDP data. + */ + IMPORT_C HBufC8* UdpData(); + + /** + * Gets destination IP address. + * @return Destination IP address + */ + IMPORT_C const TInetAddr& DestAddr(); + + /** + * Gets local port. + * @return Local port. + */ + IMPORT_C TInt LocalPort() const; + + /** + * Gets DSCP value. + * @return DSCP value. + */ + IMPORT_C TUint8 Dscp() const; + +private: + + /** + * UDP data. + * Own. + */ + HBufC8* iUdpData; + + /** + * Destination IP address + * Own. + */ + TInetAddr iDestAddr; + + /** + * Local port. + * Own. + */ + TInt iLocalPort; + + /** + * DSCP value. + * Own. + */ + TUint8 iDscp; + }; + + +#endif // T_IKESENDQUEUEITEM_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/inc/internaladdress.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/inc/internaladdress.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Internal address structure +* +*/ + + +#ifndef C_INTERNALADDRESS_H +#define C_INTERNALADDRESS_H + +#include + +/** + * Internal address structure. + * This class contains internal address in secure network and all DNS + * addresses related to that secure network. + * + * @lib ikeutils.lib + */ +class CInternalAddress : public CArrayPtrFlat + { + public: + /** + * Constructor. + * @param aGranularity Granularity + */ + IMPORT_C CInternalAddress( TInt aGranularity ); + + /** + * Destructor. + */ + ~CInternalAddress(); + + /** + * Two-phased constructor. + * @param aInternalAddress Internal address + */ + IMPORT_C static CInternalAddress* NewL( const CInternalAddress& aInternalAddress ); + + /** + * Copies internal address. + * @param aInternalAddress Internal address + */ + IMPORT_C void CopyL( const CInternalAddress& aData ); + + public: // data + + /** + * Internal address. + * Own. + */ + TInetAddr iClientIntAddr; + }; + +#endif // C_INTERNALADDRESS_H + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/inc/ipsecpolicyutil.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/inc/ipsecpolicyutil.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Utility class for using IPSec policy server +* +*/ + + +#ifndef C_IPSECPOLICYUTIL_H +#define C_IPSECPOLICYUTIL_H + +#include +#include + +// FORWARD DECLARATIONS +class CIpsecSaSpecList; +class TInetAddr; + +class CIpsecPolicyUtil : public CBase + { +public: + + IMPORT_C static CIpsecPolicyUtil* NewL(); + ~CIpsecPolicyUtil() ; + + + /** + * Gets acceptable IPsec policies for specified selectors. + * + * @param aLocalAddr IP address, including possible port, of the local end selector + * @param aLocalMask Local end selector mask + * @param aRemoteAddr IP address, including possible port, of the remote end selector + * @param aRemoteMask Remote end selector mask + * @param aProtocol Protocol id + * @param aVpnNetId VPN net id + */ + IMPORT_C CIpsecSaSpecList* GetIpseSaSpecListLC( TInetAddr aLocalAddr, TInetAddr aLocalMask, + TInetAddr aRemoteAddr, TInetAddr aRemoteMask, + TInt aProtocol, TUint32 aVpnNetId ); + +private: + CIpsecPolicyUtil(); + void ConstructL(); + +private: // data + + /** + * IPSec policy server. + * Own. + */ + RIpsecPolicyServ iIpsecPolicyServ; + + }; + + +#endif // C_IPSECPOLICYUTIL_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/inc/ipsecsadata.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/inc/ipsecsadata.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,70 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IPSec SA data structure for PFKEY Update and Add primitives +* +*/ + + +#ifndef T_IPSECSADATA_H +#define T_IPSECSADATA_H + +#include +#include + +// FORWARD DECLARATIONS +class TIpsecSALifetime; + +/** + * IPSec SA data structure. + * + * @lib ikeutils.lib + */ +class TIpsecSAData + { +public: + TIpsecSAData(); + +public: // data + TUint8 iSAType; + TUint32 iSeq; + TInetAddr iSrc; + TInetAddr iDst; + TUint8 iProtocol; + TPtr8 iSrcIdent; + TUint16 iSrcIdType; + TPtr8 iDstIdent; + TUint16 iDstIdType; + TUint32 iPid; + TUint32 iSPI; + TUint8 iAuthAlg; + TUint8 iEncrAlg; + TPtrC8 iAuthKey; + TPtrC8 iEncrKey; + TUint32 iFlags; + TUint8 iReplayWindowLength; +// +// Private Nokia VPN specific extensions +// + TInetAddr iInternalAddress; +// +// Genereric private format PFKEY extension. In this phase extesion consists +// Information for ESP UDP encapsulation (NAT Traversal) +// + TPtrC8 iGenericExtension; + + TIpsecSALifetime* iHard; + TIpsecSALifetime* iSoft; + }; + +#endif // T_IPSECSADATA_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/inc/ipsecsalifetime.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/inc/ipsecsalifetime.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IPSec SA lifetime structure +* +*/ + + +#ifndef T_IPSECSALIFETIME_H +#define T_IPSECSALIFETIME_H + +#include + +/** + * IPSec SA lifetime structure. + * + * @lib ikeutils.lib + */ +class TIpsecSALifetime + { +public: + IMPORT_C TIpsecSALifetime( TUint32 aAllocations, + const TInt64& aBytes, + const TInt64& aAddtime, + const TInt64& aUsetime ); + + IMPORT_C TIpsecSALifetime& operator=( const TIpsecSALifetime& aSource ); + +public: // data + TUint32 iAllocations; + TInt64 iBytes; + TInt64 iAddtime; + TInt64 iUsetime; + }; + +#endif // T_IPSECSALIFETIME_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/inc/ipsecsalist.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/inc/ipsecsalist.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Structure for storing IPSec SA Specs +* +*/ + + +#ifndef C_IPSECSALIST_H +#define C_IPSECSALIST_H + +#include +#include + +class CIpsecSaSpecList : public CArrayFixFlat + { +public: + IMPORT_C CIpsecSaSpecList(); + }; + +#endif // C_IPSECSALIST_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/inc/ipsecsaspiretriever.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/inc/ipsecsaspiretriever.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,102 @@ +/* +* Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Active object that retrieves an SPI value for IPsec SA +* +*/ + + +#ifndef IPSECSASPIRETRIEVER_H_ +#define IPSECSASPIRETRIEVER_H_ + +#include + +/** + * A Callback interface for IPsec SA SPI value retriever. + * Callback interface which is used by CIpsecSaSpiRetriever object to + * notify about completion of IPsec SA SPI retrieve + * + * @lib ikeutils.lib + */ +class MIpsecSaSpiRetrieverCallback + { +public: + + /** + * Notifies about completion of IPsec SPI SA retrieve. + * + * @param aSpiRequestId Id of the SPI retrieve request. + * @param aStatus Completion status + * @param aSpi SPI value + */ + virtual void IpsecSaSpiRetrieved(TUint32 aSpiRequestId, + TInt aStatus, + TUint32 aSpi) = 0; + + }; + +class CPFKeySocketIf; +class TInetAddr; + +/** + * Retrieves new IPsec SA SPI value from the IPsec + * + * @lib ikeutils.lib + */ +class CIpsecSaSpiRetriever : public CActive + { +public: + + /** + * Constructs new IPsec SA SPI retriever. + * + * @param aRetrieverCallback Used callback interface + * @param aSocketIf Used PFKey socket interface. + */ + IMPORT_C static CIpsecSaSpiRetriever* NewL(MIpsecSaSpiRetrieverCallback& aRetrieverCallback, + CPFKeySocketIf& aSocketIf); + ~CIpsecSaSpiRetriever(); + + /** + * Issues new IPsec SA SPI retrieve request. + * The completation of the SPI retrieve request is notified by using + * MIpsecSaSpiRetrieverCallback interface. + * + * @param aSpiRequestId Id for the SPI request. + * @param aIpsecProtocol Used IPsec protocol. + * Possible values are SADB_SATYPE_AH and SADB_SATYPE_ESP. + * @param aSrc Source address of the IPsec SA. + * If SRC_SPECIFIC is not set in the IPsec policy can be set to Unspecified. + * @param aDst Destination address of the IPsec SA. + */ + IMPORT_C void GetIpsecSaSpi(const TUint32 aSpiRequestId, + const TUint8 aIpsecProtocol, + const TInetAddr& aSrc, + const TInetAddr& aDst); + +private: + CIpsecSaSpiRetriever(MIpsecSaSpiRetrieverCallback& aRetrieverCallback, + CPFKeySocketIf& aSocketIf); + + void RunL(); + void DoCancel(); + TInt RunError(TInt aStatus); + + MIpsecSaSpiRetrieverCallback& iRetrieverCallback; + CPFKeySocketIf& iSocketIf; + + TUint32 iSpi; + TUint32 iSpiRequestId; + }; + +#endif /* IPSECSASPIRETRIEVER_H_ */ diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/inc/pfkeyextdatautil.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/inc/pfkeyextdatautil.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: VPN PFKEY extension data utility +* +*/ + + +#ifndef PFKEYEXTDATAUTIL_H +#define PFKEYEXTDATAUTIL_H + +#include + +/** + * PFKEY extension data utility class + * + * PFKEY extension data utility class for building generic PFKEY API extension + * data. + * + * @lib ikeutils.lib + */ +class PFKeyExtDataUtil + { +public: + /** + * This static method builds a generic PFKEY API extension data which is + * needed for IPSEC do UDP encapsulation/decapsulation for ESP packet. + * @param aExtData Generic extension data (returned) + * @param aNAT_D_Flags NAT_D flags + * @param aNATDetected Informs if NAT detected (local end behind NAT) + * @param aNokiaNATProbeUsed Nokia NAT probe used + * @param aUdpEncapsPort UDP encapsulation port + * @param aKeepAliveTimeout Keep alive timeout + * @param aDestinAddr Destination address + * @param aOriginalAddr Peer original address + */ + EXPORT_C static void BuildUdpEncExtensionData( TDes8& aExtData, + TUint32 aNAT_D_Flags, + TBool aNATDetected, + TBool aNokiaNATProbeUsed, + TUint16 aUdpEncapsPort, + TUint16 aKeepAliveTimeout, + const TInetAddr& aDestinAddr, + const TInetAddr& aOriginalAddr ); + }; + +#endif // PFKEYEXTDATAUTIL_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/inc/pfkeymsg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/inc/pfkeymsg.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,250 @@ +/* +* Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Key management daemon PFKEY message module. +* +*/ + +#ifndef PFKEYMSG_H +#define PFKEYMSG_H + +#include +#include +#include + +#include +#include + +// +// Classes for handling PFKEY structures. +// + +class TPfkeyBase + { +public: + const struct sadb_msg* iMsg; + TPfkeyBase(); + +#ifdef _DEBUG + void String( TDes &aStr, + const TDesC &aLabel ) const; +#endif + }; + +class TPfkeyAssociation + { +public: + const struct sadb_sa* iExt; + TPfkeyAssociation(); + +#ifdef _DEBUG + void String( TDes &aStr, + const TDesC &aLabel ) const; +#endif + }; + +class TPfkeyLifetime + { +public: + const struct sadb_lifetime* iExt; + TPfkeyLifetime(); + +#ifdef _DEBUG + void String( TDes &aStr, + const TDesC &aLabel ) const; +#endif + }; + +class TPfkeyAddress + { +public: + const struct sadb_address* iExt; + const TInetAddr* iAddr; + TPfkeyAddress(); + IMPORT_C const TInetAddr& Address() const; + +#ifdef _DEBUG + void String( TDes &aStr, + const TDesC &aLabel ) const; +#endif + }; + +class TPfkeyKey + { +public: + const struct sadb_key* iExt; + TPtrC8 iData; + TPfkeyKey(); + +#ifdef _DEBUG + void String( TDes &aStr, + const TDesC &aLabel ) const; +#endif + }; + +class TPfkeyIdentity + { +public: + const struct sadb_ident* iExt; + TPtrC8 iData; + TPfkeyIdentity(); + +#ifdef _DEBUG + void String( TDes &aStr, + const TDesC &aLabel ) const; +#endif + }; + +class TPfkeySensitivity + { +public: + const struct sadb_sens* iExt; + TPtrC8 iSensBitmap; + TPtrC8 iIntegBitmap; + TPfkeySensitivity(); + +#ifdef _DEBUG + void String( TDes &aStr, + const TDesC &aLabel ) const; +#endif + }; + +class TPfkeyProposal + { +public: + const struct sadb_prop* iExt; + const struct sadb_comb* iComb; + TInt iNumComb; + TPfkeyProposal(); + +#ifdef _DEBUG + void String( TDes &aStr, + const TDesC &aLabel ) const; +#endif + }; + +class TPfkeySupported + { +public: + const struct sadb_supported* iExt; + const struct sadb_alg* iAlg; + TInt iNumAlg; + TPfkeySupported(); + +#ifdef _DEBUG + void String( TDes &aStr, + const TDesC &aLabel ) const; +#endif + virtual void AlgString( TDes &aStr, + TUint8 aAlg ) const = 0; + }; + +class TPfkeySupportedAuth : public TPfkeySupported + { +public: + void AlgString( TDes &aStr, + TUint8 aAlg ) const; + static void Alg2String( TDes &aStr, + TUint8 aAlg ); + }; + +class TPfkeySupportedEncrypt : public TPfkeySupported + { +public: + void AlgString( TDes &aStr, + TUint8 aAlg ) const; + static void Alg2String( TDes &aStr, + TUint8 aAlg ); + }; + +class TPfkeySpirange + { +public: + const struct sadb_spirange* iExt; + TPfkeySpirange(); + +#ifdef _DEBUG + void String( TDes &aStr, + const TDesC &aLabel ) const; +#endif + }; + +class TPfKeySelector: public sadb_x_selector + { +public: + TInetAddr iSrc; + TInetAddr iDst; + }; + +class TPfkeyTs + { +public: + const struct sadb_x_ts* iExt; + TPfkeyTs(); + IMPORT_C TInt SelectorCount() const; + IMPORT_C const TPfKeySelector& Selector( TInt aIndex ) const; + +#ifdef _DEBUG + void String( TDes &aStr, + const TDesC &aLabel ) const; +#endif + }; + + +class TPFkeyPrivExt + { +public: + const struct sadb_gen_ext* iExt; + TPtrC8 iData; + TPFkeyPrivExt(); + +#ifdef _DEBUG + void String( TDes &aStr, + const TDesC &aLabel ) const; +#endif + }; + + +// +// Internal presentation of the PF_KEY message +// +class TPfkeyMessage + { +public: + // + // Construct internal presentation from the PFKEY bytestream message + TPfkeyMessage( TPfkeyRecvMsg& aMsg ); + TPfkeyMessage(); + TInt iError; // == KErrNone, if message format valid. + TPfkeyBase iBase; + TPfkeyAssociation iSa; + TPfkeyLifetime iCurrent; + TPfkeyLifetime iHard; + TPfkeyLifetime iSoft; + TPfkeyAddress iSrcAddr; + TPfkeyAddress iDstAddr; + TPfkeyAddress iProxyAddr; + TPfkeyKey iAuthKey; + TPfkeyKey iEncryptKey; + TPfkeyIdentity iSrcIdent; + TPfkeyIdentity iDstIdent; + TPfkeySensitivity iSensitivity; + TPfkeyProposal iProposal; + TPfkeySupportedAuth iAuthAlgs; + TPfkeySupportedEncrypt iEncryptAlgs; + TPfkeySpirange iSpirange; + TPfkeyTs iTs; + TPFkeyPrivExt iPrivateExtension; // For ESP UDP encapsulation + }; + +#endif // PFKEYMSG_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/inc/pfkeysocketif.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/inc/pfkeysocketif.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,118 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: VPN PFKEY socket interface +* +*/ + +#ifndef C_PFKEYSOCKET_H +#define C_PFKEYSOCKET_H + +#include +#include +#include +#include "pfkeymsg.h" + +// FORWARD DECLARATIONS +class TIpsecSAData; +class RSocketServ; +class MIkeDebug; + +class MPFKeyMessageListener + { +public: + virtual void PfkeyMessageReceived( const TPfkeyMessage& aReq ) = 0; + }; + + +class TPendingSpiRequest + { +public: + TPendingSpiRequest(TUint32& aSpi, TRequestStatus& aClientStatus): + iSpi(aSpi), iClientStatus(aClientStatus){} + + TUint32& iSpi; + TRequestStatus& iClientStatus; + }; + +// +// Register for ESP +// and stay listening the PFKEY socket +// +class CPFKeySocketIf : public CActive + { +public: + IMPORT_C static CPFKeySocketIf* NewL( MPFKeyMessageListener* aListener, + MIkeDebug& aDebug ); + ~CPFKeySocketIf() ; + + //PFKEY related functions + void GetSpi( const TUint8 aType, + const TUint32 aSeq, + const TInetAddr& aSrc, + const TInetAddr& aDst, + TUint32& aSpi, + TRequestStatus& aClientStatus); + void CancelGetSpi(TRequestStatus& aClientStatus); + + IMPORT_C void AcquireSAError( const TIpsecSAData& aSAData, + const TInt aError ); + + IMPORT_C void UpdateSAL( const TIpsecSAData& aSAData ); + + IMPORT_C void AddSAL( const TIpsecSAData& aSAData ); + + IMPORT_C void DeleteSA( const TUint32 aSPI, + const TInetAddr& aSrc, + const TInetAddr& aDst, + const TUint8 aProtocol ); + + IMPORT_C void FlushSAs(); + +private: + CPFKeySocketIf( MPFKeyMessageListener* aListener, + MIkeDebug& aDebug ); + void ConstructL(); + + void AddUpdateSAL( const TUint8 aType, + const TIpsecSAData& aSAData ); + + TUint32 NewSpi(); + +#ifdef _DEBUG + void ShowMessageL( TPfkeyRecvMsg& aMsg ); +#endif + +// from base class CActive + void RunL(); + void DoCancel(); + TInt RunError( TInt aError ); + +protected: // data + MPFKeyMessageListener* iListener; + +private: // data + + RSocketServ iSocketServer; + RSADB iSadb; + + TPfkeyRecvMsg iMsg; + TUint32 iSeq; + TUint32 iSpiBase; + + MIkeDebug& iDebug; + + RArray iPendingSpiRequests; + }; + +#endif // C_PFKEYSOCKET_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/inc/vpnaddrinfo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/inc/vpnaddrinfo.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Utility for building internal address info. +* +*/ + + +#ifndef VPNADDRINFO_H +#define VPNADDRINFO_H + +#include + +// FORWARD DECLARATIONS +class CInternalAddress; +class MIkeDebug; +class TInetAddr; +class TVPNAddress; + +/** + * VPN address info utility. + * + * Utility class for building internal address info. + * + * @lib internal (kmdserver.exe) + */ +class VPNAddrInfo + { +public: + + /** + * Builds internal address info object. + * @param aInternalAddr Internal address + * @param aDnsServerAddr DNS server address + * @param aVPNAddress Internal address info (returned) + * @param aDebug Debug trace interface + */ + EXPORT_C static void BuildVPNAddrInfo( const CInternalAddress* aInternalAddr, + const TInetAddr& aDnsServerAddr, + TVPNAddress& aVPNAddress, + MIkeDebug& aDebug ); + + }; + + +#endif // VPNADDRINFO_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/rom/ikeutils.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/rom/ikeutils.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Image description file for project +* ikeutils +* +*/ + + + +#ifndef __IKEUTILS_IBY__ +#define __IKEUTILS_IBY__ + +#ifdef SYMBIAN_EXCLUDE_IPSEC + +REM Feature IKEUTILS not included in this rom + +#else + +file=ABI_DIR\BUILD_DIR\ikeutils.dll SHARED_LIB_DIR\ikeutils.dll + +#endif // SYMBIAN_EXCLUDE_IPSEC + +#endif // __IKEUTILS_IBY__ + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/src/ikesendqueueitem.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/src/ikesendqueueitem.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,100 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE send queue item +* +*/ + + +// INCLUDE FILES +#include "ikesendqueueitem.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Constructor +// --------------------------------------------------------------------------- +// +EXPORT_C TIkeSendQueueItem::TIkeSendQueueItem( HBufC8* aUdpData, + const TInetAddr& aDestAddr, + TInt aLocalPort, + TUint8 aDscp ) + : iUdpData( aUdpData ), + iDestAddr( aDestAddr ), + iLocalPort( aLocalPort ), + iDscp( aDscp ) + { + } + +// --------------------------------------------------------------------------- +// Constructor with message identification parameter. Constructs object +// which should be used for matching with Match() method. +// --------------------------------------------------------------------------- +// +EXPORT_C TIkeSendQueueItem::TIkeSendQueueItem( HBufC8* aUdpData ) + : iUdpData( aUdpData ), + iDestAddr( TInetAddr() ), + iLocalPort( 0 ), + iDscp( 0 ) + { + } + +// --------------------------------------------------------------------------- +// Determines whether two objects match. +// --------------------------------------------------------------------------- +// +EXPORT_C TBool TIkeSendQueueItem::Match( const TIkeSendQueueItem& aItemOne, + const TIkeSendQueueItem& aItemTwo ) + { + if ( aItemOne.iUdpData == aItemTwo.iUdpData ) + { + return ETrue; + } + return EFalse; + } + +// --------------------------------------------------------------------------- +// Gets UDP data. +// --------------------------------------------------------------------------- +// +EXPORT_C HBufC8* TIkeSendQueueItem::UdpData() + { + return iUdpData; + } + +// --------------------------------------------------------------------------- +// Gets destination IP address. +// --------------------------------------------------------------------------- +// +EXPORT_C const TInetAddr& TIkeSendQueueItem::DestAddr() + { + return iDestAddr; + } + +// --------------------------------------------------------------------------- +// Gets local port. +// --------------------------------------------------------------------------- +// +EXPORT_C TInt TIkeSendQueueItem::LocalPort() const + { + return iLocalPort; + } + +// --------------------------------------------------------------------------- +// Gets DSCP value. +// --------------------------------------------------------------------------- +// +EXPORT_C TUint8 TIkeSendQueueItem::Dscp() const + { + return iDscp; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/src/internaladdress.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/src/internaladdress.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Internal address structure +* +*/ + + +// CLASS HEADER +#include "internaladdress.h" + +EXPORT_C CInternalAddress::CInternalAddress( TInt aGranularity ) + : CArrayPtrFlat( aGranularity ) + { + } + +CInternalAddress::~CInternalAddress() + { + ResetAndDestroy(); + } + +EXPORT_C CInternalAddress* CInternalAddress::NewL( const CInternalAddress& aData ) + { + CInternalAddress* internalAddr = new (ELeave) CInternalAddress(1); + internalAddr->CopyL(aData); + return internalAddr; + } + +EXPORT_C void CInternalAddress::CopyL( const CInternalAddress& aData ) + { + for ( TInt i=0; iConstructL(); + CleanupStack::Pop(self); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CIpsecPolicyUtil::~CIpsecPolicyUtil() + { + iIpsecPolicyServ.Close(); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CIpsecPolicyUtil::CIpsecPolicyUtil() + { + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CIpsecPolicyUtil::ConstructL() + { + User::LeaveIfError( iIpsecPolicyServ.Connect() ); + } + +// --------------------------------------------------------------------------- +// Get acceptable IPsec policies for specified selectors. Get all acceptable +// SA specifications with sequential GetIPSecSAInfo() method calls. +// --------------------------------------------------------------------------- +// +EXPORT_C CIpsecSaSpecList* CIpsecPolicyUtil::GetIpseSaSpecListLC( TInetAddr aLocalAddr, TInetAddr aLocalMask, + TInetAddr aRemoteAddr, TInetAddr aRemoteMask, + TInt aProtocol, TUint32 aVpnNetId ) + { + CIpsecSaSpecList* ipsecSaList = new (ELeave)CIpsecSaSpecList(); + CleanupStack::PushL(ipsecSaList); + + aLocalAddr.ConvertToV4Mapped(); + aLocalMask.ConvertToV4Mapped(); + aRemoteAddr.ConvertToV4Mapped(); + aRemoteAddr.SetScope(aVpnNetId); + aRemoteMask.ConvertToV4Mapped(); + + + TIpsecSelectorInfo selectorInfo; + selectorInfo.iLocal = aLocalAddr; + selectorInfo.iLocalMask = aLocalMask; + selectorInfo.iRemote = aRemoteAddr; + selectorInfo.iRemoteMask = aRemoteMask; + selectorInfo.iProtocol = aProtocol; + selectorInfo.iSaIndex = 0; + TPckg pckgSelectorInfo(selectorInfo); + TIpsecSaSpec saInfo; + do + { + TRequestStatus requestStatus; + TPckg pckgSASpec(saInfo); + + iIpsecPolicyServ.MatchSelector( pckgSelectorInfo, + pckgSASpec, + requestStatus ); + User::WaitForRequest(requestStatus); + User::LeaveIfError(requestStatus.Int()); + + ipsecSaList->AppendL(saInfo); + selectorInfo.iSaIndex++; + } + while(saInfo.iMoreSasExist); + + return ipsecSaList; + } + + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/src/ipsecsadata.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/src/ipsecsadata.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IPSec SA data structure for PFKEY Update and Add primitives +* +*/ + + +// CLASS HEADER +#include "ipsecsadata.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +EXPORT_C TIpsecSAData::TIpsecSAData() + : iSAType(0), + iSeq(0), + iSrc(), + iDst(), + iProtocol(0), + iSrcIdent(0,0), + iSrcIdType(0), + iDstIdent(0,0), + iDstIdType(0), + iPid(0), + iSPI(0), + iAuthAlg(0), + iEncrAlg(0), + iAuthKey(0,0), + iEncrKey(0,0), + iFlags(0), + iReplayWindowLength(0), + iInternalAddress(), + iGenericExtension(0,0), + iHard(0), + iSoft(0) + { + }; + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/src/ipsecsalifetime.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/src/ipsecsalifetime.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IPSec SA lifetime structure +* +*/ + + +// CLASS HEADER +#include "ipsecsalifetime.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +EXPORT_C TIpsecSALifetime::TIpsecSALifetime( TUint32 aAllocations, + const TInt64& aBytes, + const TInt64& aAddtime, + const TInt64& aUsetime ) + : iAllocations( aAllocations ), + iBytes(aBytes), + iAddtime(aAddtime), + iUsetime(aUsetime) + { + } + +// --------------------------------------------------------------------------- +// Assignment operator. +// --------------------------------------------------------------------------- +// +EXPORT_C TIpsecSALifetime& TIpsecSALifetime::operator=( const TIpsecSALifetime& aSource ) + { + if ( this != &aSource ) + { + iAllocations = aSource.iAllocations; + iBytes = aSource.iBytes; + iAddtime = aSource.iAddtime; + iUsetime = aSource.iUsetime; + } + return *this; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/src/ipsecsalist.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/src/ipsecsalist.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Structure for storing IPSec SA Specs +* +*/ + + +// CLASS HEADER +#include "ipsecsalist.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +EXPORT_C CIpsecSaSpecList::CIpsecSaSpecList() + : CArrayFixFlat(1) + { + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/src/ipsecsaspiretriever.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/src/ipsecsaspiretriever.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: KMD server +* +*/ + + +#include "ipsecsaspiretriever.h" +#include "pfkeysocketif.h" + +EXPORT_C CIpsecSaSpiRetriever* CIpsecSaSpiRetriever::NewL(MIpsecSaSpiRetrieverCallback& aRetrieverCallback, + CPFKeySocketIf& aSocketIf) + { + CIpsecSaSpiRetriever* self = new (ELeave) CIpsecSaSpiRetriever(aRetrieverCallback, aSocketIf); + return self; + } + +CIpsecSaSpiRetriever::CIpsecSaSpiRetriever(MIpsecSaSpiRetrieverCallback& aRetrieverCallback, + CPFKeySocketIf& aSocketIf) +:CActive(EPriorityStandard), iRetrieverCallback(aRetrieverCallback), iSocketIf(aSocketIf) + { + CActiveScheduler::Add(this); + } + +CIpsecSaSpiRetriever::~CIpsecSaSpiRetriever() + { + Cancel(); + } + +EXPORT_C void CIpsecSaSpiRetriever::GetIpsecSaSpi(const TUint32 aSpiRequestId, + const TUint8 aIpsecProtocol, + const TInetAddr& aSrc, + const TInetAddr& aDst) + { + iSpiRequestId = aSpiRequestId; + iSocketIf.GetSpi(aIpsecProtocol, aSpiRequestId, aSrc, aDst, iSpi, iStatus); + SetActive(); + } + + +void CIpsecSaSpiRetriever::RunL() + { + iRetrieverCallback.IpsecSaSpiRetrieved(iSpiRequestId, iStatus.Int(), iSpi); + } + +void CIpsecSaSpiRetriever::DoCancel() + { + iSocketIf.CancelGetSpi(iStatus); + } + +TInt CIpsecSaSpiRetriever::RunError(TInt /*aStatus*/) + { + User::Invariant(); //RunL should never leave + return KErrNone; + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/src/pfkeyextdatautil.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/src/pfkeyextdatautil.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,110 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: VPN PFKEY extension data utility +* +*/ + + +#include +#include +#include + +#include "ikemsgheader.h" +#include "pfkeyextdatautil.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// This static method builds a generic PFKEY API extension data for IPSEC. +// This data contains all parameters needed by the IPSEC to do UDP +// encapsulation/decpsulation for ESP packet. Generic extension data format is +// LID format begining with four bytes extension header. Extension header +// consists two bytes extension length and two bytes extension ID. LID format +// consists from one byte length, one byte ID and parameter data. +// Buffer format: HL,HID,LID,LID,...LID +// Generic extension data buffer handling macros are defined in pfkeyext.h +// (common macros with IPSEC) +// --------------------------------------------------------------------------- +// +void PFKeyExtDataUtil::BuildUdpEncExtensionData( TDes8& aExtData, + TUint32 aNAT_D_Flags, + TBool aNATDetected, + TBool aNokiaNATProbeUsed, + TUint16 aUdpEncapsPort, + TUint16 aKeepAliveTimeout, + const TInetAddr& aDestinAddr, + const TInetAddr& aOriginalAddr ) + { + if ( aNAT_D_Flags ) + { + aUdpEncapsPort = FLOATED_IKE_PORT; // for IETF specified ESP UDP encapsulation + if ( ( aNAT_D_Flags & LOCAL_END_NAT ) == 0 ) + { + aKeepAliveTimeout = 0; // Local end is not behind NAT, no keepalive needed + } + } + else + { + // + // Nokia specific NAT traversal info (=ESP UDP tunneling) + // If aNATDetected is true connection is over NAT:ted + // network (=local end behind NAT). UDP encapsulation shall + // then be done using configured port iEspUdpPort. If that + // value is undefined default port 9872 shall be used then. + // If aNATDetected is false and aNokiaNATProbeUsed is true + // the NAT probe procedure has confirmed that there is no + // NAT device between. ESP UDP encapsulation port is zeroed + // then to avoid unnecessary ESP UDP encapsulation. + // If aNokiaNATProbeUsed is false ESP UDP encapsulation is done + // without probing, if any aUdpEncapsPort is defined + // + if ( !aNATDetected && aNokiaNATProbeUsed ) + { + aUdpEncapsPort = 0; + } + } + + if ( aUdpEncapsPort == 0 ) + { + aExtData.SetLength(0); // No extension data needed + return; + } + + TPfkeyGenExtension NatExtension( aExtData, ESP_UDP_ENCAPSULATION_EXT ); + + NatExtension.StoreParameter( UDP_ENCAPSULATION_PORT, + 2, + (TUint8*)&aUdpEncapsPort ); + + if ( aKeepAliveTimeout ) + { + NatExtension.StoreParameter( NAT_KEEPALIVE_TIMEOUT, + 2, + (TUint8*)&aKeepAliveTimeout ); + } + + if ( aNAT_D_Flags & REMOTE_END_NAT ) + { + NatExtension.StoreParameter( DESTINATION_ADDRESS, + sizeof(TInetAddr), + (TUint8*)&aDestinAddr ); + } + + if ( aOriginalAddr.Family() != KAFUnspec ) + { + NatExtension.StoreParameter( PEER_ORIGINAL_ADDRESS, + sizeof(TInetAddr), + (TUint8*)&aOriginalAddr ); + } + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/src/pfkeymsg.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/src/pfkeymsg.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,722 @@ +/* +* Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Key management daemon PFKEY message module. +* +*/ + +#include +#include +#include + +#include "pfkeymsg.h" + +// ======== MEMBER FUNCTIONS ======== + +#ifdef _DEBUG +// +// Convert to String methods +// +// TPfkeyBase::String +// Convert Base Message Header to printable string +// + +void TPfkeyBase::String(TDes &aStr, const TDesC &aLabel) const + { + + if (!iMsg) + return; + + aStr.Append(aLabel); + aStr.AppendFormat(_L("#%d.%d "), + (int)iMsg->sadb_msg_seq, + (int)iMsg->sadb_msg_pid); + switch (iMsg->sadb_msg_type) + { + case SADB_GETSPI: + aStr.Append(_L("GETSPI")); + break; + case SADB_UPDATE: + aStr.Append(_L("UPDATE")); + break; + case SADB_ADD: + aStr.Append(_L("ADD")); + break; + case SADB_DELETE: + aStr.Append(_L("DELETE")); + break; + case SADB_GET: + aStr.Append(_L("GET")); + break; + case SADB_ACQUIRE: + aStr.Append(_L("ACQUIRE")); + break; + case SADB_REGISTER: + aStr.Append(_L("REGISTER")); + break; + case SADB_EXPIRE: + aStr.Append(_L("EXPIRE")); + break; + case SADB_FLUSH: + aStr.Append(_L("FLUSH")); + break; + case SADB_DUMP: + aStr.Append(_L("DUMP")); + break; + default: + aStr.AppendFormat(_L("UNKNOWN(%d)"), + iMsg->sadb_msg_type); + break; + } + if (iMsg->sadb_msg_version != PF_KEY_V2) + aStr.AppendFormat(_L("(V%d)"), (int)iMsg->sadb_msg_version); + + if (iMsg->sadb_msg_errno) + { + aStr.AppendFormat(_L("(Errno%d)"), (int)iMsg->sadb_msg_errno); + } + else + aStr.Append(_L("[ok] ")); + switch (iMsg->sadb_msg_satype) + { + case SADB_SATYPE_AH: + aStr.Append(_L("AH")); + break; + case SADB_SATYPE_ESP: + aStr.Append(_L("ESP")); + break; + case SADB_SATYPE_UNSPEC: + aStr.Append('*'); + break; + default: + aStr.AppendFormat(_L("UNKNOWN=%d"), (int)iMsg->sadb_msg_satype); + break; + } + } + +void TPfkeyAssociation::String(TDes &aStr, const TDesC &aLabel) const + { + if (!iExt) + return; + aStr.Append(aLabel); + if (iExt->sadb_sa_encrypt || iExt->sadb_sa_auth) + { + aStr.Append('('); + if (iExt->sadb_sa_encrypt) + TPfkeySupportedEncrypt::Alg2String(aStr, iExt->sadb_sa_encrypt); + aStr.Append(','); + if (iExt->sadb_sa_auth) + TPfkeySupportedAuth::Alg2String(aStr, iExt->sadb_sa_auth); + aStr.Append(')'); + } + + switch (iExt->sadb_sa_state) + { + case SADB_SASTATE_LARVAL: + aStr.Append(_L(" LARVAL")); + break; + case SADB_SASTATE_MATURE: + aStr.Append(_L(" MATURE")); + break; + case SADB_SASTATE_DYING: + aStr.Append(_L(" DYING")); + break; + case SADB_SASTATE_DEAD: + aStr.Append(_L(" DEAD")); + break; + default: + aStr.AppendFormat(_L(" UNKNOWN=%d"), (int)iExt->sadb_sa_state); + break; + } + aStr.AppendFormat(_L(" SPI=%x"), (int)ByteOrder::Swap32(iExt->sadb_sa_spi)); + if (iExt->sadb_sa_replay) + aStr.AppendFormat(_L(" Replay=%d"), (int)iExt->sadb_sa_replay); + } + +void TPfkeyAddress::String(TDes &aStr, const TDesC &aLabel) const + { + if (!iExt) + return; + aStr.Append(aLabel); + if (iAddr) + { + TBuf<39> addr; + iAddr->OutputWithScope(addr); + aStr.Append(addr); + if (iExt->sadb_address_proto) + aStr.AppendFormat(_L(" proto=%d"), iExt->sadb_address_proto); + if (iAddr->Port()) + aStr.AppendFormat(_L(" port=%d"), iAddr->Port()); + } + } + +void TPfkeyKey::String(TDes &aStr, const TDesC &aLabel) const + { + if (iExt) + aStr.Append(aLabel); + } + +void TPfkeyLifetime::String(TDes &aStr, const TDesC &aLabel) const + { + if (!iExt) + return; + aStr.Append(aLabel); + aStr.Append((TChar)'('); + aStr.AppendNum(iExt->sadb_lifetime_allocations); + aStr.Append((TChar)','); + aStr.AppendNum(iExt->sadb_lifetime_bytes); + aStr.Append((TChar)','); + aStr.AppendNum(iExt->sadb_lifetime_addtime); + aStr.Append((TChar)','); + aStr.AppendNum(iExt->sadb_lifetime_usetime); + aStr.Append((TChar)')'); + } + +void TPfkeySupported::String(TDes &aStr, const TDesC &aLabel) const + { + if (!iExt) + return; + aStr.Append(aLabel); + for (int i = 0; i < iNumAlg; ++i) + { + AlgString(aStr, iAlg[i].sadb_alg_id); + if (iAlg[i].sadb_alg_minbits == iAlg[i].sadb_alg_maxbits) + aStr.AppendFormat + (_L("(IV=%d,key=%d)"), + (int)iAlg[i].sadb_alg_ivlen, + (int)iAlg[i].sadb_alg_maxbits); + else + aStr.AppendFormat + (_L("(IV=%d,%d<=key<=%d)"), + (int)iAlg[i].sadb_alg_ivlen, + (int)iAlg[i].sadb_alg_minbits, + (int)iAlg[i].sadb_alg_maxbits); + } + } + +void TPfkeyIdentity::String(TDes &aStr, const TDesC &aLabel) const +{ + +#ifdef _UNICODE + if (iExt) + { + aStr.Append(aLabel); + if (iData.Length() == 0) + return; + HBufC *unibuf = HBufC::New(iData.Length()); + if (!unibuf) + return; + unibuf->Des().Copy(iData); + aStr.Append(unibuf->Des()); + delete unibuf; + } +#else + if (iExt) + { + aStr.Append(aLabel); + aStr.Append(iData); + } +#endif +} + +void TPfkeySensitivity::String(TDes &aStr, const TDesC &aLabel) const + { + if (iExt) + { + aStr.Append(aLabel); + } + } + +void TPfkeyProposal::String(TDes &aStr, const TDesC &aLabel) const + { + if (!iExt) + return; + aStr.Append(aLabel); + if (iExt->sadb_prop_replay) + aStr.AppendFormat(_L("replay=%d"), (int)iExt->sadb_prop_replay); + for (int i = 0; i < iNumComb; i++) + { + aStr.AppendFormat(_L(" %d:("), i+1); + if (iComb[i].sadb_comb_flags & SADB_SAFLAGS_PFS) + aStr.Append(_L("PFS ")); + if (iComb[i].sadb_comb_encrypt) + { + TPfkeySupportedEncrypt::Alg2String(aStr, iComb[i].sadb_comb_encrypt); + aStr.AppendFormat(_L("[%d..%d]"), + iComb[i].sadb_comb_encrypt_minbits, + iComb[i].sadb_comb_encrypt_maxbits); + } + if (iComb[i].sadb_comb_auth) + { + aStr.Append(','); + TPfkeySupportedAuth::Alg2String(aStr, iComb[i].sadb_comb_auth); + aStr.AppendFormat(_L("[%d..%d]"), + iComb[i].sadb_comb_auth_minbits, + iComb[i].sadb_comb_auth_maxbits); + } + if (iComb[i].sadb_comb_soft_allocations || + iComb[i].sadb_comb_soft_bytes != 0 || + iComb[i].sadb_comb_soft_addtime != 0|| + iComb[i].sadb_comb_soft_usetime != 0) + { + aStr.AppendFormat(_L(" soft=(%d,"), (int)iComb[i].sadb_comb_soft_allocations); + aStr.AppendNum(iComb[i].sadb_comb_soft_bytes); + aStr.Append(','); + aStr.AppendNum(iComb[i].sadb_comb_soft_addtime); + aStr.Append(','); + aStr.AppendNum(iComb[i].sadb_comb_soft_usetime); + aStr.Append(')'); + } + if (iComb[i].sadb_comb_hard_allocations || + iComb[i].sadb_comb_hard_bytes != 0 || + iComb[i].sadb_comb_hard_addtime != 0 || + iComb[i].sadb_comb_hard_usetime != 0) + { + aStr.AppendFormat(_L(" hard=(%d,"), (int)iComb[i].sadb_comb_hard_allocations); + aStr.AppendNum(iComb[i].sadb_comb_hard_bytes); + aStr.Append(','); + aStr.AppendNum(iComb[i].sadb_comb_hard_addtime); + aStr.Append(','); + aStr.AppendNum(iComb[i].sadb_comb_hard_usetime); + aStr.Append(')'); + } + aStr.Append(')'); + } + } + +void TPfkeySpirange::String(TDes &aStr,const TDesC &aLabel) const + { + if (iExt) + { + aStr.Append(aLabel); + } + } + +void TPfkeyTs::String(TDes &aStr,const TDesC &aLabel) const + { + if (iExt) + { + for (TInt i = 0; i < SelectorCount(); ++i) + { + const TPfKeySelector& selector = Selector(i); + + TBuf<50> src; + TBuf<50> dst; + + selector.iSrc.OutputWithScope(src); + selector.iDst.OutputWithScope(dst); + + aStr.AppendFormat(_L("%S[%d] proto=%d src=%S:%d, dst=%S:%d" ), + &aLabel, i, selector.sadb_x_selector_proto, + &src, selector.iSrc.Port(), + &dst, selector.iDst.Port()); + + + } + } + } + +void TPFkeyPrivExt::String(TDes &aStr, const TDesC &aLabel) const + { + if (iExt) + aStr.Append(aLabel); + } + +#endif //#ifdef _DEBUG + + +TPfkeyBase::TPfkeyBase() + : iMsg( 0 ) + { + } + +TPfkeyAssociation::TPfkeyAssociation() + : iExt( 0 ) + { + } + +TPfkeyLifetime::TPfkeyLifetime() + : iExt( 0 ) + { + } + +TPfkeyAddress::TPfkeyAddress() + : iExt(0), iAddr(0) + { + } + +EXPORT_C const TInetAddr& TPfkeyAddress::Address() const + { + return *iAddr; + } + +TPfkeyKey::TPfkeyKey() + : iExt( 0 ) + { + } + +TPfkeyIdentity::TPfkeyIdentity() + : iExt( 0 ) + { + } + +TPfkeySensitivity::TPfkeySensitivity() + : iExt(0) + { + } + +TPfkeyProposal::TPfkeyProposal() + : iExt( 0 ), + iComb( 0 ), + iNumComb( 0 ) + { + } + +TPfkeySupported::TPfkeySupported() + : iExt( 0 ), + iAlg( 0 ), + iNumAlg( 0 ) + { + } + +void TPfkeySupportedAuth::AlgString( TDes &aStr, + TUint8 aAlg ) const + { + Alg2String( aStr, aAlg ); + } + +void TPfkeySupportedAuth::Alg2String(TDes &aStr, TUint8 aAlg) + { + switch (aAlg) + { + case SADB_AALG_MD5HMAC: + aStr.Append(_L("md5hmac")); + break; + case SADB_AALG_SHA1HMAC: + aStr.Append(_L("sha1hmac")); + break; + default: + aStr.AppendFormat(_L("%d"), (int)aAlg); + } + } + +void TPfkeySupportedEncrypt::AlgString( TDes &aStr, + TUint8 aAlg ) const + { + Alg2String( aStr, aAlg ); + } + +void TPfkeySupportedEncrypt::Alg2String(TDes &aStr, TUint8 aAlg) + { + switch (aAlg) + { + case SADB_EALG_DESCBC: + aStr.Append(_L("descbc")); + break; + case SADB_EALG_3DESCBC: + aStr.Append(_L("3descbc")); + break; + case SADB_EALG_NULL: + aStr.Append(_L("null")); + break; + case 4: + aStr.Append(_L("rc5")); + break; + case 5: + aStr.Append(_L("idea")); + break; + case 6: + aStr.Append(_L("cast")); + break; + case 7: + aStr.Append(_L("blowfish")); + break; + case 8: + aStr.Append(_L("3idea")); + break; + case 9: + aStr.Append(_L("desiv32")); + break; + case 10: + aStr.Append(_L("rc4")); + break; + case 12: + aStr.Append(_L("aes")); + break; + + default: + aStr.AppendFormat(_L("%d"), (int)aAlg); + } + } + +TPfkeySpirange::TPfkeySpirange() + : iExt( 0 ) + { + } + +TPfkeyTs::TPfkeyTs() + : iExt(0) + { + } + +EXPORT_C TInt TPfkeyTs::SelectorCount() const + { + return (iExt != NULL) ? iExt->sadb_x_ts_numsel : 0; + } + +EXPORT_C const TPfKeySelector& TPfkeyTs::Selector(TInt aIndex) const + { + __ASSERT_DEBUG(iExt != NULL, User::Invariant()); + __ASSERT_DEBUG(iExt->sadb_x_ts_numsel > aIndex, User::Invariant()); + + TPfKeySelector *selector = (TPfKeySelector*)((TUint8*)iExt + sizeof(struct sadb_x_ts)); + return selector[aIndex]; + } + +TPFkeyPrivExt::TPFkeyPrivExt() + : iExt( 0 ) + { + } + +// +// TPfkeyMessage +// +TPfkeyMessage::TPfkeyMessage() + : iError( KErrNone ) + { + } + +// +// Construct TPfkeyMesage from a PF_KEY v2 byte stream (aMsg) +// +TPfkeyMessage::TPfkeyMessage(TPfkeyRecvMsg& aMsg) + { + const TUint8 *p = aMsg.Ptr(); + TInt length = aMsg.Length(); + + iError = KErrArgument; + if (length < (TInt)sizeof(sadb_msg)) + return; // EMSGSIZE (impossible message size) + + // Base Message Header + iBase.iMsg = (struct sadb_msg *)p; + if (iBase.iMsg->sadb_msg_version != PF_KEY_V2) + return; // EINVAL + // SADB_ACQUIRE response can have sadb_msg_errno set to non-zero value + if (iBase.iMsg->sadb_msg_errno && (iBase.iMsg->sadb_msg_type != SADB_ACQUIRE)) + return; // EINVAL (should be set zero by sender) + if (iBase.iMsg->sadb_msg_len * 8 != length) + return; // EMSGSIZE (incorrect message length) + // SADB_ACQUIRE response can have sadb_msg_reserved set to non-zero value + if (iBase.iMsg->sadb_msg_reserved && (iBase.iMsg->sadb_msg_type != SADB_ACQUIRE)) + return; // EINVAL (unused parts must be zeroed) + p += sizeof(struct sadb_msg); + length -= sizeof(struct sadb_msg); + + // Extension headers + // Some general rules: + // - only one instance of an extension type is valid + while (length > 0) + { + struct sadb_ext *ext = (struct sadb_ext *)p; + int ext_len = ext->sadb_ext_len; + int data_len, data_len2; + + if (ext_len < 1) + return; // EINVAL (bad message format) + ext_len *= 8; + if (ext_len > length) + return; // EINVAL + switch (ext->sadb_ext_type) + { + case SADB_EXT_RESERVED: + return; // EINVAL (bad mesage format) + + case SADB_EXT_SA: + if (iSa.iExt) + return; // EINVAL + iSa.iExt = (struct sadb_sa *)p; + break; + + case SADB_EXT_LIFETIME_CURRENT: + if (iCurrent.iExt) + return; // EINVAL; + iCurrent.iExt = (struct sadb_lifetime *)p; + break; + + case SADB_EXT_LIFETIME_HARD: + if (iHard.iExt) + return; + iHard.iExt = (struct sadb_lifetime *)p; + break; + + case SADB_EXT_LIFETIME_SOFT: + if (iSoft.iExt) + return; + iSoft.iExt = (struct sadb_lifetime *)p; + break; + + case SADB_EXT_ADDRESS_SRC: + if (iSrcAddr.iExt) + return; + if (ext_len != sizeof(struct sadb_address) + sizeof(TInetAddr)) + return; + iSrcAddr.iExt = (struct sadb_address *)p; + iSrcAddr.iAddr = (TInetAddr *)(p + sizeof(struct sadb_address)); + break; + + case SADB_EXT_ADDRESS_DST: + if (iDstAddr.iExt) + return; + if (ext_len != sizeof(struct sadb_address) + sizeof(TInetAddr)) + return; + iDstAddr.iExt = (struct sadb_address *)p; + iDstAddr.iAddr = (TInetAddr *)(p + sizeof(struct sadb_address)); + break; + + case SADB_EXT_ADDRESS_PROXY: + if (iProxyAddr.iExt) + return; + if (ext_len != sizeof(struct sadb_address) + sizeof(TInetAddr)) + return; + iProxyAddr.iExt = (struct sadb_address *)p; + iProxyAddr.iAddr = (TInetAddr *)(p + sizeof(struct sadb_address)); + break; + + case SADB_EXT_KEY_AUTH: + if (iAuthKey.iExt) + return; + iAuthKey.iExt = (struct sadb_key *)p; + data_len = (iAuthKey.iExt->sadb_key_bits + 7) / 8; + if (data_len == 0 || data_len + (int)sizeof(struct sadb_key) > ext_len) + return; + iAuthKey.iData.Set(p + sizeof(struct sadb_key), data_len); + break; + + case SADB_EXT_KEY_ENCRYPT: + if (iEncryptKey.iExt) + return; + iEncryptKey.iExt = (struct sadb_key *)p; + data_len = (iEncryptKey.iExt->sadb_key_bits + 7) / 8; + if (data_len == 0 || data_len + (int)sizeof(struct sadb_key) > ext_len) + return; + iEncryptKey.iData.Set(p + sizeof(struct sadb_key), data_len); + break; + + case SADB_EXT_IDENTITY_SRC: + { + if (iSrcIdent.iExt) + return; + iSrcIdent.iExt = (struct sadb_ident *)p; + data_len = ext_len - sizeof(struct sadb_ident); + if (data_len < 0) + return; + iSrcIdent.iData.Set(p + sizeof(struct sadb_ident), data_len); + TInt i = iSrcIdent.iData.Locate((TChar)0); + if (i >= 0) + iSrcIdent.iData.Set(iSrcIdent.iData.Ptr(), i); + break; + } + + case SADB_EXT_IDENTITY_DST: + { + if (iDstIdent.iExt) + return; + iDstIdent.iExt = (struct sadb_ident *)p; + data_len = ext_len - sizeof(struct sadb_ident); + if (data_len < 0) + return; + iDstIdent.iData.Set(p + sizeof(struct sadb_ident), data_len); + TInt i = iDstIdent.iData.Locate((TChar)0); + if (i >= 0) + iDstIdent.iData.Set(iDstIdent.iData.Ptr(), i); + break; + } + + case SADB_EXT_SENSITIVITY: + if (iSensitivity.iExt) + return; + iSensitivity.iExt = (struct sadb_sens *)p; + data_len = iSensitivity.iExt->sadb_sens_sens_len * 8; + iSensitivity.iSensBitmap.Set(p + sizeof(struct sadb_sens), data_len); + data_len2 = iSensitivity.iExt->sadb_sens_integ_len * 8; + iSensitivity.iSensBitmap.Set(p + (sizeof(struct sadb_sens) + data_len), + data_len2); + if (data_len + data_len2 + (int)sizeof(struct sadb_sens) > ext_len) + return; + break; + + case SADB_EXT_PROPOSAL: + if (iProposal.iExt) + return; + iProposal.iExt = (struct sadb_prop *)p; + iProposal.iNumComb = (ext_len - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb); + iProposal.iComb = (struct sadb_comb *)(p + sizeof(struct sadb_prop)); + break; + + case SADB_EXT_SUPPORTED_AUTH: + if (iAuthAlgs.iExt) + return; + iAuthAlgs.iExt = (struct sadb_supported *)p; + iAuthAlgs.iNumAlg = (ext_len - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg); + iAuthAlgs.iAlg = (struct sadb_alg *)(p + sizeof(struct sadb_supported)); + break; + + case SADB_EXT_SUPPORTED_ENCRYPT: + if (iEncryptAlgs.iExt) + return; + iEncryptAlgs.iExt = (struct sadb_supported *)p; + iEncryptAlgs.iNumAlg = (ext_len - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg); + iEncryptAlgs.iAlg = (struct sadb_alg *)(p + sizeof(struct sadb_supported)); + break; + + case SADB_EXT_SPIRANGE: + if (iSpirange.iExt) + return; + iSpirange.iExt = (struct sadb_spirange *)p; + break; + + /**--------------------------------------------------------------- + * + * PFKEY API general private extension. + * + *----------------------------------------------------------------*/ + case SADB_PRIV_GENERIC_EXT: + if (iPrivateExtension.iExt) + return; + iPrivateExtension.iExt = (struct sadb_gen_ext *)p; + data_len = (ext_len - sizeof(struct sadb_gen_ext)); + if (data_len > ext_len) + return; + iPrivateExtension.iData.Set(p + sizeof(struct sadb_gen_ext), data_len); + break; + + + case SADB_X_EXT_TS: + if (iTs.iExt) + return; + iTs.iExt = (struct sadb_x_ts *)p; + break; + + default: + // Unknown extensions must be ignored, not an error! + break; + } + p += ext_len; + length -= ext_len; + } + if (length != 0) + return; + + iError = KErrNone; // Message unpacked successfully + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/src/pfkeysocketif.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/src/pfkeysocketif.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,423 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of VPN PFKEY socket interface +* +*/ + + +#include +#include +#include +#include +#include +#include "pfkeysocketif.h" +#include "pfkeymsg.h" +#include "ipsecsadata.h" +#include "ipsecsalifetime.h" +#include "ikedebug.h" + +const TInt KDefaultPID( 0x2001E609 ); // UID3 of ikeutils.dll + +// ======== MEMBER FUNCTIONS ======== + +EXPORT_C CPFKeySocketIf* CPFKeySocketIf::NewL( MPFKeyMessageListener* aListener, + MIkeDebug& aDebug ) + { + CPFKeySocketIf* reader = new ( ELeave ) CPFKeySocketIf( aListener, aDebug ); + CleanupStack::PushL( reader ); + reader->ConstructL(); + CleanupStack::Pop( reader ); + return reader; + } + +// +// CPFKeySocketIf::~CPFKeySocketIf +// +CPFKeySocketIf::~CPFKeySocketIf() + { + Cancel(); + iPendingSpiRequests.Close(); + iSadb.Close(); + iSocketServer.Close(); + } + +// +// CPFKeySocketIf::CPFKeySocketIf +// +CPFKeySocketIf::CPFKeySocketIf( MPFKeyMessageListener* aListener, + MIkeDebug& aDebug ) +: CActive( EPriorityNormal ), + iListener( aListener ), + iSeq( 0 ), + iDebug( aDebug ) + { + CActiveScheduler::Add( this ); + } + +// +// CPFKeySocketIf::ConstructL() +// Open and activate the socket input +// +void CPFKeySocketIf::ConstructL() + { + TPtr8 ptr( (TUint8*)&iSpiBase, sizeof( iSpiBase ) ); + ptr.SetLength( sizeof( iSpiBase ) ); + TRandom::RandomL( ptr ); + iSpiBase &= 0x7fffffff; + + User::LeaveIfError( iSocketServer.Connect() ); + User::LeaveIfError( iSadb.Open( iSocketServer ) ); + + // + // Register for ACQUIRE messages + // + TPfkeySendMsg reg( SADB_REGISTER, SADB_SATYPE_ESP, ++iSeq, KDefaultPID ); + TRequestStatus status; + iSadb.FinalizeAndSend( reg, status ); + User::WaitForRequest( status ); + DEBUG_LOG1( _L("Register for ESP, status=%d"), iStatus.Int() ); + + iMsg.Reset(); + iSadb.ReadRequest( iMsg, iStatus ); + SetActive(); + } + + +void CPFKeySocketIf::GetSpi( const TUint8 aType, + const TUint32 aSeq, + const TInetAddr& aSrc, + const TInetAddr& aDst, + TUint32& aSpi, + TRequestStatus& aClientStatus) + { + /*Params: + aType:SADB_SATYPE_AH,SADB_SATYPE_ESP from prop_II + aSeq: Seq number for the message + aSrc,aDst: Src & dst addresses + */ + TRequestStatus status; + TUint32 start = NewSpi(); + + TPfkeySendMsg msg( SADB_GETSPI, aType, aSeq, (TUint32)&aClientStatus ); + msg.Add( Int2Type(), aSrc ); + msg.Add( Int2Type(), aDst ); + msg.Add( Int2Type(), start ); + + aClientStatus = KRequestPending; + TPendingSpiRequest pendingSpiRequest(aSpi, aClientStatus); + TInt err = iPendingSpiRequests.Append(pendingSpiRequest); + + if (err == KErrNone) + { + iSadb.FinalizeAndSend( msg, status ); + User::WaitForRequest( status ); + } + else + { + TRequestStatus* status = &aClientStatus; + User::RequestComplete(status, err); + } + } + + +void CPFKeySocketIf::CancelGetSpi(TRequestStatus& aClientStatus) + { + for (TInt i = 0; i < iPendingSpiRequests.Count(); ++i) + { + TPendingSpiRequest& pendingSpiRequest = iPendingSpiRequests[i]; + if (&pendingSpiRequest.iClientStatus == &aClientStatus) + { + pendingSpiRequest.iSpi = 0; + TRequestStatus* status = &pendingSpiRequest.iClientStatus; + iPendingSpiRequests.Remove(i); + User::RequestComplete(status, KErrCancel); + break; + } + } + } + + +// Sends Acquire with errno informing about key management failure. +EXPORT_C void CPFKeySocketIf::AcquireSAError( const TIpsecSAData& aSAData, + const TInt aError ) + { + TRequestStatus status; + TInt err = -aError; + TPfkeySendMsg msg( SADB_ACQUIRE, + aSAData.iSAType, + aSAData.iSeq, + aSAData.iPid ); + + struct sadb_msg& msgHdr = msg.MsgHdr(); + msgHdr.sadb_msg_errno = (TUint8) err; + msgHdr.sadb_msg_reserved = (TUint16) ( err>>8 ); + + msg.Add( Int2Type(), aSAData.iSPI ); + msg.Add( Int2Type(), aSAData.iDst ); + iSadb.FinalizeAndSend( msg, status ); + User::WaitForRequest( status ); + } + +EXPORT_C void CPFKeySocketIf::UpdateSAL( const TIpsecSAData& aSAData ) + { + AddUpdateSAL( SADB_UPDATE, aSAData ); + } + +EXPORT_C void CPFKeySocketIf::AddSAL( const TIpsecSAData& aSAData ) + { + AddUpdateSAL( SADB_ADD, aSAData ); + } + +EXPORT_C void CPFKeySocketIf::DeleteSA( const TUint32 aSPI, + const TInetAddr& aSrc, + const TInetAddr& aDst, + const TUint8 aProtocol ) + { + TRequestStatus status; + TPfkeySendMsg msg( SADB_DELETE, + aProtocol ); + msg.Add( Int2Type(), aSPI ); + msg.Add( Int2Type(), aSrc ); + msg.Add( Int2Type(), aDst ); + iSadb.FinalizeAndSend( msg, status ); + User::WaitForRequest( status ); + } + +EXPORT_C void CPFKeySocketIf::FlushSAs() + { + TRequestStatus status; + TPfkeySendMsg msg( SADB_FLUSH, + SADB_SATYPE_UNSPEC, + ++iSeq, + KDefaultPID ); + iSadb.FinalizeAndSend( msg, status ); + User::WaitForRequest( status ); + DEBUG_LOG1( _L("Request FLUSH, iStatus=%d"), iStatus.Int() ); + } + +//Updates an SA from the SA database. +//SPI in Net order. +void CPFKeySocketIf::AddUpdateSAL( const TUint8 aType, + const TIpsecSAData &aSAData ) + { + TRequestStatus status; + TPfkeySendMsg* msg = new( ELeave ) TPfkeySendMsg( aType, + aSAData.iSAType, + aSAData.iSeq, + aSAData.iPid ); + msg->Add( Int2Type(), + aSAData.iSPI, + aSAData.iAuthAlg, + aSAData.iEncrAlg, + SADB_SASTATE_MATURE, + aSAData.iReplayWindowLength, + aSAData.iFlags ); + + if( aSAData.iHard ) + { + msg->Add( Int2Type(), + aSAData.iHard->iAllocations, + aSAData.iHard->iBytes, + aSAData.iHard->iAddtime, + aSAData.iHard->iUsetime); + } + if( aSAData.iSoft ) + { + msg->Add( Int2Type(), + aSAData.iSoft->iAllocations, + aSAData.iSoft->iBytes, + aSAData.iSoft->iAddtime, + aSAData.iSoft->iUsetime); + } + msg->Add( Int2Type(), + aSAData.iSrc, + aSAData.iProtocol ); + msg->Add( Int2Type(), + aSAData.iDst, + aSAData.iProtocol ); + + // Deliver internal address for IPSEC4 + if ( aSAData.iFlags & SADB_SAFLAGS_INT_ADDR ) + msg->Add( Int2Type(), + aSAData.iInternalAddress ); + + if ( aSAData.iAuthKey.Length() > 0 ) + { + msg->Add( Int2Type(), + aSAData.iAuthKey ); + } + if ( aSAData.iEncrKey.Length() > 0 ) + { + msg->Add( Int2Type(), + aSAData.iEncrKey ); + } + if ( aSAData.iSrcIdent.Length() > 0 ) + { + msg->Add( Int2Type(), + aSAData.iSrcIdent, + aSAData.iSrcIdType ); + } + if ( aSAData.iDstIdent.Length() > 0 ) + { + msg->Add( Int2Type(), + aSAData.iDstIdent, + aSAData.iDstIdType ); + } + + // Deliver generic private PFKEY API extension, if exist. + // In this phase extension can consists NAT traversal information for ESP UDP encapsulation (done by IPSEC) + if ( aSAData.iGenericExtension.Length() ) + { + msg->Add( Int2Type(), + aSAData.iGenericExtension ); + } + + iSadb.FinalizeAndSend( *msg, status ); + User::WaitForRequest( status ); + delete msg; + } + +TUint32 CPFKeySocketIf::NewSpi() + { + iSpiBase++; + return iSpiBase; + } + +// +// SocketReader::ShowMessage +// Output actual "payload" messages (e.g. PFKEY) +// +#ifdef _DEBUG +void CPFKeySocketIf::ShowMessageL( TPfkeyRecvMsg &aMsg ) + { + HBufC* buffer = HBufC::NewL( 1000 ); + TPtr str( buffer->Des() ); + TPfkeyMessage msg( aMsg ); + + if ( msg.iError ) + { + str.Format( _L("Received malformed PFKEY msg of %d bytes: %d\n"), + aMsg.Length(), msg.iError ); + } + else + { + msg.iBase.String( str, _L(" ") ); + msg.iSa.String( str, _L(" ") ); + msg.iCurrent.String( str, _L(" C=") ); + msg.iHard.String( str, _L(" H=") ); + msg.iSoft.String( str, _L(" S=") ); + msg.iSrcAddr.String( str, _L(" SRC=") ); + msg.iDstAddr.String( str, _L(" DST=") ); + msg.iProxyAddr.String( str, _L(" PROXY=") ); + msg.iAuthKey.String( str, _L(" AUTHKEY=") ); + msg.iEncryptKey.String( str, _L(" ENCRYPTKEY=") ); + msg.iSrcIdent.String( str, _L(" SRCI=") ); + msg.iDstIdent.String( str, _L(" DSTI=") ); + msg.iSensitivity.String( str, _L(" SENS=") ); + msg.iProposal.String( str, _L(" PROP=") ); + msg.iAuthAlgs.String( str, _L(" AUTH=") ); + msg.iEncryptAlgs.String( str, _L(" ENCR=") ); + msg.iSpirange.String( str, _L(" SPIR=") ); + msg.iTs.String( str, _L(" TS=") ); + msg.iPrivateExtension.String( str, _L(" GEN_EXT=") ); + } + DEBUG_LOG( str ); + + delete buffer; + buffer = NULL; + } +#endif + +// +// CPFKeySocketIf::RunL +// Called when request completed +// +void CPFKeySocketIf::RunL() + { + if ( iStatus.Int() != KErrNone ) + { + DEBUG_LOG1( _L("Socket read, iStatus=%d"), iStatus.Int() ); + } + +#ifdef _DEBUG + TRAP_IGNORE( ShowMessageL( iMsg ) ); +#endif + + TPfkeyMessage msg(iMsg); + if ( ( msg.iError == KErrNone ) && + ( msg.iBase.iMsg->sadb_msg_errno == KErrNone ) ) // No error + { + switch ( msg.iBase.iMsg->sadb_msg_type ) + { + case SADB_GETSPI: + for (TInt i = 0; i < iPendingSpiRequests.Count(); ++i) + { + TPendingSpiRequest& pendingSpiRequest = iPendingSpiRequests[i]; + if ((TUint32)&pendingSpiRequest.iClientStatus == msg.iBase.iMsg->sadb_msg_pid) + { + pendingSpiRequest.iSpi = msg.iSa.iExt->sadb_sa_spi; + TRequestStatus* status = &pendingSpiRequest.iClientStatus; + iPendingSpiRequests.Remove(i); + User::RequestComplete(status, KErrNone); + break; + } + } + break; + case SADB_ADD: // Fall through + case SADB_UPDATE: // Fall through + case SADB_ACQUIRE: // Fall through + case SADB_EXPIRE: // Fall through + iListener->PfkeyMessageReceived( msg ); + break; + + default: + break; + } + } + else + { + DEBUG_LOG2( _L("Error in Pfkey message, iError=%d, sadb_msg_errno=%d"), + iStatus.Int(), msg.iBase.iMsg->sadb_msg_errno ); + } + iMsg.Reset(); + iSadb.ReadRequest( iMsg, iStatus ); // Start a new read + SetActive(); + } + +// +// CPFKeySocketIf::DoCancel +// Called when a pending request should be cancelled +// +void CPFKeySocketIf::DoCancel() + { + iSadb.CancelRecv(); + } + +// +// CPFKeySocketIf::RunError +// Called when RunL() leaves +// +TInt CPFKeySocketIf::RunError( TInt aError ) + { + DEBUG_LOG1( _L("CPFKeySocketIf::RunError() aError=%d, PFKEY message lost"), + aError ); + aError = aError; + + iMsg.Reset(); + iSadb.ReadRequest( iMsg, iStatus ); // Start a new read. + SetActive(); + + return KErrNone; // Active scheduler Error() method NOT called + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikeutils/src/vpnaddrinfo.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikeutils/src/vpnaddrinfo.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Utility for building internal address info. +* +*/ + + +#include "ikedebug.h" +#include "internaladdress.h" +#include "vpnmandefs.h" + +// CLASS HEADER +#include "vpnaddrinfo.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Build internal address info object from internal address information. +// --------------------------------------------------------------------------- +// +void VPNAddrInfo::BuildVPNAddrInfo( const CInternalAddress* aInternalAddr, + const TInetAddr& aDnsServerAddr, + TVPNAddress& aVPNAddress, + MIkeDebug& aDebug ) + { + __ASSERT_DEBUG( aInternalAddr != NULL, + User::Invariant() ); + + aVPNAddress.iVPNIfAddr = aInternalAddr->iClientIntAddr; + + // + // Add DNS address(es) to the virtual TVPNAddress object + // + TInt dnsCount = aInternalAddr->Count(); + if ( dnsCount ) + { + aVPNAddress.iVPNIfDNS1 = *(aInternalAddr->At(0)); + if ( dnsCount > 1 ) + { + aVPNAddress.iVPNIfDNS2 = *(aInternalAddr->At(1)); + } + } + else + { + if ( aDnsServerAddr.Address() != KAFUnspec ) + { +#ifdef _DEBUG + TBuf<39> addrBuf; + aDnsServerAddr.OutputWithScope( addrBuf ); + aDebug.LogWriteF(_L("DNS Server Address in IKE data %S"), &addrBuf); +#endif //_DEBUG + aVPNAddress.iVPNIfDNS1 = aDnsServerAddr; + } + else + { +#ifdef _DEBUG + aDebug.LogWrite(_L("DNS server not defined in policy")); +#endif // _DEBUG + } + } + } + + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/EABI/ikev1libU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/EABI/ikev1libU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + _Z12Ikev1PlugInLR17MKmdEventLoggerIfR9MIkeDebug @ 1 NONAME + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/bwins/IKEV1LIBU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/bwins/IKEV1LIBU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?Ikev1PlugInL@@YAPAVMIkePluginIf@@AAVMKmdEventLoggerIf@@AAVMIkeDebug@@@Z @ 1 NONAME ; class MIkePluginIf * Ikev1PlugInL(class MKmdEventLoggerIf &, class MIkeDebug &) + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Build information file +* +*/ + + +#include + +PRJ_PLATFORMS + +PRJ_EXPORTS + + +PRJ_MMPFILES +ikev1lib.mmp + +PRJ_TESTMMPFILES + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/group/ikev1lib.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/group/ikev1lib.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,77 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project ikev1lib +* +*/ + + + +#include + +TARGET ikev1lib.dll +TARGETTYPE DLL +UID 0x1000008d 0x10206994 + +CAPABILITY CAP_SERVER CommDD NetworkControl +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE ikev1crack.cpp +SOURCE ikev1crypto.cpp +SOURCE ikev1dialog.cpp +SOURCE ikev1extra.cpp +SOURCE ikev1infonegotiation.cpp +SOURCE ikev1keepalive.cpp +SOURCE ikev1natdiscovery.cpp +SOURCE ikev1negotiation.cpp +SOURCE ikev1payload.cpp +SOURCE ikev1plugin.cpp +SOURCE ikev1pluginsession.cpp +SOURCE ikev1private.cpp +SOURCE ikev1receiver.cpp +SOURCE ikev1sa.cpp +SOURCE ikev1sender.cpp +SOURCE ikev1timeout.cpp +SOURCE ikev1trans.cpp +SOURCE ikev1isakmpstream.cpp +SOURCE ikev1nokianattkeepalive.cpp + +USERINCLUDE ../inc +USERINCLUDE ../../ikesocket/inc +USERINCLUDE ../../kmdapi/inc +USERINCLUDE ../../kmdserver/inc +USERINCLUDE ../../ikecert/inc +USERINCLUDE ../../eventmediatorapi/inc +USERINCLUDE ../../ikepolparser/inc +USERINCLUDE ../../vpnmanager/inc +USERINCLUDE ../../utlcrypto/inc +USERINCLUDE ../../pkiserviceapi/inc +USERINCLUDE ../../vpncommon/inc +USERINCLUDE ../../../vpnapiimpl/inc +USERINCLUDE ../../ikeutils/inc + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY euser.lib +LIBRARY esock.lib +LIBRARY insock.lib +LIBRARY efsrv.lib +LIBRARY utlcrypto.lib +LIBRARY ikecert.lib +LIBRARY ikepolparser.lib +LIBRARY ikesocket.lib +LIBRARY random.lib +LIBRARY ikeutils.lib + + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1SA.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1SA.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,116 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv1 SA +* +*/ + + +#ifndef C_IKEV1SA_H +#define C_IKEV1SA_H + +#include "ikev1SAdata.h" +#include "ikev1keepalive.h" + +#define SECOND 1000000 // One second is 1000000 us. (1 us. per tick) +#define ISAKMP_DELETE_TIME 2*SECOND //Expiration time for a ISAKMP SA after it's erased + +class CIkev1PluginSession; +class CIkev1NokiaNattKeepAlive; +class MIkeDebug; + +//List of the IPSEC SAs negotiated by the ISAKMP SA +NONSHARABLE_CLASS(CIpsecSPIList) : public CArrayPtrFlat +{ + public: + CIpsecSPIList(TInt aGranularity); + ~CIpsecSPIList(); +}; + +NONSHARABLE_CLASS(CIkev1SA) : public CTimer, public MDpdHeartBeatEventHandler +{ + public: + static CIkev1SA* NewL( CIkev1PluginSession& aPluginSession, + TIkev1SAData& aIkev1SAdata, + CSARekeyInfo* aSaRekey, + MIkeDebug& aDebug ); + ~CIkev1SA(); + + void UpdateSAL( TBool aExpired, + TIkev1SAData* aIkev1SAdata ); + void ExpireSA(); + void AddIpsecSPIL( TIpsecSPI& aIpsecSpi ); + TBool FindIpsecSPI( TUint32 aSPI, + TBool aInbound ); + TBool DeleteIpsecSPI( TUint32 aSPI, + TBool aInbound ); + /** + * Deletes IPsec SAs and sends delete payload to the GW. + */ + void DeleteIpsecSAs(); + /** + * Deletes IPsec SAs without sending delete payload to the GW. + * Used when connection is lost. + */ + void DeleteIpsecSAsForced(); + void SetExpired(); + inline TBool IsExpired() {return iExpired;} + void EventHandlerL(); + + inline void SetDeactivating( TBool aDeactivating ) { iDeactivating = aDeactivating; } + inline TBool IsDeactivating() { return iDeactivating; } + + void CancelRekey(); + + protected: + // + // CActive methods + // + void DoCancel(); + void RunL(); + TInt RunError(TInt aError); + + private: + CIkev1SA( CIkev1PluginSession& aPluginSession, + MIkeDebug& aDebug ); + void ConstructL( TIkev1SAData& aIkev1SAdata, + CSARekeyInfo* aSaRekey ); + + void StartTimer(); + + public: + TIkev1SAData iHdr; // Common negotiation info + CIpsecSPIList* iSPIList; //Contains a SPIs List to know the direction when a delete received + + private: + CIkev1PluginSession& iPluginSession; + + TUint32 iRemainingTime; //Timer remaining + TUint32 iRemainingKB; //KB life remaining + TUint32 iCurrentBytes; //Bytes life currently added + + TUint32 iLeftOverTime; //Time remaining after rekey started + TBool iRekeyed; //Rekeyed SA + + CIkeV1KeepAlive* iIkeKeepAlive; // Pointer to common IKE keepalive object + + TBool iExpired; //The ISAKMP SA may be expired but waiting possible delete IPSEC SA msgs that arrive after + + CIkev1NokiaNattKeepAlive *iNokiaNatt; // Pointer to Nokia NAT-T keepalive object + + TBool iDeactivating; + + MIkeDebug& iDebug; +}; + +#endif // C_IKEV1SA_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1SAdata.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1SAdata.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,220 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv1 SA data definition +* +*/ + + +#ifndef T_IKEV1SADATA_H +#define T_IKEV1SADATA_H + +#include "internaladdress.h" +#include "ikemsgheader.h" +#include "ikev1payloads.h" + +class CIkeData; + +#define IKEV1_KEY_MATERIAL_SIZE 64 +#define IKEV1_MAX_IV_SIZE 20 //Max hash algorithm output size +#define DEFAULT_MAX_ISAKMP_LIFETIME 28000 //for security reasons + +// Class TIkev1SAData is the IKEv1 SA parameter definition +// which is used to pass SA information between IKE server and IKEv1 +// plug-in. +class TIkev1SAData +{ +public: + TIkev1SAData() + :iCookie_I(), + iCookie_R(), + iSAId(0), + iSAState(0), + iInitiator(EFalse), + iDPDSupported(EFalse), + iFamiliarPeer(EFalse), + iNAT_T_Required(EFalse), + iAutoLogin(EFalse), + iNAT_D_Flags(0), + iIkeData(NULL), + iLocalAddr(), + iRemoteAddr(), + iDestinAddr(), + iVirtualIp(NULL), + iSeq(0), + iPrevExchange(0), + iFlags(0), + iEncrAlg(0), + iHashAlg(0), + iAuthMethod(0), + iGroupDesc(0), + iGroupType(0), + iKeyLength(0), + iPRF(0), + iLifeTimeSecs(0), + iLifeTimeKB(0), + iDPDRetry(0), + iDPDSequence(0), + iPendingDPDSequence(0), + iExpectedDPDSequence(0), + iLastIKEMsgInfo(), + iLastMsg(NULL) + {} + inline void CleanUp() + { + delete iVirtualIp; + iVirtualIp = NULL; + delete iLastMsg; + iLastMsg = NULL; + } + inline void StoreVirtualIp(CInternalAddress* aVirtualIp) + { + delete iVirtualIp; + iVirtualIp = aVirtualIp; + } + inline void CopyL(TIkev1SAData& aSrc) + { + CInternalAddress* SavedVip = iVirtualIp; + HBufC8* SavedLastMsg = iLastMsg; + Mem::Copy((TUint8*)&iCookie_I, (TUint8*)&aSrc.iCookie_I, sizeof(TIkev1SAData)); + iVirtualIp = SavedVip; + iLastMsg = SavedLastMsg; + if ( aSrc.iVirtualIp ) + { + StoreVirtualIp(CInternalAddress::NewL(*(aSrc.iVirtualIp))); + } + if ( aSrc.iLastMsg && + aSrc.iLastMsg != iLastMsg ) + { + delete iLastMsg; + iLastMsg = aSrc.iLastMsg->AllocL(); + } + } + +public: + TCookie iCookie_I; // Initiator Cookie + TCookie iCookie_R; // Responder Cookie + TUint32 iSAId; // Internal negotiation Id + + TInt iSAState; // IKE SA State + TBool iInitiator; // TRUE if local end is initiator + TBool iDPDSupported; // Both ends support DPD + TBool iFamiliarPeer; // Nokia VPN implementation detected in peer + TBool iNAT_T_Required; // True when NAT detected between local end and peer + TBool iAutoLogin; // SA negotiated due RKMD::Activate request + TUint32 iNAT_D_Flags; // If not zero, there is NAT between sites + + CIkeData* iIkeData; + + TInetAddr iLocalAddr; + TInetAddr iRemoteAddr; // Remote Address ("From Policy") + TInetAddr iDestinAddr; // Current peer destination address and port + CInternalAddress* iVirtualIp; // Virtual IP address (and DNS addresses) + + TUint32 iSeq; // For PFKEY API + TUint8 iPrevExchange; // Used to process the last msg of Phase I + TUint8 iFlags; // Flags in the msg header + // + // Selected IKE SA proposal + // + TUint16 iEncrAlg; //OAKLEY encryption function + TUint16 iHashAlg; //OAKLEY hash function + TUint16 iAuthMethod; //OAKLEY authentication function + TUint16 iGroupDesc; //OAKLEY GROUP + TUint16 iGroupType; //OAKLEY GROUP type + TUint16 iKeyLength; //Encryption key length + TUint16 iPRF; //Reserved + TUint32 iLifeTimeSecs; //SA lifetime seconds + TUint32 iLifeTimeKB; //SA lifetime KiloBytes + + // + // IKE SA DPD (keep alive) protocol parameters + // + TInt iDPDRetry; + TUint32 iDPDSequence; + TUint32 iPendingDPDSequence; + TUint32 iExpectedDPDSequence; + + // Last IKE msg info + TLastIKEMsg iLastIKEMsgInfo; + HBufC8* iLastMsg; + TInetAddr iLastRemoteAddr; + + // + // IKEv1 keymaterial + // + TBuf8 iSKEYID; //KEY used for encryption/decryption of messages + TBuf8 iSKEYID_d; //KEY used to derive keys for non-ISAKMP SAs + TBuf8 iSKEYID_a; //KEY used for authentication of ISAKMP messages + TBuf8 iSKEYID_e; //KEY used for encryption/decryption of ISAKMP messages + + TBuf8 iIV; //normal IV + TBuf8 iLastIV; //Saves the last IV of PHASE_I to compute iNotifIV everytime and the first IV in Quick mode + +}; + + +class CSARekeyInfo : public CBase +{ + public: + static CSARekeyInfo* NewL(const TCookie& aICookie, const TCookie& aRCookie, + CInternalAddress* aInternalAddr) + { + return new (ELeave) CSARekeyInfo(aICookie, aRCookie, aInternalAddr); + } + ~CSARekeyInfo() + { + delete iInternalAddr; + } + + inline const TCookie& GetCookieI() { return iCookie_I;} + inline const TCookie& GetCookieR() { return iCookie_R;} + inline CInternalAddress* GetInternalAddr() + { + CInternalAddress* VirtualIp = iInternalAddr; + iInternalAddr = NULL; + return VirtualIp; + } + + private: + CSARekeyInfo(const TCookie& aICookie, const TCookie& aRCookie, + CInternalAddress* aInternalAddr) + :iCookie_I(aICookie), + iCookie_R(aRCookie), + iInternalAddr(aInternalAddr) + {} + + private: + TCookie iCookie_I; // Initiator Cookie of the IKE SA rekeyed + TCookie iCookie_R; // Responder Cookie of the IKE SA rekeyed + CInternalAddress* iInternalAddr; + +}; + + +class TIpsecSPI +{ + public: + TIpsecSPI() + :iSrcAddr(), iDstAddr(), iSPI(0), iInbound(EFalse), iProtocol(0) + {}; + public: + TInetAddr iSrcAddr; + TInetAddr iDstAddr; + TUint32 iSPI; + TBool iInbound; // Inbound = ETrue + TUint8 iProtocol; + TUint8 iReserved[3]; +}; + +#endif // T_IKEV1SADATA_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1crack.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1crack.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,124 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv1 Crack authentication +* +*/ + +#ifndef IKEV1CRACK_H +#define IKEV1CRACK_H + +#include +#include "ikev1dialog.h" + +/*--------------------------------------------------------------------------- + * + * CRACK return codes for public methods + * + *---------------------------------------------------------------------------*/ +#define CRACK_SUCCESS 0 +#define CRACK_CONTINUE 0x1 +#define CRACK_IGNORE_MSG 0x2 +#define CRACK_FAILED 0x4 + +/*--------------------------------------------------------------------------- + * + * CRACK iState flags + * + *---------------------------------------------------------------------------*/ +#define WAITING_USER_RSP 0x1 +#define WAITING_PEER_RSP 0x2 +#define CHALLENGE_RECEIVED 0x4 +#define CRACK_AUTHENTICATED 0x8 +#define SHOW_ERROR_DIALOG 0x10 +#define SECURID_NEXT_PIN_MODE 0x20 + +/*--------------------------------------------------------------------------- + * + * CAuthDialogInfo class + * + *---------------------------------------------------------------------------*/ +#define DIALOG_INFO_ID 0xfedcba98 +#define XAUTH_DIALOG_ID 0x76543210 + +class CIkev1Negotiation; +class TNotificationISAKMP; +class TCHREISAKMP; +class ThdrISAKMP; +class CIkev1PluginSession; +class MIkeDebug; + +class CAuthDialogInfo : public CBase + { +public: + CAuthDialogInfo(CIkev1PluginSession* aPluginSession, TUint32 aObjId, TUint32 aSAId, TUint32 aMsgId) + { iPluginSession = aPluginSession; iSAId = aSAId; iObjId = aObjId; iMsgId = aMsgId; } + ~CAuthDialogInfo() {iObjId = 0;} + inline CIkev1PluginSession* PluginSession() { return iPluginSession;} + inline TUint32 SAId() { return iSAId;} + inline TUint32 GetObjId() { return iObjId;} + inline TUint32 GetMsgId() { return iMsgId;} + +private: + TUint32 iObjId; // Object identifier + CIkev1PluginSession* iPluginSession; // Plugin session pointer + TUint32 iSAId; // SA id of CIkev1Negotiation + TUint32 iMsgId; // Transaction exchange message ID + +public: +// Credentials data get from user with asynchronous dialog + HBufC8 *iUsername; + HBufC8 *iSecret; + HBufC8 *iDomain; + }; + + +NONSHARABLE_CLASS(CIKECRACKNegotiation) : public CBase, public MIkeDialogComplete +{ +public: + CIKECRACKNegotiation( MIkeDebug& aDebug ); + ~CIKECRACKNegotiation(); + TInt ConstructL(TInt aLAMType, CIkev1Negotiation *aNegotiation, const TDesC &aDomain); + TInt ExecuteCRACKMsgL(const ThdrISAKMP &aHdr); + TInt ProcessUserResponseL(CAuthDialogInfo *aUserInfo); + TInt CrackAuthenticationFailedL(const TNotificationISAKMP *aNotifPayload); + + TInt DialogCompleteL(CIkev1Dialog* /*aDialog*/, TAny* aUserInfo, HBufC8* aUsername, HBufC8* aSecret, HBufC8* aDomain); + + +private: + TInt GetDataL(HBufC8* aChallenge); + TInt GetDatafromUserL(HBufC8 *aChallenge); + TInt GetUNPWDFromPolicyL(); + TInt ProcessCHREAttibutesL(const TCHREISAKMP *aCHRE_PAYLOAD); + void SendCredentialsL(TUint16 aAttr1, TUint16 aAttr2, TUint16 aAttr3, + HBufC8* aBfr1, HBufC8* aBfr2, HBufC8* aBfr3); + +private: + TInt iLAMType; // Legacy Authentication Method type code + TInt iState; // CRACK negotiation state + TInt iMsgCount; // CRACK message count xmitted (does not contain retries) + + CIkev1PluginSession* iPluginSession; // IKEv1 plugin session + CIkev1Negotiation* iNegotiation; // Current negotiation object (related to CRACK) + CIkev1Dialog* iDialog; // Pending dialog object + CAuthDialogInfo* iDialogInfo; // Dialog info object + + HBufC8 *iUserName; // Saved for User name caching + HBufC8 *iDomain; // Fixed domain value for this CRACK negotiation + + MIkeDebug& iDebug; +}; + + +#endif // IKEV1CRACK_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1crypto.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1crypto.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,90 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Cryptographic Intermediate Layer to use and change any crypto library easily. +* +*/ + +#ifndef IKEV1CRYPTO_H +#define IKEV1CRYPTO_H + +#include +#include "ikev1isakmpct.h" + + +class CUtlDiffieHellman; + +NONSHARABLE_CLASS(CIkeKeys) : public CBase +{ +public: + static CIkeKeys* NewL(const TDesC8& aN,const TDesC8& aG); + HBufC8 *GetPubKey(); + void XValueL(); + const HBufC8* KValueL(const TDesC8& aY) const; + inline TInt ModulusLength() {return iModuluslength;} + + ~CIkeKeys(); +private: + CUtlDiffieHellman* iDHKey; + const HBufC8* iPubKey; + TInt iModuluslength; +}; + + +// SSL function implementation using Symbian apis +// - des_ede3_cbc_encrypt +#define DES_ENCRYPT 1 +#define DES_DECRYPT 0 + +#define HMAC_MD5_SIZE 128 +#define HMAC_SHA1_SIZE 160 + +#define DESCBC_KEY_LEN 8 +#define DESCBC_IV_LEN 8 + +#define AESCBC_DEF_KEY_LEN 16 +#define AESCBC_IV_LEN 16 + +#define DEFAULT_NONCE_SIZE 128/8 //128 bits = 16 bytes + +#define PAD_SIZE 64 + 2 * DEFAULT_NONCE_SIZE + 1000 + +//DH functions +CIkeKeys* GeneratePubPrivKeysL(TUint aGroupDesc); +HBufC8* ComputeAgreedKeyL(TUint aGroupDesc, const TDesC8 &aPeerPublicKey, CIkeKeys *aOwnKeys); + +// +//Symmetric encryption/decryption functions +// +void DecryptL(const TUint8* aInputPayload, TUint8* aOutputPayload, TUint32 aLength, TDes8 &aIV, TDesC8& aKey, TUint16 aEncrAlg); +TBool EncryptL(TDes8& aInputPayload, TDes8& aOutputPayload,TDes8 &aIV, TDesC8& aKey , TUint16 aEncrAlg); +void Cipher3DesL(TUint8 *aInData, TInt aInDataLen, const TDesC8 &aPrfKey, TDes8 &aIV, TDes8 &aPrfOutput); + +// +//Message Digest Algorithms +// +void MD5HashL(const TDesC8 &aInData, TDes8& aOutData); +void SHA1HashL(const TDesC8 &aInData, TDes8& aOutData); + +void MD5HmacL(const TDesC8 &aInData, TDes8& aOutData, const TDesC8& aKeyData); +void SHA1HmacL(const TDesC8 &aInData, TDes8& aOutData, const TDesC8& aKeyData); + +//The length of aInData must be less than PAD_SIZE. The caller of this function +//has to take care of handling the size of this parameter. +void Hmac3DesCbcL(const TDesC8 &aInData, TDes8& aOutData, const TDesC8& aKeyData); + +TInt SymmetricCipherL(TUint8 *aInput, TUint8 *aOutput, TInt aLength, + TUint8 *aKey, TUint8 *aIV, TBool aEncr, TInt aEncAlg = DES_CBC); + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1dialog.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1dialog.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,142 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: CIkeDialog class headers +* +*/ + +#ifndef C_IKEV1DIALOG_H +#define C_IKEV1DIALOG_H + + +#include +#include +#include "vpnnotifierdefs.h" + +class CIkev1Dialog; +class CIkev1PluginSession; +class RFs; +class MIkeDebug; + +/** +* IKE dialog complete +* @internalComponent +*/ +class MIkeDialogComplete +{ + public: + /** + * IKE dialog completed + * @internalComponent + * + */ + virtual TInt DialogCompleteL(CIkev1Dialog* aDialog, TAny* aUserInfo, HBufC8* aUsername, HBufC8* aSecret, HBufC8* aDomain)=0; +}; + + + +NONSHARABLE_CLASS(CDialogTimeout) : public CTimer +{ +public: + CDialogTimeout( MIkeDebug& aDebug ); + ~CDialogTimeout(); + void ConstructL(CIkev1Dialog* aDialog); + +protected: + // will cancel the current dialog + void RunL(); + void DoCancel(); + +protected: // data + CIkev1Dialog* iDialog; //Needed to cancel a dialog + +private: // data + MIkeDebug& iDebug; +}; + + +NONSHARABLE_CLASS(CIkev1Dialog) : public CActive +{ +public: + static CIkev1Dialog* NewL( CIkev1PluginSession* aPluginSession, + CIkev1Dialog** aToQueAnchor, + MIkeDebug& aDebug ); + CIkev1Dialog( MIkeDebug& aDebug ); + ~CIkev1Dialog(); + + void GetAsyncUNPWDialogL(TAny *aUserInfo, MIkeDialogComplete* aCallback); + void GetAsyncUNAMEDialog(TAny *aUserInfo, MIkeDialogComplete* aCallback); + void GetAsyncSecureidDialogL(TAny *aUserInfo, MIkeDialogComplete* aCallback); + void GetAsyncSecureNextPinDialogL(TAny *aUserInfo, MIkeDialogComplete* aCallback); + void GetAsyncRespDialog(TPtr8 aChallenge, TAny *aUserInfo, MIkeDialogComplete* aCallback); + void ShowErrorDialogL(TInt aDialogType, TAny *aUserInfo, MIkeDialogComplete* aCallback); + void StoreUserNameL(TPtr8 aUserName); + void StartDialogL(); + TInt GetSyncUNPWCacheDialog(TDes& aUserName, TDes& aPassword); + + static TInt GetSyncUNPWDialog(TDes& aUserName, TDes& aPassword); + static void PurgeDialogQueue(CIkev1Dialog* aQueuedDialog); + + inline CIkev1PluginSession* PluginSession() { return iPluginSession;} + inline CIkev1Dialog* NextDialog() { return iNext;} + inline MIkeDialogComplete* Callback() { return iCallback;} + inline TAny* UserInfo() { return iUserInfo;} + +protected: + // active object stuff, completion and cancel callback functions + void RunL(); + void DoCancel(); + +private: + void ConstructL(CIkev1PluginSession* aPluginSession, CIkev1Dialog* *aToQueAnchor); + void LaunchDialogL(); + TInt QueueDialog(CIkev1Dialog* aDialog); + void DeQueueDialog(CIkev1Dialog* aDialog); + HBufC8* CreateDialogInput(TIPSecDialogInfo& aDialogInfo, TBool aUserNameCache); + HBufC8* GetUserNameFromFile(); + static TBool BuildEncryptionKey(const TDesC8& aSalt, TDes8& aEncryptionKey); + static TInt LauchSyncDialog(const TDesC8& aInput, TDes8& aOutput); + static HBufC8* ConvertPwdToOctetString(TDesC &aUnicodeBfr); + +private: + CIkev1PluginSession* iPluginSession; + RFs iFs; + CIkev1Dialog** iToQueAnchor; // Waiting queue anchor + CIkev1Dialog* iNext; // For waiting queue + TAny* iUserInfo; + MIkeDialogComplete* iCallback; + TInt iDialogType; + CDialogTimeout* iTimeout; + RNotifier iNotifier; + HBufC8* iInputData; + TPckgBuf iResponseBuf; + MIkeDebug& iDebug; +}; + +/**-------------------------------------------------------------------------- + * + * Structure TUserNameFileHdr + * User name (encrypted) cache file header. + * In this file is cached the last user name used in legacy + * authentication. + * + *--------------------------------------------------------------------------*/ +#define USER_NAME_FILE_ID 0xcccccccc +struct TUserNameFileHdr +{ + TUint8 iSalt[8]; + TUint8 iIV[8]; + TUint32 iFileId; +}; + +#endif // C_IKEV1DIALOG_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1extra.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1extra.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,250 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Key management daemon extra module. +* +*/ + +#ifndef IKEV1EXTRA_H +#define IKEV1EXTRA_H + +// +// Structures to manage proposal and attribute lists +// + +#include +#include +#include "ikev1isakmpct.h" + +//Maximum size of the SPI. 16 is ISAKMP SPI, others SPI are defined by its DOI +//but the supported ones have a smaller size (AH=? , ESP=? ) +#define MAX_SPI_SIZE ISAKMP_SPI_SIZE +#define ISAKMP_SPI_SIZE 16 + +#define MAX_LIFE_DURATION 16 //up to 2^16 secs. or KBytes +#define MAX_PRIME_SIZE 256 //the biggest is Oakley group 2 prime is 256 hex digits +#define MAX_GEN_SIZE 2 //the biggest is Oakley group 3 generator is 2 hex digits. (Could be fix size) +#define MAX_CURVE_SIZE 6 //the biggest is Oakley group 3 curve B is 6 hex digits. +#define MAX_ORDER_SIZE 48 //the biggest is Oakley group 4 order is 48 hex digits. +// +// Start numbers for Proposal-and Transform payload numbering +// +#define FIRST_ISAKMP_PROPOSAL 0 +#define FIRST_IPSEC_PROPOSAL 0 +#define FIRST_ISAKMP_TRANSFORM 0 +#define FIRST_IPSEC_TRANSFORM 0 + + +// Attribute comparison errors +// Leave -1 free to use KErrNotFound for empty lists +const TInt KErrTransformID = -2; //different transform IDs +const TInt KErrEncrAlg = -3; //different encr algs. +const TInt KErrHashAlg = -4; //different hash algs. +const TInt KErrAuthMethod = -5; //different auth. methods. +const TInt KErrGroupDesc = -6; +const TInt KErrGroupType = -7; +const TInt KErrGroupPrime = -8; +const TInt KErrGroupGen1 = -9; +const TInt KErrGroupGen2 = -10; +const TInt KErrGroupCurveA = -11; +const TInt KErrGroupCurveB = -12; +const TInt KErrPRF = -13; +const TInt KErrKeyLength = -14; +const TInt KErrFieldSize = -15; +const TInt KErrGroupOrder = -16; +const TInt KErrLifeTime = -17; +const TInt KErrLifeSize = -18; +//const TInt KErrTransfNum = -19; +const TInt KErrEncMode = -20; +const TInt KErrAuthAlg = -21; +const TInt KErrKeyRounds = -22; +const TInt KErrComprDicSize = -23; +const TInt KErrComprPrivAlg = -24; +const TInt KErrTransformNum = -25; +const TInt KErrPropProtocol = -26; //Proposals have different protocol. +const TInt KErrNoTransforms = -27; //Proposal has no transforms +const TInt KErrNoRemoteProposals= -28; //Remote Proposals list is empty +const TInt KErrNoLocalProposals = -29; //Local Proposals list is empty +const TInt KErrPropNumberMismatch= -30; //The proposals lists have fiferent number of AND'd proposals + + +//Global functions +TInt Desc8ToTInt64(const TDesC8 &aLifetime, TInt64 &aTime); //Puts the data in the descriptor into a TInt64 +TInt PrefixLen(TInetAddr& anAddr); //returns the prefix length of a mask +void PrefixMask(TInetAddr &anAddr, TInt aPrefixLen, TInt aFamily); //Creates a addr. mask of aPrefixLen length + +enum TLifeType {LIFETIME, LIFESIZE, NOLIFE}; +//Mantains SA attrib info for Phase I negotiation. Defined by IKE RFC 2409 +class TAttrib +{ +public: + TAttrib() + { + iTransformNum=0; + iTransformID=0; + iEncrAlg=0; + iHashAlg=0; + iAuthMethod=0; + iGroupDesc=0; + iGroupType=0; + iPRF=0; + iKeyLength=0; + iFieldSize=0; + iXauthUsed=EFalse; + iRole=0; + + iNext=NULL; + }; + TInt Compare(TAttrib& aAttr, TBool aIsRelaxed); + +public: + TUint8 iTransformNum; //Transform number + TUint8 iTransformID; //Transform ID + TUint16 iEncrAlg; //OAKLEY encryption function (part of EHAO/EHAS) + TUint16 iHashAlg; //OAKLEY hash function (part of EHAO/EHAS) + TUint16 iAuthMethod; //OAKLEY authentication function(part of EHAO/EHAS) + TUint16 iGroupDesc; //OAKLEY GROUP + TUint16 iGroupType; + TBuf8 iGroupPrime; + TBuf8 iGroupGen1; + TBuf8 iGroupGen2; + TBuf8 iGroupCurveA; + TBuf8 iGroupCurveB; + //TUint16 iLifeType; //Not needed + TBuf8 iLifeDurationSecs; + TBuf8 iLifeDurationKBytes; + TUint16 iPRF; + TUint16 iKeyLength; + TUint16 iFieldSize; + TBuf8 iGroupOrder; + + TBool iXauthUsed; // Used for iAuthMethod value modification + TInt iRole; // Used for iAuthMethod value modification + + TAttrib *iNext; + +}; + +class TProposal +{ +public: //To ensure correct initialization + TProposal() + { + iProposalNum=0; + iProtocol=0; + iNumTransforms=0; + iAttrList=NULL; + } +public: + TUint8 iProposalNum; + TUint8 iProtocol; // Protocol ID in use + TBuf8 iSPI; // SPI in the current exchange. SPI is in network order + TUint8 iNumTransforms; + + TAttrib *iAttrList; //Contains the list of transforms and attribs + //Only ONE proposal in Phase I + //TProposal *iNext; +}; + +class TTransModifier +{ +public: + TTransModifier() : iReducedLifeSecs(NULL,0), iReducedLifeKBytes(NULL,0) {} ; +public: + TInt iPropNum; //Local proposal number selected + TInt iTransNum; //Remote transform number selected + TPtrC8 iReducedLifeSecs; //Own lifetime (in case is smaller then received) + TPtrC8 iReducedLifeKBytes; //Own lifesize (in case is smaller then received) + TUint8 iReplayWindowLength; +}; + +NONSHARABLE_CLASS(CTransModifierList) : public CArrayPtrFlat +{ +public: + CTransModifierList(TInt aGranularity); + ~CTransModifierList(); +}; + +//#define MAX_ALG_DATA 1024 //4 + ?? vendor data +#define MAX_ALG_DATA 16 //Feature not supported, size reduced +//Mantains SA attrib info for Phase II negotiation. Defined by IPSEC DOI (RFC 2407) +class TAttrib_II +{ +public: + TAttrib_II(); + TInt Compare(TAttrib_II& aAttr, TBool aRelaxed); + void Copy(TAttrib_II &aAttr); +public: + TUint8 iTransformNum; //Transform number + TUint8 iTransformID; //Transform ID + TBuf8 iLifeDurationSecs; + //TBool iLifetimeReduced; + TBuf8 iLifeDurationKBytes; + //TBool iLifesizeReduced; + TUint16 iGroupDesc; //OAKLEY GROUP + TUint16 iEncMode; //Encapsulation Mode + TUint16 iAuthAlg; //HMAC + TUint16 iKeyLength; + TUint16 iKeyRounds; + TUint16 iComprDicSize; //Compress Dictionary size + TBuf8 iComprPrivAlg; + + //TAttrib_II *iNext; //to make a list +}; + +class TChosenAttrib_II : public TAttrib_II +{ +public: + TChosenAttrib_II() : TAttrib_II(), iReducedLifeSecs(NULL,0), iReducedLifeKBytes(NULL,0) {} ; +public: + TPtrC8 iReducedLifeSecs; + TPtrC8 iReducedLifeKBytes; +}; + +NONSHARABLE_CLASS(CAttrib_IIList) : public CArrayPtrFlat +{ +public: + CAttrib_IIList(TInt aGranularity); + ~CAttrib_IIList(); +}; + +NONSHARABLE_CLASS(CProposal_II) : public CBase +{ +public: //To ensure correct initialization + + void ConstructL(TInt aGranularity = 1); + ~CProposal_II(); +// TInt Match(CProposal_II *aRemoteProp, TBool aRelaxed); + TInt Match(CProposal_II *aRemoteProp, TBool aRelaxed, TInt* aLocalNbr); + +public: + TUint8 iProposalNum; + TUint8 iProtocol; // Protocol ID in use + TUint8 iReplayWindowLength; // replay window size in bits + TBuf8 iSPI; // SPI in the current exchange. SPI is in network order + TUint8 iNumTransforms; + + //TAttrib_II *iAttrList; //Contains the list of transforms and attribs + CAttrib_IIList *iAttrList; //Contains the list of transforms and attribs + //CProposal_II *iNext; +}; + + +NONSHARABLE_CLASS(CProposal_IIList) : public CArrayPtrFlat +{ +public: + CProposal_IIList(TInt aGranularity); + TInt MultiMatchL(CProposal_IIList *aRemoteProp, TBool aRelaxed, CTransModifierList *aTransArray); + ~CProposal_IIList(); +}; +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1filesdef.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1filesdef.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 1999-2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IPSEC/IKE configuration file macros +* +*/ + + +// +// Includes the path of all the relevant security files and directories +// + +#ifndef IKEV1FILESDEF_H +#define IKEV1FILESDEF_H + +//Global Keys file +#define DEFAULT_IKE_FILE _L("C:\\System\\Data\\Security\\IPSEC\\ike.conf") + +#define USER_NAME_CACHE_FILE _L("un") + +#endif // IKEV1FILESDEF_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1infonegotiation.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1infonegotiation.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: CIkev1InfoNegotiation class +* +*/ + +#ifndef C_IKEV1INFONEGOTIATION_H +#define C_IKEV1INFONEGOTIATION_H + +#include + +class CIkev1Negotiation; +class CIkev1PluginSession; +class ThdrISAKMP; +class TPayloadISAKMP; +class TNotificationISAKMP; +class MIkeDebug; +class MKmdEventLoggerIf; +class TInetAddr; + +class CIkev1InfoNegotiation : public CBase +{ + friend class TIkev1IsakmpStream; + friend class CIkev1PlugIn; + +public: + CIkev1InfoNegotiation( CIkev1PluginSession& aPluginSession, + CIkev1Negotiation& aNegotiation, + MIkeDebug& aDebug ); + void ExecuteL( const ThdrISAKMP& aHdr, + const TInetAddr& aSrcAddr, + TInt aLocalPort ); + + MKmdEventLoggerIf& EventLogger(); + +private: + void InfoExchangeL( const ThdrISAKMP& aHdr ); + TBool ProcessNotificationL( const TPayloadISAKMP* aPayload, TBool aEncrypted ); + TBool ProcessDeleteL( const TPayloadISAKMP* aPayload ); + TBool ProcessDPDNotifyL( TNotificationISAKMP* aNotify ); + +private: + CIkev1PluginSession& iPluginSession; + CIkev1Negotiation& iNegotiation; + TUint32 iMessageId; + MIkeDebug& iDebug; +}; + +#endif // C_IKEV1INFONEGOTIATION_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1isakmpct.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1isakmpct.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,456 @@ +/* +* Copyright (c) 1999-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: key management daemon ISAKMP constants +* +*/ + + +// +// ISAKMP constants defines in RFC 2409 (IKE) and 2407(IPSEC DOI) +// + +#ifndef ISAKMPCT_H +#define ISAKMPCT_H + +// +// All Headers with values in network byte order +// + +#define DEFAULT_IPSEC_SA_LIFETIME 28000 //RFC 2407 (DOI) +#define MIN_ISAKMP_PAYLOAD_SIZE 4 + +//Version of the implementation 1.0 +#define MAJOR 1 +#define MINOR 0 + +// +// ISAKMP HEADER +// +//Flags +#define ISAKMP_HDR_EFLAG 0x1 // Encryption Bit +#define ISAKMP_HDR_CFLAG 0x2 // Commit Bit +#define ISAKMP_HDR_AFLAG 0x4 // Authentication Only Bit + +//Payload types +#define ISAKMP_PAYLOAD_NONE 0 // (Terminator) +#define ISAKMP_PAYLOAD_SA 1 // Security Association +#define ISAKMP_PAYLOAD_P 2 // Proposal +#define ISAKMP_PAYLOAD_T 3 // Transform +#define ISAKMP_PAYLOAD_KE 4 // Key Exchange +#define ISAKMP_PAYLOAD_ID 5 // Identification +#define ISAKMP_PAYLOAD_CERT 6 // Certificate +#define ISAKMP_PAYLOAD_CR 7 // Certificate Request +#define ISAKMP_PAYLOAD_HASH 8 // Hash +#define ISAKMP_PAYLOAD_SIG 9 // Signature +#define ISAKMP_PAYLOAD_NONCE 10 // Nonce +#define ISAKMP_PAYLOAD_NOTIF 11 // Notification +#define ISAKMP_PAYLOAD_D 12 // Delete +#define ISAKMP_PAYLOAD_VID 13 // Vendor ID +#define ISAKMP_PAYLOAD_PRIVATE 128 // Private use (up to 255) + +#define ISAKMP_EXCHANGE_NONE 0 // None +#define ISAKMP_EXCHANGE_BASE 1 // Base +#define ISAKMP_EXCHANGE_ID 2 // Identity Protection (Main mode in IKE) +#define ISAKMP_EXCHANGE_AUTH 3 // Authentication Only +#define ISAKMP_EXCHANGE_AGGR 4 // Agressive +#define ISAKMP_EXCHANGE_INFO 5 // Informational +//#define ISAKMP_EXCHANGE_DOI 32 // DOI Specific (32..255) +//Additional Exchanges Defined +#define IKE_QUICK_MODE 32 //Quick Mode +#define IKE_NEW_GROUP_MODE 33 //New Group Mode + + +//Protocol number for IPSEC DOI (=1) //ProtocolId in Proposal Payload +#define PROTO_ISAKMP 1 +#define PROTO_IPSEC_AH 2 +#define PROTO_IPSEC_ESP 3 +#define PROTO_IPCOMP 4 + +//Transform ID's (RFC 2407) +//for ISAKMP +#define KEY_IKE 1 //Oakley +//for IPSEC_AH +#define AH_MD5 2 //MUST +#define AH_SHA 3 //MUST +#define AH_DES 4 +//for IPSEC_ESP +#define ESP_DES_IV64 1 +#define ESP_DES 2 //MUST +#define ESP_3DES 3 //Strongly encouraged +#define ESP_RC5 4 +#define ESP_IDEA 5 +#define ESP_CAST 6 +#define ESP_BLOWFISH 7 +#define ESP_3IDEA 8 +#define ESP_DES_IV32 9 +#define ESP_RC4 10 +#define ESP_NULL 11 //MUST +//for IPCOMP +#define IPCOMP_OUI 1 +#define IPCOMP_DEFLATE 2 +#define IPCOMP_LZS 3 + +//SA ATTRIBUTES Identifiers Phase I (RFC 2409) +#define OAKLEY_ATTR_TYPE_ENCR_ALG 1 +#define OAKLEY_ATTR_TYPE_HASH_ALG 2 +#define OAKLEY_ATTR_TYPE_AUTH_METH 3 +#define OAKLEY_ATTR_TYPE_GROUP_DESC 4 +#define OAKLEY_ATTR_TYPE_GROUP_TYPE 5 +#define OAKLEY_ATTR_TYPE_GROUP_PRIME 6 +#define OAKLEY_ATTR_TYPE_GROUP_GEN1 7 +#define OAKLEY_ATTR_TYPE_GROUP_GEN2 8 +#define OAKLEY_ATTR_TYPE_GROUP_CRVA 9 //Group curve A +#define OAKLEY_ATTR_TYPE_GROUP_CRVB 10 //Group curve B +#define OAKLEY_ATTR_TYPE_LIFE_TYPE 11 +#define OAKLEY_ATTR_TYPE_LIFE_DUR 12 +#define OAKLEY_ATTR_TYPE_PRF 13 +#define OAKLEY_ATTR_TYPE_KEY_LEN 14 +#define OAKLEY_ATTR_TYPE_FIELD_SIZE 15 +#define OAKLEY_ATTR_TYPE_GROUP_ORDER 16 + +//Values for each of the attributes +//encription algorithms +#define DES_CBC 1 +#define IDEA_CBC 2 +#define BLOWFISH_CBC 3 +#define RC5_R16_B64_CBC 4 +#define DES3_CBC 5 +#define CAST_CBC 6 +#define AES_CBC 7 //From + +#define ESP_DES_CBC 2 +#define ESP_3DES_CBC 3 +#define ESP_NULL 11 +#define ESP_AES_CBC 12 + +//hash algorithms +#define HASH_MD5 1 +#define HASH_SHA1 2 +#define HASH_TIGER 3 +//authentication methods +#define PRE_SHARED 1 //pre-shared key +#define DSS_SIG 2 //DSS signatures +#define RSA_SIG 3 //RSA signatures +#define RSA_ENCR 4 //Encryption with RSA +#define RSA_REV_ENCR 5 //Revised encryption with RSA + +//group descriptions +#define MODP_768 1 //default 768-bit MODP group (section 6.1) +#define MODP_1024 2 //alternate 1024-bit MODP group (section 6.2) +#define EC2N_155 3 //EC2N group on GP[2^155] (section 6.3) 3 +#define EC2N_185 4 //EC2N group on GP[2^185] (section 6.4) 4 +#define MODP_1536 5 //alternate 1536-bit MODP group (draft-ietf-ipsec-ike-modp-groups-04.txt) +#define MODP_2048 14 //IETF RFC 3526 +#define OAKLEY_DEFAULT_GROUP MODP_768 //default group. Not sure if needed. +//Group Types +#define MODP 1 //(modular exponentiation group) +#define ECP 2 //(elliptic curve group over GF[P]) +#define EC2N 3 //(elliptic curve group over GF[2^N]) +//Life Type +#define SECONDS 1 +#define KBYTES 2 + +//PRF +#define OAKLEY_PRF_3DES_CBC_MAC 1 //Only one implemented by now + +//Current DOI's in use +#define IPSEC_DOI 1 + +//SA ATTRIBUTES Identifiers Phase II (RFC 2407) iDOI +#define DOI_ATTR_TYPE_LIFE_TYPE 1 +#define DOI_ATTR_TYPE_LIFE_DUR 2 +#define DOI_ATTR_TYPE_GROUP_DESC 3 +#define DOI_ATTR_TYPE_ENC_MODE 4 +#define DOI_ATTR_TYPE_AUTH_ALG 5 +#define DOI_ATTR_TYPE_KEY_LEN 6 +#define DOI_ATTR_TYPE_KEY_ROUNDS 7 +#define DOI_ATTR_TYPE_COMP_DIC_SIZE 8 +#define DOI_ATTR_TYPE_COMP_PRIV_ALG 9 +//Values for each of the attributes of PHASE_II + +//Life type as Phase I +//Encapsulation Mode +#define DOI_TUNNEL 1 +#define DOI_TRANSPORT 2 +//Authentication Algorithm values +#define DOI_HMAC_MD5 1 +#define DOI_HMAC_SHA 2 +#define DOI_DES_MAC 3 +#define DOI_KPDK 4 + +#define IPSEC_SIT_IDENTITY_ONLY 0x1 //As defined in RFC 2407 DOI for ISAKMP +#define IPSEC_SIT_SECRECY 0x2 +#define IPSEC_SIT_INTEGRITY 0x4 + +//ID Types for IPSEC DOI +#define ID_IPV4_ADDR 1 +#define ID_FQDN 2 +#define ID_USER_FQDN 3 +#define ID_IPV4_ADDR_SUBNET 4 +#define ID_IPV6_ADDR 5 +#define ID_IPV6_ADDR_SUBNET 6 +#define ID_IPV4_ADDR_RANGE 7 +#define ID_IPV6_ADDR_RANGE 8 +#define ID_DER_ASN1_DN 9 +#define ID_DER_ASN1_GN 10 +#define ID_KEY_ID 11 + +//Certificate Types +#define NONE 0 +#define PKCS 1 //PKCS #7 wrapped X.509 certificate +#define PGP 2 //PGP Certificate +#define DNS 3 //DNS Signed Key +#define X509_CERT_SIG 4 //X.509 Certificate - Signature +#define X509_CERT_KE 5 //X.509 Certificate - Key Exchange +#define KERBEROS 6 //Kerberos Tokens +#define CRL 7 //Certificate Revocation List (CRL) +#define ARL 8 //Authority Revocation List (ARL)8 +#define SPKI 9 //SPKI Certificate +#define X509_CERT_ATTR 10 //X.509 Certificate - Attribute + +//NOTIFY MESSAGES - ERROR TYPES +#define INVALID_PAYLOAD_TYPE 1 +#define DOI_NOT_SUPPORTED 2 +#define SITUATION_NOT_SUPPORTED 3 +#define INVALID_COOKIE 4 +#define INVALID_MAJOR_VERSION 5 +#define INVALID_MINOR_VERSION 6 +#define INVALID_EXCHANGE_TYPE 7 +#define INVALID_FLAGS 8 +#define INVALID_MESSAGE_ID 9 +#define INVALID_PROTOCOL_ID 10 +#define INVALID_SPI 11 +#define INVALID_TRANSFORM_ID 12 +#define ATTRIBUTES_NOT_SUPPORTED 13 +#define NO_PROPOSAL_CHOSEN 14 +#define BAD_PROPOSAL_SYNTAX 15 +#define PAYLOAD_MALFORMED 16 +#define INVALID_KEY_INFORMATION 17 +#define INVALID_ID_INFORMATION 18 +#define INVALID_CERT_ENCODING 19 +#define INVALID_CERTIFICATE 20 +#define CERT_TYPE_UNSUPPORTED 21 +#define INVALID_CERT_AUTHORITY 22 +#define INVALID_HASH_INFORMATION 23 +#define AUTHENTICATION_FAILED 24 +#define INVALID_SIGNATURE 25 +#define ADDRESS_NOTIFICATION 26 +#define NOTIFY_SA_LIFETIME 27 +#define CERTIFICATE_UNAVAILABLE 28 +#define UNSUPPORTED_EXCHANGE_TYPE 29 +#define UNEQUAL_PAYLOAD_LENGTHS 30 + +//RESERVED (Future Use) 31 - 8191 +//Private Use 8192 - 16383 + +//NOTIFY MESSAGES - STATUS TYPES +#define CONNECTED 16384 +//RESERVED (Future Use) 16385 - 24575 +//DOI-specific codes 24576 - 32767 +#define DOI_RESPONDER_LIFETIME 24576 +#define DOI_REPLAY_STATUS 24577 +#define DOI_INITIAL_CONTACT 24578 +//Private Use 32768 - 40959 +//RESERVED (Future Use) 40960 - 65535 + +// +// Notify message types for Dead Peer Detection (DPD) defined in +// +// +#define DPD_R_U_THERE 36136 +#define DPD_R_U_THERE_ACK 36137 + +// +// IKE CRACK constants defines in +// + +//authentication method +#define IKE_A_CRACK 128 //CRACK authentication + +//Challenge/Response payload (CHRE) +#define ISAKMP_PAYLOAD_CHRE 128 //CHRE payload + + +//Legacy Authentication types +#define CRACK_PASSWORD 1 + +//LAM attributes (in CHRE payload) +#define CRACK_T_USERNAME 16390 //Variable +#define CRACK_T_SECRET 16391 //Variable +#define CRACK_T_DOMAIN 16392 //Variable +#define CRACK_T_PIN 16393 //Variable +#define CRACK_T_CHALLENGE 16394 //Variable +#define CRACK_T_MESSAGE 16395 //Variable +#define CRACK_T_FIN 16396 //Basic + +//CRACK Finish attribute values +#define CRACK_FIN_SUCCESS 1 +#define CRACK_FIN_MORE 2 + +// +// Definitions for Private Internal Address payload +// + +// Internal Address payload +#define ISAKMP_INT_NETWORK 247 //INTNET payload + +//Internal Address attributes +#define PRI_INTERNAL_ADDRESS 24001 //Variable +#define PRI_INTERNAL_DNS 24002 //Variable +#define PRI_INTERNAL_WINS 24003 //Variable + +// +// Definitions for expanded Vendor ID payload options +// +#define VENDOR_OPTION_HASH 1 +#define VENDOR_OPTION_NAT_TRAVERSAL 2 +#define VENDOR_OPTION_VERSION 3 + +#define NOKIA_UDP_ENCAPS_PORT 9872 +#define UDP_KEEPALIVE_TIME 30 // Default value 30 seconds + +// NAT Discovery and NAT original address payloads ( +#define IETF_NAT_DISCOVERY 130 // 15 in draft version 05 and later +#define IETF_NAT_ORIG_ADDR 131 // 16 in draft version 05 and later +#define IETF_RFC_NAT_DISCOVERY 20 // 15 in draft version 05 and later +#define IETF_RFC_NAT_ORIG_ADDR 21 // 16 in draft version 05 and later + +// Encapsulation modes with NAT-traversal +#define UDP_ENC_TUNNEL 61443 // 3 in draft version 03 and later +#define UDP_ENC_TRANSPORT 61444 // 4 in draft version 03 and later +#define UDP_RFC_ENC_TUNNEL 3 // 3 in draft version 03 and later +#define UDP_RFC_ENC_TRANSPORT 4 // 4 in draft version 03 and later + +// +// Definitions related to Extended Authentication (XAUTH) (draft-beaulieu-ike-xauth-02.txt) +// and to The ISAKMP Configuration Method (MODE-CFG) (draft-dukes-ike-mode-cfg-01.txt) +// The ISAKMP Configuration Method defines an ISAKMP exchange called Transaction Exchange. +// Both XAUTH and MODE-CFG uses that ISAKMP exchange. +// +#define ISAKMP_EXCHANGE_TRANSACT 6 // Transaction exchange + +// +// XAUTH Notification via Authentication Method Types +// The following values relate to the ISAKMP authentication method +// attribute used in proposals. They optionally allow an XAUTH +// implementation to propose use of extended authentication after the +// initial phase 1 authentication. Values are taken from the private +// use range defined in [IKE] and should be used among mutually +// consenting parties. +// +#define XAUTHInitPreShared 65001 +#define XAUTHRespPreShared 65002 +#define XAUTHInitDSS 65003 +#define XAUTHRespDSS 65004 +#define XAUTHInitRSA 65005 +#define XAUTHRespRSA 65006 +#define XAUTHInitRSAEncryption 65007 +#define XAUTHRespRSAEncryption 65008 +#define XAUTHInitRSARevisedEncr 65009 +#define XAUTHRespRSARevisedEncr 65010 +#define XAUTHInitIndicator (TUint16)0x1 +#define XAUTHMethodBase (TUint16)65000 +#define XAUTHScaler (TUint16)0x1 + +// +// Attribute Payload (draft-dukes-ike-mode-cfg-01.txt) +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Next Payload ! RESERVED ! Payload Length ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Type ! RESERVED ! Identifier ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! ! +// ~ Attributes ~ +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +#define ISAKMP_PAYLOAD_ATTRIBUTES 14 // Attributes payload + +// +// Configuration message types used within the Type field of an Attribute ISAKMP payload +// (draft-dukes-ike-mode-cfg-01.txt) +// +#define ISAKMP_CFG_REQUEST 1 // Configure request +#define ISAKMP_CFG_REPLY 2 // Configure reply +#define ISAKMP_CFG_SET 3 // Configure set +#define ISAKMP_CFG_ACK 4 // Configure ack + +// +// Configuration Attribute values within an Attributes Payload +// (draft-dukes-ike-mode-cfg-01.txt) +// +#define ATTR_INTERNAL_IP4_ADDR 1 // Internal IPv4 address (=Virtual IP) +#define ATTR_INTERNAL_IP4_MASK 2 // Internal IPv4 mask +#define ATTR_INTERNAL_IP4_DNS 3 // Internal DNS address +#define ATTR_INTERNAL_IP4_NBNS 4 // Internal NBNS address +#define ATTR_INTERNAL_ADDR_EXPIRY 5 // Internal Address expiry time +#define ATTR_INTERNAL_IP4_DHCP 6 // Internal DHCP address +#define ATTR_APPLICATION_VERSION 7 // Application version data +#define ATTR_INTERNAL_IP6_ADDR 8 // Internal IPv6 address (=Virtual IP) +#define ATTR_INTERNAL_IP6_MASK 9 // Internal IPv6 mask +#define ATTR_INTERNAL_IP6_DNS 10 // Internal DNS address +#define ATTR_INTERNAL_IP6_NBNS 11 // Internal NBNS address +#define ATTR_INTERNAL_IP6_DHCP 12 // Internal DHCP address +#define ATTR_INTERNAL_IP4_SUBNET 13 // Internal IPv4 subnet (=policy selector) +#define ATTR_SUPPORTED_ATTRIBUTES 14 // Supported attributes info data +#define ATTR_INTERNAL_IP6_SUBNET 15 // Internal IPv6 subnet (=policy selector) + +// +// Extended Authentication Attribute values within an Attributes Payload +// (draft-beaulieu-ike-xauth-02.txt) +// +#define ATTR_XAUTH_TYPE 16520 // Extended authentication type code +#define ATTR_USER_NAME 16521 // User name data +#define ATTR_PASSWORD 16522 // Password data +#define ATTR_PASSCODE 16523 // Passcode data +#define ATTR_MESSAGE 16524 // Message data +#define ATTR_CHALLENGE 16525 // Challenge data +#define ATTR_DOMAIN 16526 // Domain name data +#define ATTR_STATUS 16527 // Status value +#define ATTR_NEXT_PIN 16528 // Next PIN value +#define ATTR_ANSWER 16529 // Answer data + +// +// Additional Extended Authentication Attribute values within an +// Attributes Payload. +// (draft-ietf-ipsec-isakmp-xauth-04.txt) +// +#define ATTR_PIX_XAUTH_TYPE 13 // Extended authentication type code +#define ATTR_PIX_USER_NAME 14 // User name data +#define ATTR_PIX_PASSWORD 15 // Password data +#define ATTR_PIX_PASSCODE 16 // Passcode data +#define ATTR_PIX_MESSAGE 17 // Message data +#define ATTR_PIX_CHALLENGE 18 // Challenge data +#define ATTR_PIX_DOMAIN 19 // Domain name data +#define ATTR_PIX_STATUS 20 // Status value + +// +// Extended Authentication type values +// (draft-beaulieu-ike-xauth-02.txt) +// +#define ATTR_XAUTH_GENERIC 0 // Generic authentication type code +#define ATTR_XAUTH_RADIUS_CHAP 1 // RADIUS CHAP authentication type code +#define ATTR_XAUTH_OTP 2 // OTP authentication type code +#define ATTR_XAUTH_SKEY 3 // S/KEY authentication type code + +// +// Extended Authentication Set status values +// (draft-beaulieu-ike-xauth-02.txt) +// +#define ATTR_STATUS_OK 1 +#define ATTR_STATUS_FAIL 0 + +#endif // ISAKMPCT_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1isakmpstream.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1isakmpstream.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,88 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Stream class definition for ISAKMP +* +*/ + + +#ifndef IKEV1ISAKMPSTREAM_H +#define IKEV1ISAKMPSTREAM_H + +#include + + +class CIkev1Negotiation; +class TInetAddr; +class TAttrib; +class TIdentISAKMP; +class TAttrib_II; +class MIkeDebug; + +// +// Constructing outgoing message +// +class TIkev1IsakmpStream +{ +public: + TIkev1IsakmpStream( MIkeDebug& aDebug ); + void IsakmpInit(CIkev1Negotiation *aSession); + void IsakmpSa(); + void IsakmpKeyL(); + void IsakmpOwnIdentL(); + void IsakmpPeerIdentL(); + void IsakmpCertificateL(); + void IsakmpCertificateReqL(); + void IsakmpHashL(); + void IsakmpHashContL(); + void IsakmpSignatureL(); + void IsakmpNonce(); + void IsakmpNotification(TUint16 aType, TUint8 aProtocol, TUint8* aNotifData = NULL, TInt aLth = 0); + void IsakmpReplayStatus(TUint8 aProtocol, TUint32 aSPI, TUint8 aReplayWindowLength); + void IsakmpResponderLifetime(TUint8 aProtocol, TUint32 aSPI, const TDesC8 &aLifetime, const TDesC8 &aLifesize); + void IsakmpDelete(TDesC8 &aSPI, TUint8 aProtocol); + void IsakmpChre(TUint16 aLAMType, TUint16 aAttr1, HBufC8 *aBfr1, + TUint16 aAttr2, HBufC8 *aBfr2, TUint16 aAttr3, HBufC8 *aBfr3); + void IsakmpVendorId(TInt aID_Type, TUint8 *aICOOKIE, TUint8 *aRCOOKIE, TInetAddr &aLocalAddr, + TUint8 *aGenericVidData = NULL, TInt aGenericVidLth = 0); + void IsakmpIntnet(TUint32 aIpv4Addr); + void IsakmpNatD(TBool aRfcNatt,TDesC8 &aHash); + void IsakmpAttributes(TUint8 aMsgType, TUint16 aIdentifier, TDesC8 &aAttributes); + +private: + void IsakmpProposal(); + void IsakmpTransform(TUint8 *aTransform, TUint8 aNumTransforms); + void IsakmpAttrib(TUint8 *aTransform); + void IsakmpAttrib1(TAttrib *aTransform); + void IsakmpAttrib2(TAttrib_II *aTransform); + void IsakmpChreAttrib(TUint16 aType, HBufC8 *aBfr); + void IsakmpIdentL(TBool aIsOwn); //Own or Peer + void Isakmp_Phase1_IdL(TDes8& aIdData, TIdentISAKMP& aIdPayload); + +private: + CIkev1Negotiation *iNegotiation;//const + TUint8 *iNextPayload; + TUint8 *iPropNextPayload; //Used for Proposals to avoid overwritting the SA next + //field which has to be filled by other payloads + TUint8 *iTransfNextPayload; //For Transforms + TInt iHash_pos; //Stores a position to insert the hash in PHASE_II + MIkeDebug& iDebug; + +public: + TBuf8<4096> iBuf; + TBool iError; //ETrue if any error building the message + }; + + + +#endif // IKEV1ISAKMPSTREAM_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1keepalive.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1keepalive.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,96 @@ +/* +* Copyright (c) 2005-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv1 keep alive object +* +*/ + + +#ifndef C_IKEV1KEEPALIVE_H +#define C_IKEV1KEEPALIVE_H + +#include // TInetAddr + +class CIkev1PluginSession; +class CEchoSender; + +/** +* IKE keepalive event handler +* @internalComponent +*/ +class MDpdHeartBeatEventHandler +{ + public: + /** + * IKE PKI service operation completed + * @internalComponent + * @param aStatus completion status of operation + * @param aObject pointer to CIkePkiService object + * + */ + virtual void EventHandlerL()=0; +}; + + +NONSHARABLE_CLASS(CIkeV1KeepAlive) : public CTimer +{ + public: + static CIkeV1KeepAlive* NewL( CIkev1PluginSession& aPluginSession, + TInt aPort, + TInetAddr& aDestAddr, + TInt NatKeepAlive, + TInt DpdKeepAlive, + MDpdHeartBeatEventHandler* aHandler, + TUint8 aDscp = 0 ); + ~CIkeV1KeepAlive(); + + protected: + // + // CActive methods + // + void DoCancel(); + void RunL(); + TInt RunError(TInt aError); + + private: // implementation + CIkeV1KeepAlive( CIkev1PluginSession& aPluginSession, + TInt aPort, + TInetAddr& aDestAddr, + TInt NatKeepAlive, + TInt DpdKeepAlive, + MDpdHeartBeatEventHandler* aHandler, + TUint8 aDscp ); + void ConstructL(); + void StartTimer(); + + private: // data + MDpdHeartBeatEventHandler* iCallback; + CIkev1PluginSession& iPluginSession; + + TInt iPort; + + /** Data to send in keepalive packet */ + TBuf8<1> iMsg; + + TInt iNatKeepAlive; + TInt iDpdKeepAlive; + + TInt iCurrDPDTimeLeft; + TInt iRemainingTime; + + TInetAddr iDestAddr; + + TUint8 iDscp; +}; + +#endif // C_IKEV1KEEPALIVE_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1natdiscovery.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1natdiscovery.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Negotiation of NAT-Traversal in the IKE +* +*/ + + +#ifndef C_IKEV1NATDISCOVERY_H +#define C_IKEV1NATDISCOVERY_H + +#include + +class TIkev1IsakmpStream; +class CProposal_IIList; +class TVendorISAKMP; +class TNATDISAKMP; +class TNATOaISAKMP; +class TInetAddr; + +// Class CIkev1NatDiscovery implents negotiation of NAT-Traversal. +// The current implementation follows IETF . +class CIkev1NatDiscovery : public CBase + { +public: + CIkev1NatDiscovery(){}; + static CIkev1NatDiscovery* NewL(TUint32 aNatFlags); + ~CIkev1NatDiscovery() {}; + void BuildNatVendorId(TIkev1IsakmpStream &aMsg); + void BuildRfcNatVendorId(TIkev1IsakmpStream &aMsg); + TBool CheckNatVendorId(const TVendorISAKMP *aVendorPayload); + TBool CheckRfcNatVendorId(const TVendorISAKMP *aVendorPayload); + void BuildDiscoveryPayloadsL(TIkev1IsakmpStream &aMsg, TUint16 aHashType, + TUint8 *aICOOKIE, TUint8 *aRCOOKIE, + TInetAddr &aLocalAddr, TInetAddr &aRemoteAddr); + TUint32 CheckDiscoveryPayloadsL(const CArrayFixFlat *aNatDPayloadArray, + TUint16 aHashType, TUint8 *aICOOKIE, TUint8 *aRCOOKIE, + TInetAddr &aLocalAddr, TInetAddr &aRemoteAddr); + + void BuildNatOaPayload(TIkev1IsakmpStream &aMsg, TInetAddr &aLocalAddr, CProposal_IIList *aProposalList); + TBool GetPeerOriginalAddress(const TNATOaISAKMP *aNatOaPayload, TInetAddr& aRemoteOrigAddr, CProposal_IIList *aProposalList); + +private: + void CalculateAddrPortHashL(TUint16 aHashType, + TUint8 *aICOOKIE, TUint8 *aRCOOKIE, + TInetAddr &aLocalAddr, TInetAddr &aRemoteAddr); + TBool CompareHashData(TUint8 *aHashData, TUint32 aHashLth, TDesC8 &aReferenceHash); + + + TBool iSupport; // ETrue = Both ends supports current draft + TBool iRfcSupport; //ETrue = Both ends support current RFC + TBuf8<16> iIetfNattVidHash; // NAT-T vendor id string (= md5("draft-ietf-ipsec-nat-t-ike-05") + TBuf8<16> iIetfRfcNattVidHash; // NAT-T vendor id string (= md5("RFC 3947") + TBool iHashExists; // ETrue = Hash data below has been calculated + TBuf8<32> iLocalAddrPortHash; // value of the HASH(CKY-I | CKY-R | Local_IP | Port) + TBuf8<32> iRemoteAddrPortHash; // value of the HASH(CKY-I | CKY-R | Remote_IP | Port) + + }; + + +#endif // C_IKEV1NATDISCOVERY_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1negotiation.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1negotiation.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,532 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv1 negotiation. +* +*/ + +#ifndef C_IKEV1NEGOTIATION_H +#define C_IKEV1NEGOTIATION_H + +#include + +#include "ikev1payloads.h" +#include "ikev1extra.h" +#include "ikev1SAdata.h" +#include "ikepolparser.h" +#include "ipsecsaspiretriever.h" + +#define INITIATOR 0 +#define RESPONDER 1 + +#define PHASE_I 1 //Used to identify the PHASE number +#define PHASE_II 2 + +#define OAKLEY_DEFAULT_NONCE_SIZE 128/8 //128 bits = 16 bytes +#define ISAKMP_HEADER_SIZE 28 +#define ISAKMP_HASH_SIZE 24 //Size for 3des_cbc return value +#define MAX_PRF_LENGTH 24 //In bytes corresponds to 3DES_CBC +#define MAX_RETRANS_TIMER 10 //Isakmp packet retransmission timer +#define MAX_RETRANS_COUNT 7 //Maximum retransmission count + +//Vendor ID type codes values +#define HASH_VENDOR_ID 0 //Contains only a vendor specific hash +#define EXPANDED_VENDOR_ID 1 //Contains NAT probing data and a vendor specific hash +#define IETF_NATT_VENDOR_ID 2 //Vendor ID for draft +#define IETF_RFC_NATT_VENDOR_ID 3 + +const TInt KMaxDpdRetryCount( 2 ); + +struct TSPINode +{ + TInt iPropNum; //Proposal # + TUint32 iSeq; //Sequence # in the GETSPI msg + TUint32 iSPI; //Received SPI +}; + +class TPfkeyMessage; +class CIkev1PluginSession; +class CAuthDialogInfo; +class CIkev1Timeout; +class CX509Certificate; +class CIkeKeys; +class CIkeV1PkiService; +class TSAISAKMP; +class TPayloadISAKMP; +class TKeyISAKMP; +class TIdentISAKMP; +class TCertificateISAKMP; +class TSignatureISAKMP; +class THashISAKMP; +class TNotificationISAKMP; +class TVendorISAKMP; +class TINTNETISAKMP; +class TProposalISAKMP; +class CIkev1NatDiscovery; +class CIKECRACKNegotiation; +class CTransNegotiation; +class TIkev1IsakmpStream; +class MIkeDebug; +class MKmdEventLoggerIf; +class CPFKeySocketIf; + +// +// Class CIkev1Negotiation: Contains all the info for each negotiation in progress +// +NONSHARABLE_CLASS(CIkev1Negotiation) : public CBase, + public MIpsecSaSpiRetrieverCallback + { + friend class CIkev1InfoNegotiation; + friend class TIkev1IsakmpStream; + friend class CIKECRACKNegotiation; + friend class CTransNegotiation; + friend class CIkev1Payloads; + +public: + static CIkev1Negotiation* NewL( CIkev1PluginSession* aPluginSession, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug, + const TInetAddr& aRemote, + const TCookie& aInitiator, + const TCookie& aResponder ); + + static CIkev1Negotiation* NewL( CIkev1PluginSession* aPluginSession, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug, + const TInetAddr& aRemote, + const TCookie& aInitiator, + TBool aAutoLogin ); + + static CIkev1Negotiation* NewL( CIkev1PluginSession* aPluginSession, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug, + TIkev1SAData* aIkev1SAdata, + TUint aRole, + const TPfkeyMessage *aReq = NULL ); + + static CIkev1Negotiation* NewL( CIkev1PluginSession* aPluginSession, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug, + const TInetAddr& aRemote, + TBool aAutoLogin ); + + static CIkev1Negotiation* NewL( CIkev1PluginSession* aPluginSession, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug, + const TInetAddr& aRemote, + const TPfkeyMessage& aReq ); + + ~CIkev1Negotiation(); + + TBool ExecuteL( const ThdrISAKMP& aHdr, + const TInetAddr& aRemote, + TInt aLocalPort ); + TBool ExecutePhase2L( const ThdrISAKMP& aHdr, + const TInetAddr& aRemote, + TInt aLocalPort ); + TBool ExecuteTransactionL( const ThdrISAKMP &aHdr, + const TInetAddr& aRemote, + TInt aLocalPort ); + void InitNegotiationL(); + void InitPhase2L(); + //used by the timer + void ReSendL(); + + inline TUint32 AcqSeq() {return iAcquireSeq;} + inline TInt GetNotifyStatus() {return iReceivedNotify;} + inline void SetNotifyStatus(TInt aStatus) {if (iReceivedNotify == KErrNone) iReceivedNotify = aStatus;} + inline TBool Autologin() {return iAutoLogin;} + inline TBool Finished() {return iFinished;} + inline void SetFinished() {iFinished = ETrue;} + inline void SetRekeyInfo(CSARekeyInfo* aSARekeyInfo) { iSARekeyInfo = aSARekeyInfo;} + inline TUint32 SAId() {return iSAId;} + TIkev1IsakmpStream* SaveIkeMsgBfr(TIkev1IsakmpStream* aMsg); + void AuthDialogCompletedL(CAuthDialogInfo *aUserInfo); + TInt32 RandomMessageId(); + void SendDeleteL(TUint8 aProtocol, TUint32 aIpsecSPI = 0); //Send a Delete payload for the negotiation + void SendKeepAliveMsgL(TIkev1SAData* aSa); + + TBool IsRekeyingIkeSa(); + void PreparePhase2L(const TPfkeyMessage &aReq); + + MKmdEventLoggerIf& EventLogger(); + +// from base class MIpsecSaSpiRetrieverCallback + + /** + * Notification about completion of IPsec SPI SA retrieve. + * + * @param aSpiRequestId Id of the SPI retrieve request. + * @param aStatus Completion status + * @param aSpi SPI value + */ + void IpsecSaSpiRetrieved(TUint32 aSpiRequestId, + TInt aStatus, + TUint32 aSpi); + +private: + + CIkev1Negotiation( CIkev1PluginSession* aPluginSession, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug ); + CIkev1Negotiation( CIkev1PluginSession* aPluginSession, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug, + const TInetAddr& aRemote, + const TCookie& aInitiator ); + CIkev1Negotiation( CIkev1PluginSession* aPluginSession, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug, + const TInetAddr& aRemote ); + + void ConstructL( TBool aAutoLogin ); + //When receiving an acquire + void ConstructL( const TPfkeyMessage& aReq ); + // To create a negotiation form an existing ISAKMP SA either as negotiator or responder + void ConstructL( TIkev1SAData* aIkev1SAdata, + TUint aRole, + const TPfkeyMessage *aReq = NULL ); + + void GetAcquireDataL(const TPfkeyMessage &aReq); + void CommonConstructL(); + TBool BuildProposals1L(); + TInt BuildProposals2L(); + //Packet processing functions + TBool ProcessHeaderL(const ThdrISAKMP &aHdr); + //received packet processing depending on the stage + TBool ProcessStage1L(const ThdrISAKMP &aHdr); //Checks SA from INITIATOR + TBool ProcessStage2L(const ThdrISAKMP &aHdr); //Checks SA from RESPONDER + TBool ProcessStage3MainL(const ThdrISAKMP &aHdr); //Checks KE,NONCE from INITIATOR + TBool ProcessStage3AggrL(const ThdrISAKMP &aHdr);//Checks ID,AUTH from RESPONDER + TBool ProcessStage4L(const ThdrISAKMP &aHdr); //Checks KE,NONCE from RESPONDER + TBool ProcessStage5L(const ThdrISAKMP &aHdr); //Checks ID,AUTH from INITIATOR + TBool ProcessStage6L(const ThdrISAKMP &aHdr); //Checks ID,AUTH from RESPONDER + TBool ProcessStage7L(const ThdrISAKMP &aHdr); //CRACK authentication going + TBool ProcessStage1Phase2L(const ThdrISAKMP &aHdr);//Checks HASH(1),SA,KE,NONCE,ID from INITIATOR + TBool ProcessStage2Phase2L(const ThdrISAKMP &aHdr);//Checks HASH(2),SA from RESPONDER + TBool ProcessStage3Phase2L(const ThdrISAKMP &aHdr);//Checks HASH(3) from INITIATOR/RESPONDER + TBool ProcessCONNECTEDL(const ThdrISAKMP &aHdr);//Checks HASH(INF, NOTIF) from RESPONDER + TBool ProcessSAL(const TSAISAKMP *aPayload, TUint8 *aRecvProposals); + TBool ProcessProposalsL(const TPayloadISAKMP *aPayload,TUint32 aLengthLeft, TUint8 *aRecvProposals); + TInt ProcessTransformsL(const TPayloadISAKMP *aPayload,TUint32 aLengthLeft); + TInt ProcessTransforms2L(const TPayloadISAKMP *aPayload,CProposal_II *aProp,TUint32 aLengthLeft); + TInt ProcessAttributesL(const TPayloadISAKMP *aPayload,TAttrib *aAttrib); //checks and return the SA attributes + TInt ProcessAttributes2L(const TPayloadISAKMP *aPayload,TAttrib_II *aAttrib,TUint8 aProtocol); //checks and return the SA attributes + TBool ProcessKeyL(const TKeyISAKMP *aKey); //check payload and stores public key value + TBool ProcessNonceL(const TPayloadISAKMP *aPayload); + TBool ProcessStage1_II_IDsL(const TIdentISAKMP *aInit_ID_payload,const TIdentISAKMP *aResp_ID_payload, CProposal_IIList *aRecv_proposals); + TBool ProcessStage2_II_IDsL(const TIdentISAKMP *aInit_ID_payload,const TIdentISAKMP *aResp_ID_payload);//, CProposal_IIList *aRecv_proposals); + TBool CheckIdentL(const TPayloadISAKMP *aPayload); + TBool ProcessCertificateReqL(const TCertificateReqISAKMP *aCertReq); + TBool ProcessCertificateReqArrayL(const CArrayFixFlat *aCRPayloadArray); + TBool ProcessCertificateArrayL(CArrayFixFlat *aCertArray); + TBool ProcessSignatureL(const TSignatureISAKMP *aPayload); + TBool ProcessHashL(const THashISAKMP *aHashPayload); + TBool ProcessHash2L(const ThdrISAKMP &aHdr, const THashISAKMP *aHashPayload, TUint aPadding); + TBool ProcessNotificationL(const TNotificationISAKMP *aNotifPayload); + TBool ProcessResponderLifetimeL(const TNotificationISAKMP *aNotifPayload); + TBool ProcessReplayStatus(const TNotificationISAKMP *aNotifPayload); + TBool ProcessInitialContactL(const TNotificationISAKMP *notif_payload); + void ProcessVendorL(CArrayFixFlat* aVids); + void ProcessIntAddrL(const TINTNETISAKMP *aIntnetPayload); + + TBool Phase_IExchangeL(const ThdrISAKMP &aHdr); + TBool Phase_IIExchangeL(const ThdrISAKMP &aHdr); + void QuickModeReplyL(); + void MainModeReplyL(); + void AggressiveReplyL(); + + //Certificate reading functions + TBool ReadCAsL(CArrayFixFlat *aCAList); + TBool ReadOwnCertL(); + + TCookie CreateCookieL() const; + TBool CheckCookies(const TCookie& aInit, const TCookie& aResp); + TBool CheckPayloadCode(TUint8 aPayload); + TBool CheckVersionL(TUint8 aVersion); + TBool CheckExchangeTypeL(TUint8 aType); + TBool CheckFlagsL(TUint8 aFlags); + TBool CheckMessageIdL(TUint32 aId); + TBool CheckDOI(TUint32 aDOI); + TBool CheckSituationL(TUint32 aSIT); + TBool CheckGenericPayloadL(const TPayloadISAKMP *aPayload); + TBool CheckProtocolL(TUint8 aProtocol); //checks if protocol supported + TBool CheckSPIL(const TProposalISAKMP *aProposal); //checks if the SPI is valid + TBool CheckTransformID(TUint8 aProtocol,TUint8 aID); + + //SA Attributes checking functions + TBool CheckEncrAlg(TUint16 aValue); + TBool CheckHashAlg(TUint16 aValue); + TBool CheckAuthMethod(TUint16 aValue); + TBool CheckGroupDesc(TUint16 aValue); + TBool CheckGroupType(TUint16 aValue); + TBool CheckGroupPrime(const TUint8* aValue, TUint16 length); + TBool CheckGroupGen(const TUint8* aValue, TUint16 length); + TBool CheckGroupCurve(const TUint8* aValue, TUint16 length); + TBool CheckLifeType(TUint16 aValue); + TBool CheckLifeDuration(const TUint8* aValue, TUint16 length); + TBool CheckPRF(TUint16 aValue); + TBool CheckKeyLength(TUint16 aValue,TUint8 aID,TUint8 aProtocol); + TBool CheckFieldSize(TUint16 aValue); + TBool CheckGroupOrder(const TUint8* aValue, TUint16 length); + TBool CheckEncMode(TUint16 aValue); + TBool CheckAuthAlg(TUint16 aValue); + + //Certificate payload checks + TBool CertifyRemoteIdentityL(const TIdentISAKMP *aIdPayload); + TInt CheckEncodingL(TUint8 aEncoding); + + + //Signatures + TBool VerifySignatureL(CX509Certificate *aCert,TUint8 *iHash, TInt aLength,TUint8 *aSig,TUint aSigLength); + + + //Diffie-Hellman Exchange Routines + TBool ComputeDHPublicValueL(); + void ComputeNonceL(); + + //Hash and Signature computation + void ComputeHashrL(TDes8 &aHash); + void ComputeHash1L(TDes8 &aHash); + void ComputeHash2L(TDes8& aHash,TInt aStage,const TUint8 *aHashMsg=NULL,TInt aHashMsgLen=0); + TBool VerifyHash2L(const THashISAKMP *iHash,const TUint8 *aHashMsg=NULL,TInt aHashMsgLen=0); + TBool VerifyInformationalHashL(const THashISAKMP *aHash,const TPayloadISAKMP *aPayload, TUint32 iMessageId); + void ComputeHashInfL(TDes8& aHash,const TUint8 *aHashMsg,TInt aHashMsgLen); + + //Send a Notification packet informing of an error. + void SendNotifyL(TUint16 aError); + + void CheckSendResponderLifetime(TIkev1IsakmpStream &aMsg); + static TPtrC ExchangeType(TUint8 aExchange); + static void TextPayload(TDes &aBuf, TUint8 aPayload); + static TPtrC TextNotifyType(TUint16 aNotif); + + //PFKEY related functions + void AcquireSAErrorResponse(TInt aError); + void GetSPIL(); + void ReceiveSPIL(TUint32 aSPI, TUint32 aSeq); + + void UpdateSADatabaseL(); + + void ComputeLifetimes_II(const TDesC8 &aLifetime, const TDesC8 &aLifesize, TInt64 &aTime, TInt64 &aBytes); + + //CRACK related functions + TBool StartCRACKAuthL(); + + TBool IsakmpPhase1CompletedL(); + + //Socket + void SendL(TIkev1IsakmpStream &aMsg); + + inline TUint Role() {return iRole;} + inline CIkev1PluginSession* PluginSession() {return iPluginSession;} + TInt HashLength(); //Output size for PRF algorithm + + TUint32 ISAKMPEncrKeyLength(TUint8 aAlgId) const; //in bytes + TUint32 HMAC_KeyLength(TUint8 aId) const; + + //builds the correct key using the values in iNegotiation + TBool ComputeKeysL(); + void ComputeKeys2L(const CProposal_II *aProp, TInt aKeyLen, TSPINode &aInboundSpiNode, TDes8& aOutboundKey_II, TDes8& aInboundKey_II); + void ComputePRFL(TDes8 &prf_output, const TDesC8 &prf_key, const TDesC8 &prf_data); + TBool InitIVL(); //Initial IV value + TBool ComputeIVL(TDes8 &aIV, TInt32 aMessageId); //subsequent IV computations + //Encryption routines + void AppendAttributeError(TInt aErr, TDes &aBuf) const; + void SaveISAKMPSAL(); + void CreateChosenProposalL(CProposal_IIList* aPropList, TInt aPropNum, CTransModifierList *aTransArray); + TBool ExamineRemoteIdentity(const TDesC8& aRemoteIdInPolicy); + TBool ProcessIdentityData(const TDesC8& aIdentity, TUint8* aToIdType, TInetAddr* aToIpAddr1, TInetAddr* aToIpAddr2); + + void DpdNotifyMessageReceivedL(TIkev1SAData* aSa, TUint16 aMsgType, TUint32 aSequence); + TUint32 GetNextSequence(TUint32 aSequence); + void SendDpdNotifyMessageL(TUint16 aMsgType, TUint32 aSequence); + + TInt ErrorStatus(); + void SetErrorStatus(TInt aStatus); + + void SendAndSaveIkeMsgL( const TDesC8& aIkeMsg, + TInetAddr& aDestAddr, + TBool aUseNatPort ); + + TBool IsRetransmit(TLastIKEMsg& aRef); + void SaveRetransmitInfo(TLastIKEMsg& aRef); + void SaveLastMsgL(); + +public: + TCookie iCookie_I; // Initiator Cookie (Used with responder to create KEYID) + TCookie iCookie_R; // Responder Cookie + TUint32 iSAId; + TUint32 iMessageId; // Message Id. o during Phase I + CIkev1Negotiation *iNext; // A link field to maintain negotiations. + +private: + //Data relevant to the host + CIkeData *iHostData; + + //Internal Data + TInetAddr iLocalAddr; + TInetAddr iRemoteAddr; // Remote Address (Gateway or end host) + + + TUint iRole; // If we are PHASE I Initiator or Responder + TUint iPhase; // Phase I or II + TUint iStage; // Negotiation Stage + + //Header Data + TUint8 iExchange; // IKE mode in use (Main, agressive,...) + TUint8 iPrevExchange; // Used to process the last msg of Phase I + + TUint8 iFlags; // Own flags to use when sending a msg header + TUint8 iRecvFlags; // Received flags in the last msg header + TBool iCommitBitSet; // If true the Commit bit has been set by this host + TUint32 iNotifyMessageId; // Message Id. for Informational Exchanges + TLastIKEMsg iLastIKEMsgInfo;// Information of the last received IKE message + + //SA Data + TUint8 *iSAPayload; // Initiator SA payload (used in the hash computation). Generic payload NOT included + TInt iSAPayloadSize; + TUint32 iDOI; // Must be IPSEC = 1 + + //Proposal/transform list Phase I and II + TProposal iProposal_I; // Contains proposed SA attrib for Phase I with it's attr list + TProposal iChosenProposal_I; + CProposal_IIList *iProposal_IIList; //Contains the Phase_II Proposal List (PROPOSED) + CProposal_IIList *iChosenProp_IIList; //Contains the Phase_II Proposal List (Received from the remote peer) + + + TInt iProposalNum; //Accepted proposed proposal. Needed to know which are the valid SPIs in the next list + CArrayFixFlat *iInboundSPIList; + + //Keys (DH Generated public value when own) + CIkeKeys *iOwnKeys; //Contains own public and private keys + HBufC8 *iOwnPublicKey; + TPtrC8 iOwnPublicKey_ptr; + TBuf8 iPeerPublicKey; //(gxr) + TBuf8 iSKEYID; //KEY used for encryption/decryption of messages + TBuf8 iSKEYID_d; //KEY used to derive keys for non-ISAKMP SAs + TBuf8 iSKEYID_a; //KEY used for authentication of ISAKMP messages + TBuf8 iSKEYID_e; //KEY used for encryption/decryption of ISAKMP messages + + //IV used by des_cbc and des3_cbc is 8 and for AES 16 + TBuf8 iIV; //normal IV + TBuf8 iLastIV; //Saves the last IV of PHASE_I to compute iNotifIV everytime and the first IV in Quick mode + TInt iIVSize; //Current IV/cipher block size + + //Perfect Forward Secrecy + TBool iPFS; + + //Replay Window Length + //TInt8 iReplayWindowLength; + + //Nonces + TBuf8 iNONCE_I; + TBuf8 iNONCE_R; + + //IDENTITY info + TUint8 *iPeerIdentPayload; //Full Peer ID payload for HASH_I/R computation.Generic payload NOT included + TInt iPeerIdentPayloadSize; + TUint8 *iOwnIdentPayload; //Full own ID payload for HASH_I/R computation.Generic payload NOT included + TInt iOwnIdentPayloadSize; + //TUint8 iIDType; + TUint16 iIDLocalPort; + TUint16 iIDRemotePort; + TUint8 iIDProtocol; + TBool iIDReceived; + + TBool iSwapRemoteIdType; + TBool iDefaultRemoteID; //To avoid updating the Remote ID if a default is being used + TInetAddr iRemoteAddr1_ID_II;// Remote proxy Address, subnet or initial range + TInetAddr iRemoteAddr2_ID_II;// Remote proxy mask or end range + TUint8 iRemoteIDType_II; + TBool iDefaultLocalID; //To avoid updating the Local ID if a default is being used + TInetAddr iLocalAddr1_ID_II; // Local proxy Address, subnet or initial range + TInetAddr iLocalAddr2_ID_II; // Local proxy mask or end range if implemented + TUint8 iLocalIDType_II; + + // + //IETF NAT Traversal information + // + CIkev1NatDiscovery *iNatDiscovery; // IETF NAT traversal control object pointer + TUint32 iNAT_D_Flags; // If not zero, there is NAT between sites + TInetAddr iLastRemoteAddr; // Last detected remote address + TInetAddr iRemoteOriginalAddr; // Private address of the remote end + + // + //NAT Traversal information + // + TBool iFamiliarPeer; // Nokia VPN implementation detected in peer + TBool iNAT_T_Required; // True when NAT detected between local end and peer + + // + // Dead peer detection support + // + TBool iDPDSupported; // Both ends support DPD + + // + //Internal address information received from Nokia VPN gateway + // + CInternalAddress *iInternalAddr; //Internal address and possible DNS addresses + + // + // Certificates + // + TUint8 iEncoding; + CX509Certificate *iPeerX509Cert; //Received X509 certificate (or read in RSA encryption if already stored). + + // + // Trusted CA certificates list + // + HBufC8* iPeerTrustedCA; //Trusted CA (of peer) + HBufC8* iICA1; //Level 1 Intermediate certificate + HBufC8* iICA2; //Level 2 Intermediate certificate + HBufC8* iCA; + HBufC8* iOwnCert; //Certificate in use + + TBool iSendCert; //Tells if is Required to send our cert in next stage (Told in a Cert Req.) + TBool iCertRequested; //Tells whether we've requested a CERT through a CR + + //PFKEY related data + TBool iAcquirePending; //Informs if Acquire is pending + TUint32 iAcquireSeq; //Seq num received in the acquire msg. will be used for UPDATE + TUint32 iSeq; //Current Seq. num will be used in GETSPI + TUint32 iPfkeyAcquirePID; //PID in the acquire msg. will be used in GETSPI + TUint8 iPendingSPI; // Used for GetSPI and Receive in case there are many SPI to request + + //Miscellanious data + HBufC8* iLastMsg; // Last message sent (Used for retransmissions). + CIkev1Timeout *iTimer; // Timer to retry sending a message + TInt iRetryNum; // Number of retry in the current message + TBool iFinished; //Tells if the negotiation is finished to destroy it + TBool iAutoLogin; //If ETrue, Negotiation started by policy activation + TInt iReceivedNotify; //Status value of (the first) received Notify payload + TUint32 iLengthLeft; //Use to check the size of a payload is not bigger than the data left to process + + //References to objects + CIkev1PluginSession* iPluginSession; // IKEv1 plugin session + CIkeV1PkiService* iPkiService; + CIKECRACKNegotiation* iCRACKneg; + CTransNegotiation* iTransactionNeg; + CSARekeyInfo* iSARekeyInfo; + TIkev1IsakmpStream* iSavedIkeMsgBfr; + TBool iVendorIDRfc; + + TBool iPhaseIIAfterIkeSaRekey; // Start PhaseII after IKE SA rekeying + TInt64 iHardLifetime; + + CIpsecSaSpiRetriever* iIpsecSaSpiRetriever; + CPFKeySocketIf& iPFKeySocketIf; + MIkeDebug& iDebug; + }; + +#endif // C_IKEV1NEGOTIATION_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1nokianattkeepalive.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1nokianattkeepalive.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Keepalive object for Nokia IPsec over NAT +* +*/ + + +#ifndef C_IKEV1NOKIANATTKEEPALIVE_H +#define C_IKEV1NOKIANATTKEEPALIVE_H + +#include // TInetAddr + +class CIkev1PluginSession; +class MIkeDebug; + +/** + * Nokia IPsec over NAT keepalive object. Sends + * UDP packets to specified host with specified + * interval to keep NAT mapping alive. Constructing + * the object starts sending and sending is stopped + * when destruction happens. + * @internalComponent + */ +NONSHARABLE_CLASS(CIkev1NokiaNattKeepAlive) : public CBase + { + +public: // Public constructor and destructor + static CIkev1NokiaNattKeepAlive* NewL( CIkev1PluginSession& aPluginSession, + TInetAddr& aDestAddr, + TUint16 aPort, + TUint aInterval, + MIkeDebug& aDebug ); + virtual ~CIkev1NokiaNattKeepAlive(); + +private: // Private constructors + + CIkev1NokiaNattKeepAlive( CIkev1PluginSession& aPluginSession, + TInetAddr& aDestAddr, + TUint16 aPort, + MIkeDebug& aDebug ); + void ConstructL( TUint aInterval ); + +private: + + /** + * Send + * Sends keepalive packet + */ + void Send(); + + /** + * PeriodicCallback + * Callback function which is called everytime + * the interval is reached. + */ + static TInt PeriodicCallback(TAny *aPtr); + +private: + CIkev1PluginSession& iPluginSession; + + TInetAddr iDestAddr; + TUint iPort; + + /** Data to send in keepalive packet */ + TBuf8<1> iMsg; + + CPeriodic *iTimer; + + MIkeDebug& iDebug; + + }; + +#endif // C_IKEV1NOKIANATTKEEPALIVE_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1payload.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1payload.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,88 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: CIkev1payload class +* +*/ + +#ifndef IKEV1PAYLOAD_H +#define IKEV1PAYLOAD_H + +#include + + +class ThdrISAKMP; +class CIkev1Negotiation; +class TSAISAKMP; +class TKeyISAKMP; +class TNonceISAKMP; +class THashISAKMP; +class TSignatureISAKMP; +class TNATOaISAKMP; +class TCHREISAKMP; +class TINTNETISAKMP; +class TAttributeISAKMP; +class TIdentISAKMP; +class TCertificateISAKMP; +class TCertificateReqISAKMP; +class TNotificationISAKMP; +class TDeleteISAKMP; +class TVendorISAKMP; +class TNATDISAKMP; +class TPayloadISAKMP; +class MIkeDebug; + +// +// Processing incoming message +// +NONSHARABLE_CLASS(CIkev1Payloads) : public CBase + { +public: + ~CIkev1Payloads(); + static CIkev1Payloads* NewL( const ThdrISAKMP &aHdr, + CIkev1Negotiation& aNegotiation, + MIkeDebug& aDebug ); + TBool ParsePayloadsL(const ThdrISAKMP &aHdr); + + const TSAISAKMP* iSa; + const TKeyISAKMP* iKe; + const TNonceISAKMP* iNonce; + const THashISAKMP* iHash; + const TSignatureISAKMP* iSign; + + const TNATOaISAKMP* iNatOa; + const TCHREISAKMP* iChre; + const TINTNETISAKMP* iIaddr; + const TAttributeISAKMP* iAttr; + + CArrayFixFlat* iIds; + CArrayFixFlat* iCerts; + CArrayFixFlat* iCertReqs; + CArrayFixFlat* iNotifs; + CArrayFixFlat* iDeletes; + CArrayFixFlat* iVids; + CArrayFixFlat* iNatDs; + + CArrayFixFlat* iGenPlds; + + TUint iPadding; + +private: + CIkev1Payloads( CIkev1Negotiation& aNegotiation, + MIkeDebug& aDebug ); + + CIkev1Negotiation& iNegotiation; + MIkeDebug& iDebug; + }; + +#endif //IKEV1PAYLOAD_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1payloads.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1payloads.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,713 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv1 payload handling. +* +*/ + +#ifndef IKEV1PAYLOADS_H +#define IKEV1PAYLOADS_H + +#include +#include "ikemsgheader.h" +#include "ikev1isakmpct.h" + +// +// GENERIC PAYLOAD HEADER +// +class TPayloadISAKMP + { +public: + TPayloadISAKMP() {u.iData32[0] = 0; } + inline TUint8 GetPayload() const; + inline void SetPayload(TUint8 aPayload); + inline TUint16 GetLength() const; + inline void SetLength(TUint16 aLength); + inline TUint8 GetReserved() const; + inline void SetReserved(TUint8 aVal); + inline const TUint8 *SpecificData() const + { return (TUint8 *)((char *)this + sizeof(*this)); } //returns a * to the specific data of this payload + inline const TUint SpecificDataLen() const + { return (GetLength() - sizeof(*this)); } //returns a * to the specific data of this payload + inline const TPayloadISAKMP *Next() const + { return (TPayloadISAKMP *)((char *)this + GetLength()); } + +private: + union + { + TUint32 iData32[1]; + TUint16 iData16[2]; + TUint8 iData8[4]; + } u; + }; +inline TUint8 TPayloadISAKMP::GetPayload() const { return u.iData8[0]; } +inline void TPayloadISAKMP::SetPayload(TUint8 aPayload) { u.iData8[0] = aPayload; } +inline TUint16 TPayloadISAKMP::GetLength() const { return (TUint16)GET16(&u.iData8[2]); } +inline void TPayloadISAKMP::SetLength(TUint16 aLength) { PUT16(&u.iData8[2], aLength); } +inline TUint8 TPayloadISAKMP::GetReserved() const { return u.iData8[1]; } +inline void TPayloadISAKMP::SetReserved(TUint8 aVal) { u.iData8[1] = aVal; } + +// +// SA PAYLOAD +// + + +class TProposalISAKMP; + +//Plus Variable field (Labeled Domain Identifier) from IPSEC DOI (included in length if present) +//use TSAPayloadISAKMP to decodify its values; + +class TSAPayloadISAKMP +{ + public: + inline TSAPayloadISAKMP() {iReserved=0;} + + public: + inline TUint16 GetLength() const { return (TUint16)GET16(&iLength); } + inline void SetLength(TUint16 aLength) { PUT16(iLength, aLength); } + inline TUint16 GetReserved() const { return iReserved; } //No need to swap because always 0 + inline const TSAPayloadISAKMP *Next() const //next payload + { return (TSAPayloadISAKMP *)((TUint8 *)this + GetLength()); } + inline const TUint32 *Data() const + { return (TUint32 *)(this + sizeof(*this)); } //returns the address of the data field + + private: + TUint16 iLength; + TUint16 iReserved; +}; +//followed by a variable size field of the length indicated + +class TSAISAKMP : public TPayloadISAKMP +{ +public: + inline TUint32 Size() const { return sizeof(TSAISAKMP); } //sizeof OK because aligned + inline TUint32 GetDOI() const { return GET32(&iDOI); } + inline void SetDOI(TUint32 aDOI) { PUT32(&iDOI, aDOI); } + inline TUint32 GetSIT() const { return GET32(&iSIT); } + inline void SetSIT(TUint32 aSIT) { PUT32(&iSIT, aSIT); } + inline TUint GetSITLength() const + { + if ( GetDOI() == IPSEC_DOI) //IPSEC DOI has SPI of size 4 octets + return 4; + return 0; + } + inline TBool HasLDId() const + { + TUint32 sit=(IPSEC_SIT_SECRECY | IPSEC_SIT_INTEGRITY); + if ((GetDOI()==IPSEC_DOI) && (GetSIT() & sit)) + return ETrue; //DOI and (SECRECY or INTEGRITY) supported + + return EFalse; + } + static inline TSAISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TSAISAKMP *)aPayload; } + inline TUint32 *Data() const + { return (TUint32 *)(this + sizeof(*this)); } //returns the address of the data field following the header + TPayloadISAKMP* Payload() const + { + TUint size= sizeof(*this); //fixed size + if (!HasLDId()) + return (TPayloadISAKMP *) ((TUint8*)this + size); + size += 4; //Labeled Domain Identifier payload size + TUint32 *d=Data(); + TSAPayloadISAKMP *p = (TSAPayloadISAKMP *)++d; + TInt32 res; + + for (TInt i=0; i < 4; i++) + { + if (i % 2==0) //Fields 1 and 3 in bytes + Math::Int(res, p->GetLength() / 4); + else //Fields 2, 4 in bits + Math::Int(res, p->GetLength() / 32); + + size += res+1; + } + + return (TPayloadISAKMP *) ((TUint8 *)this + size); + } + + TUint32 iDOI; + TUint32 iSIT; +}; + +class TTransformISAKMP; +class TProposalISAKMP : public TPayloadISAKMP + { +public: + inline TUint32 Size() const { return sizeof(TProposalISAKMP); }//sizeof OK because aligned + inline TUint8 GetNum() const { return iNum; }; + inline void SetNum(TUint8 aPayload) { iNum = aPayload; }; + inline TUint8 GetProtocol() const { return iProtocol; }; + inline void SetProtocol(TUint8 aPayload) { iProtocol = aPayload; }; + inline TUint8 GetSPISize() const { return iSPISize; }; + inline void SetSPISize(TUint8 aPayload) { iSPISize = aPayload; }; + inline TUint8 GetNumTrans() const { return iNumTrans; }; + inline void SetNumTrans(TUint8 aPayload) { iNumTrans = aPayload; }; + //inline TUint32 GetSPI() const { return iSPI; }; + //inline void SetSPI(TUint32 aSPI) { iSPI = aSPI; }; + static inline TProposalISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TProposalISAKMP *)aPayload; } + inline const TPayloadISAKMP* Payload() const //next payload (transform) + { return (TPayloadISAKMP*)((TUint8*)this + sizeof(*this) + GetSPISize()); } + inline const TUint8 *SPI() {return (const TUint8 *)((TUint8*)this + sizeof(*this));} //* to the SPI + //void String(TDes &aStr) const; + +//private: + TUint8 iNum; //Proposal Number + TUint8 iProtocol; //Protocol ID for the current negotiation PROTO_ISAKMP, PROTO_IPSEC_AH, PROTO_IPSEC_ESP, ... + TUint8 iSPISize; //size in octets. For ISAKMP should be from 0 to 16. If >0 SPI ignored + TUint8 iNumTrans; //Num of transformations + //TUint32 iSPI; //Variable size (depends on protocol). No Padding. + }; + + +class TDataISAKMP; +class TTransformISAKMP : public TPayloadISAKMP + { +public: + inline TTransformISAKMP() {iReserved=0;} +public: + inline TUint32 Size() const { return sizeof(TTransformISAKMP); } //sizeof OK because aligned + inline TUint8 GetNum() const { return iNum; }; + inline void SetNum(TUint8 aPayload) { iNum = aPayload; }; + inline TUint8 GetID() const { return iID; }; + inline void SetID(TUint8 aPayload) { iID = aPayload; }; + inline TUint16 GetReserved() const { return (TUint16)GET16(&iReserved); }; + static inline TTransformISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TTransformISAKMP *)aPayload; } + inline TDataISAKMP *SAAttrib() const {return (TDataISAKMP *)((TUint8*)this + sizeof(*this)); } //* to SA attributes + //void String(TDes &aStr) const; + +//private: + //TPayloadISAKMP iHdr; //Generic part + TUint8 iNum; //Transform Number + TUint8 iID; //Transform ID for the current negotiation AH, ESP, OSPF, TLS, ... + TUint16 iReserved; //always set to 0 +}; + + + +class TKeyISAKMP : public TPayloadISAKMP +{ +public: + static inline TKeyISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TKeyISAKMP *)aPayload; } + //void String(TDes &aStr) const; + inline TUint8 *KeyData() const {return ((TUint8*)this + sizeof(*this)); } //* to keyData + +}; + + +//would require a few modifications for DOI != IPSECDOI +class TIdentISAKMP : public TPayloadISAKMP +{ +public: + inline TUint8 GetIDType() const { return iIDType; } + inline void SetIDType(TUint8 aIDType) { iIDType=aIDType; } + //IPSEC DOI Specific routines + inline TUint8 GetProtocol() const { return iProtocolID; } + inline void SetProtocol(TUint8 aProtocolID) { iProtocolID = aProtocolID; }; + inline TUint16 GetPort() const { return (TUint16)GET16(&iPort); } + inline void SetPort(TUint16 aPort) { PUT16(&iPort, aPort); } + // + static inline TIdentISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TIdentISAKMP *)aPayload; } + //TBool String(TDes &aStr,TUint aLength) const; + inline TUint8 *IDData() const {return ((TUint8*)this + sizeof(*this)); } //* to identity data + inline TUint16 IDDataLen() const {return (TUint16)(GetLength() - sizeof(*this)); } //Length of the payload data +public: + TUint8 iIDType; + //IPSEC DOI Specific fields + TUint8 iProtocolID; + TUint16 iPort; + +}; + + + +//Used for certificate +//WARNING:Do not use sizeof this class, better Size because size of returns aligned size and not the real. +class TCertificateISAKMP: public TPayloadISAKMP +{ +public: + inline TUint8 GetEncoding() const { return iEncoding; } + inline void SetEncoding(TUint8 aEncoding) { iEncoding = aEncoding; } + static inline TUint16 Size() {return (sizeof(TPayloadISAKMP) + sizeof(TUint8));} //TUint8 is iEncoding + inline TUint16 CertDataLen() const {return (TUint16)(GetLength()-Size()); } //* to certificate data + inline TUint8 *CertData() const {return ((TUint8*)this + Size()); } + //+1 for iEncoding.Cannot use sizeof(*this) because is not aligned and returns 8 instead of 5 + + static inline TCertificateISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TCertificateISAKMP *)aPayload; } + + TUint8 iEncoding; // Certificate Encoding + +}; + + + +//Used for certificate Request payloads +class TCertificateReqISAKMP : public TPayloadISAKMP +{ +public: + inline TUint8 GetEncoding() const { return iEncoding; } + inline void SetEncoding(TUint8 aEncoding) { iEncoding= aEncoding; } + static inline TUint16 Size() {return (sizeof(TPayloadISAKMP) + sizeof(TUint8));} //TUint8 is iEncoding + static inline TCertificateReqISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TCertificateReqISAKMP *)aPayload; } + inline TUint16 CertReqDataLen() const {return (TUint16)(GetLength() - Size()); } //* to certificate data + inline TUint8 *CertReqData() const {return ((TUint8*)this + Size()); } + + TUint8 iEncoding; // Certificate Encoding + +}; + +class THashISAKMP : public TPayloadISAKMP +{ +public: + static inline THashISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (THashISAKMP *)aPayload; } + inline TUint8 *Data() const {return ((TUint8*)this + sizeof(*this)); } //pointer to hash data + inline TUint16 DataLen() const {return (TUint16)(GetLength() - sizeof(*this)); } //pointer to hash data + //TBool String(TDes &aStr,TUint aLength) const; +}; + + +class TSignatureISAKMP : public TPayloadISAKMP +{ +public: + static inline TSignatureISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TSignatureISAKMP *)aPayload; } + inline TUint16 GetDataLength() const //Length of the data part in bytes + { return (TUint16)(GetLength() - sizeof(*this));} + inline TUint8 *SigData() const {return ((TUint8*)this + sizeof(*this)); } //pointer to signature data + +}; + +class TNonceISAKMP : public TPayloadISAKMP +{ +public: + static inline TNonceISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TNonceISAKMP *)aPayload; } + + inline TUint8 *NonceData() const {return ((TUint8*)this + sizeof(*this)); } //* to Nonce Data + inline TUint16 NonceDataLen() const {return (TUint16)(GetLength() - sizeof(*this)); } //* to Nonce Data +}; + + + +class TNotificationISAKMP : public TPayloadISAKMP +{ +public: + inline TUint32 GetDOI() const { return GET32(&iDOI); }; + inline void SetDOI(TUint32 aDOI) { PUT32(&iDOI, aDOI); }; + inline TUint8 GetProtocol() const { return iProtocol; }; + inline void SetProtocol(TUint8 aPayload) { iProtocol = aPayload; }; + inline TUint8 GetSPISize() const { return iSPISize; }; + inline void SetSPISize(TUint8 aPayload) { iSPISize = aPayload; }; + inline TUint16 GetMsgType() const { return (TUint16)GET16(&iMsgType); }; + inline void SetMsgType(TUint16 aMsgType) { PUT16(&iMsgType, aMsgType); }; + inline TUint8 *GetSPI() const { return ((TUint8*)this + sizeof(*this)); }; //returns the SPI Data + inline TUint8 *GetNotifData() const { return ((TUint8*)this + sizeof(*this) + iSPISize); }; //returns the Notification Data + inline TUint16 GetNotifDataSize() const { return (TUint16)(GetLength() - (sizeof(*this) + iSPISize)); };//returns the Notification Data Length + + static inline TNotificationISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TNotificationISAKMP *)aPayload; } + + TUint32 iDOI; //Domain Of Interpretation + TUint8 iProtocol; //Protocol ID for the current notification + TUint8 iSPISize; //size in octets. For ISAKMP should be from 0 to 16. If >0 SPI ignored + TUint16 iMsgType; //Notify msg type. See constants. + //Plus the variable fields SPI and Notification Data (both included in length) +private: + inline void MsgTypeToStr(TDes &aBuf, TUint16 aMsgType) const + { +#ifdef _DEBUG + switch (aMsgType) + { + //NOTIFY MESSAGES - ERROR TYPES + case INVALID_PAYLOAD_TYPE: + aBuf = _L("INVALID_PAYLOAD_TYPE"); + break; + case DOI_NOT_SUPPORTED: + aBuf = _L("DOI_NOT_SUPPORTED"); + break; + case SITUATION_NOT_SUPPORTED: + aBuf = _L("SITUATION_NOT_SUPPORTED"); + break; + case INVALID_COOKIE: + aBuf = _L("INVALID_COOKIE"); + break; + case INVALID_MAJOR_VERSION: + aBuf = _L("INVALID_MAJOR_VERSION"); + break; + case INVALID_MINOR_VERSION: + aBuf = _L("INVALID_MINOR_VERSION"); + break; + case INVALID_EXCHANGE_TYPE: + aBuf = _L("INVALID_EXCHANGE_TYPE"); + break; + case INVALID_FLAGS: + aBuf = _L("INVALID_FLAGS"); + break; + case INVALID_MESSAGE_ID: + aBuf = _L("INVALID_MESSAGE_ID"); + break; + case INVALID_PROTOCOL_ID: + aBuf = _L("INVALID_PROTOCOL_ID"); + break; + case INVALID_SPI: + aBuf = _L("INVALID_SPI"); + break; + case INVALID_TRANSFORM_ID: + aBuf = _L("INVALID_SPI"); + break; + case ATTRIBUTES_NOT_SUPPORTED: + aBuf = _L("ATTRIBUTES_NOT_SUPPORTED"); + break; + case NO_PROPOSAL_CHOSEN: + aBuf = _L("NO_PROPOSAL_CHOSEN"); + break; + case BAD_PROPOSAL_SYNTAX: + aBuf = _L("BAD_PROPOSAL_CHOSEN"); + break; + case PAYLOAD_MALFORMED: + aBuf = _L("PAYLOAD_MALFORMED"); + break; + case INVALID_KEY_INFORMATION: + aBuf = _L("INVALID_KEY_INFORMATION"); + break; + case INVALID_ID_INFORMATION: + aBuf = _L("INVALID_ID_INFORMATION"); + break; + case INVALID_CERT_ENCODING: + aBuf = _L("INVALID_CERT_ENCODING"); + break; + case INVALID_CERTIFICATE: + aBuf = _L("INVALID_CERTIFICATE"); + break; + case CERT_TYPE_UNSUPPORTED: + aBuf = _L("CERT_TYPE_UNSUPPORTED"); + break; + case INVALID_CERT_AUTHORITY: + aBuf = _L("INVALID_CERT_AUTHORITY"); + break; + case INVALID_HASH_INFORMATION: + aBuf = _L("INVALID_HASH_INFORMATION"); + break; + case AUTHENTICATION_FAILED: + aBuf = _L("AUTHENTICATION_FAILED"); + break; + case INVALID_SIGNATURE: + aBuf = _L("INVALID_SIGNATURE"); + break; + case ADDRESS_NOTIFICATION: + aBuf = _L("ADDRESS_NOTIFICATION"); + break; + case NOTIFY_SA_LIFETIME: + aBuf = _L("NOTIFY_SA_LIFETIME"); + break; + case CERTIFICATE_UNAVAILABLE: + aBuf = _L("CERTIFICATE_UNAVAILABLE"); + break; + case UNSUPPORTED_EXCHANGE_TYPE: + aBuf = _L("UNSUPPORTED_EXCHANGE_TYPE"); + break; + case UNEQUAL_PAYLOAD_LENGTHS: + aBuf = _L("UNEQUAL_PAYLOAD_LENGTHS"); + break; + case CONNECTED: + aBuf = _L("CONNECTED"); + break; + default: + if ((aMsgType>30) && (aMsgType < 8192)) + aBuf.Format(_L("ERROR RESERVED Future Use (%d)"),aMsgType); + else if ((aMsgType>8191) && (aMsgType < 16384)) + aBuf.Format(_L("ERROR Private Use (%d)"),aMsgType); + else if (((aMsgType>16384) && (aMsgType < 24576)) || ((aMsgType>40959) && (aMsgType < 65536))) + aBuf.Format(_L("STATUS RESERVED Future Use (%d)"),aMsgType); + else if ((aMsgType>24575) && (aMsgType < 32768)) + aBuf.Format(_L("STATUS DOI Specific (%d)"),aMsgType); + else if ((aMsgType>32767) && (aMsgType < 40959)) + aBuf.Format(_L("STATUS Private Use (%d)"),aMsgType); + else + aBuf.Format(_L("UNKNOWN ERROR (%d)"),aMsgType); + } +#else + (void)aBuf; + (void)aMsgType; +#endif + } + + inline void ProtocolToStr(TDes& aBuf, TUint16 aProtocol) const + { +#ifdef _DEBUG + + switch (aProtocol) + { + //Protocol number for IPSEC DOI (=1) + case PROTO_ISAKMP: + aBuf = _L("PROTO_ISAKMP"); + break; + case PROTO_IPSEC_AH: + aBuf = _L("PROTO_IPSEC_AH"); + break; + case PROTO_IPSEC_ESP: + aBuf = _L("PROTO_IPSEC_ESP"); + break; + case PROTO_IPCOMP: + aBuf = _L("PROTO_IPCOMP"); + break; + default: + aBuf.Format(_L("Unknown (%d) "),aProtocol); + } +#else + (void)aBuf; + (void)aProtocol; +#endif + } + + +}; + +class TDeleteISAKMP : public TPayloadISAKMP +{ +public: + inline TUint32 DOI() const { return GET32(&iDOI); }; + inline void SetDOI(TUint32 aDOI) { PUT32(&iDOI, aDOI); }; + inline TUint8 Protocol() const { return iProtocol; }; + inline void SetProtocol(TUint8 aPayload) { iProtocol = aPayload; }; + inline TUint8 SPISize() const { return iSPISize; }; + inline void SetSPISize(TUint8 aPayload) { iSPISize = aPayload; }; + inline TUint16 NumSPI() const { return (TUint16)GET16(&iNumSPI); }; + inline void SetNumSPI(TUint16 aNumSPI) { PUT16(&iNumSPI, aNumSPI); }; + + static inline TDeleteISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TDeleteISAKMP *)aPayload; } + inline TUint8 *SPIList() const {return ((TUint8*)this + sizeof(*this)); } //* to Vendor ID Data + inline TUint8 *SPI(TUint i) const {return ((TUint8*)this + sizeof(*this) + i * SPISize()); } //i-th SPI + inline void String(TDes &aStr) const + { +#ifdef _DEBUG + aStr.Append(_L(" Delete payload ")); + aStr.AppendFormat(_L(" DOI= %u"), DOI()); + aStr.AppendFormat(_L(" Prot=%u "), Protocol()); + aStr.AppendFormat(_L(" SPIsize= %u"), SPISize()); + aStr.AppendFormat(_L(" #SPI=%u "), NumSPI()); + //2 variable size fields + + //TUint8 *p=((TUint8 *)Payload()); + TUint8 *p; + for (TInt i=0; i < NumSPI(); i++) + { + aStr.AppendFormat(_L(" #SPI(%d)="),i); + p=SPI(i); + for (TUint j=0 ; j < SPISize() ; j++) + { + if (j%4==0) + aStr.AppendFormat(_L(" ")); + aStr.AppendFormat(_L("%02.2x"), p[j]); //not sure SPI + } + } +#else + (void)aStr; +#endif + } + + TUint32 iDOI; //Domain Of Interpretation + TUint8 iProtocol; //Protocol ID for the current notification + TUint8 iSPISize; //size in octets. For ISAKMP should be from 0 to 16. If >0 SPI ignored + TUint16 iNumSPI; //# of SPIs to be deleted + //Plus iNumSPI variable fields SPI +}; + + +class TVendorISAKMP : public TPayloadISAKMP +{ +public: + static inline TVendorISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TVendorISAKMP *)aPayload; } + inline TUint8 *VIDData() const {return ((TUint8*)this + sizeof(*this)); } //* to Vendor ID Data + +}; + +class TCHREISAKMP : public TPayloadISAKMP +{ +public: + static inline TCHREISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TCHREISAKMP *)aPayload; } + inline TUint16 GetLAMtype() const { return (TUint16)GET16(&iLAMType); } + inline void SetLAMtype(TUint16 aLength) { PUT16(&iLAMType, aLength); } + inline TUint16 GetCHREReserved() const { return iReserved; } + inline void SetCHREReserved() { iReserved = 0; } + inline TDataISAKMP *CHREAttrib() const {return (TDataISAKMP *)((TUint8*)this + sizeof(*this)); } //* to CHRE attributes + //void String(TDes &aStr) const; + TUint16 iLAMType; //LAM type + TUint16 iReserved; //reserved must be zero +}; + +class TINTNETISAKMP : public TPayloadISAKMP +{ +public: + static inline TINTNETISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TINTNETISAKMP *)aPayload; } + inline TDataISAKMP *INTNETAttrib() const {return (TDataISAKMP *)((TUint8*)this + sizeof(*this)); } //* to INTNET attributes + //void String(TDes &aStr) const; +}; + +class TNATDISAKMP : public TPayloadISAKMP +{ +public: + static inline TNATDISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TNATDISAKMP *)aPayload; } + inline TUint8 *HashData() const {return ((TUint8*)this + sizeof(*this)); } //* to NAT D hash data + inline TUint32 HashLth() const {return (GetLength() - sizeof(*this)); }; +}; + + +class TNATOaISAKMP : public TPayloadISAKMP +{ +public: + inline TUint8 GetIDType() const { return iIDType; } + inline void SetIDType(TUint8 aIDType) { iIDType=aIDType; } + inline void SetReservedFields() { iReserved8=0; PUT16(iReserved16, 0); } + // + static inline TNATOaISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TNATOaISAKMP *)aPayload; } + + inline TUint8 *OAData() const {return ((TUint8*)this + sizeof(*this)); } //* to identity data + inline TUint16 OADDataLen() const {return (TUint16)(GetLength() - sizeof(*this)); } //Length of the payload data +public: + TUint8 iIDType; + //IPSEC DOI Specific fields + TUint8 iReserved8; + TUint16 iReserved16; + +}; + +class TAttributeISAKMP : public TPayloadISAKMP +{ +public: + inline TUint8 CfgMsgType() const { return iCfgMsgType; } + inline void SetCfgMsgType(TUint8 aMsgType) { iCfgMsgType=aMsgType; } + inline void SetReservedField() { iReserved8=0;} + inline TUint16 Identifier() const { return (TUint16)GET16(&iIdentifier);} + inline void SetIdentifier(TUint16 aIdentifier) { PUT16(&iIdentifier, aIdentifier); } + // + static inline TAttributeISAKMP *Ptr(const TPayloadISAKMP *aPayload) + { return (TAttributeISAKMP *)aPayload; } + inline TDataISAKMP *AttrData() const {return (TDataISAKMP *)((TUint8*)this + sizeof(*this)); } //* to attribute data + inline TInt AttrDataLen() const {return (TInt)(GetLength() - sizeof(*this)); } //Length of the payload data +public: + TUint8 iCfgMsgType; + TUint8 iReserved8; + TUint16 iIdentifier; + +}; + + +// +// DATA ATTRIBUTES +// +class TDataISAKMP + { +public: + TDataISAKMP(){u.iData32[0] = 0;} + inline TBool IsBasic() const {return ((u.iData8[0] & 0x80) != 0);} //return if basic attrib or variable + inline void SetBasic(TBool aIsBasic) + { + if (aIsBasic) + u.iData8[0] |= 0x80; + else u.iData8[0] &= 0x7F; + } + inline TUint16 Type() const { return (TUint16)(GET16(&u.iData16[0]) & (TUint16)0x7FFF);} + inline void SetType(TUint16 aType) + { + u.iData8[1] = (TUint8)(aType & 0x00ff); + u.iData8[0] &= 0x80; + u.iData8[0] |= ((TUint8)(aType >> 8)) & 0x7F; + } + inline TUint16 Length() const + { + if (!IsBasic()) + return (TUint16)GET16(&u.iData16[1]); + return 0; //No length needed + } + inline void SetLength(TUint16 aLength) { if (!IsBasic()) PUT16(&u.iData16[1], aLength); } + inline TUint16 Value() const + { + if (IsBasic()) + return (TUint16)GET16(&u.iData16[1]); + return 0; + } + inline void SetValue(TUint16 aValue) { if (IsBasic()) PUT16(&u.iData16[1], aValue);} + inline TUint8 *VarValue() const + { + if (!IsBasic()) + return ((TUint8*)this + sizeof(*this)); + return NULL; + } + inline TUint Size() { return (sizeof(*this) + Length());} //return attr header full size + inline TDataISAKMP *Next() {return (TDataISAKMP *)((TUint8*)this + sizeof(*this) + Length());} //next attribute +public: + union + { + TUint32 iData32[1]; + TUint16 iData16[2]; + TUint8 iData8[4]; + } u; + }; +//Plus Length() bytes if variable attrib; + +// +// TLastIKEMsg +// This class is used to detect possible IKE message retransmission from peer. +// The following information is stored to object data in consturctor: +// -- IKE message length (octets iData8[0], iData8[1] and iData8[2]) +// -- Next payload code (iData8[3]) +// -- IP checksum over entire IKE message (iData32[1]) +// +class TLastIKEMsg + { +public: + inline TLastIKEMsg() { u.iData32[0] = 0; u.iData32[1] = 0;} + inline TLastIKEMsg(const ThdrISAKMP& aHdr) + { + u.iData32[0] = aHdr.GetLength(); + TUint16 *End = (TUint16*)((TUint8*)&aHdr + (u.iData32[0] & 0xfffffffe)); + TUint16 *Ptr = (TUint16*)&aHdr; + u.iData8[3] = aHdr.GetPayload(); // MUST NOT be stored before length value ! + TUint32 sum = 0; + while ( Ptr < End ) sum += *Ptr++; + u.iData32[1] = sum; + } + inline TBool IsUninitialized() + { + if (u.iData32[0] == 0 && u.iData32[1] == 0) + return ETrue; + return EFalse; + } + inline void Store(TLastIKEMsg& aRef) + { aRef.u.iData32[0] = u.iData32[0]; aRef.u.iData32[1] = u.iData32[1]; } + inline TBool IsReTransmit(TLastIKEMsg& aRef) + { return ((u.iData32[0] == aRef.u.iData32[0]) && (u.iData32[1] == aRef.u.iData32[1]));} +private: + union + { + TUint32 iData32[2]; + TUint8 iData8[8]; + } u; + }; + + +#endif // IKEV1PAYLOADS_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1plugin.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1plugin.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,176 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv1 protocol plugin interface. +* +*/ + +#ifndef C_IKEV1PLUGIN_H +#define C_IKEV1PLUGIN_H + +#include + +#include "ikepluginif.h" +#include "pfkeysocketif.h" + +// FORWARD DECLARATIONS +class CIkev1PluginSession; +class CIpsecPolicyUtil; +class CIpsecSaSpecList; +class CPFKeySocketIf; +class MIkeDataInterface; +class MIkeDebug; +class MKmdEventLoggerIf; +class TIpsecSPI; +class TInetAddr; + +/** +* Ikev1 protocol plugin +* @internalComponent +*/ +/** + * IKEv1 protocol plugin. + * + * @lib internal (ikev1lib.lib) + */ + +NONSHARABLE_CLASS(CIkev1Plugin) : public CBase, + public MIkePluginIf, + public MPFKeyMessageListener + { +public: + /** + * Two-phased constructor. + * @param aEventLogger Event logger interface + * @param aDebug Debug trace interface + */ + static CIkev1Plugin* NewL( MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ); + /** + * Destructor. + */ + ~CIkev1Plugin(); + + /** + * Handles IKE plugin session deletion. + * @param aPluginSession IKE plugin session + */ + void IkePluginSessionDeleted( CIkev1PluginSession* aPluginSession ); + + /** + * Gets acceptable IPsec policies for specified selectors. + * + * @param aLocalAddr IP address, including possible port, of the local end selector + * @param aLocalMask Local end selector mask + * @param aRemoteAddr IP address, including possible port, of the remote end selector + * @param aRemoteMask Remote end selector mask + * @param aProtocol Protocol id + * @param aVpnNetId VPN net id + */ + CIpsecSaSpecList* GetIpseSaSpecListLC( const TInetAddr& aLocalAddr, const TInetAddr& aLocalMask, + const TInetAddr& aRemoteAddr, const TInetAddr& aRemoteMask, + TInt aProtocol, TUint32 aVpnNetId ); + + /** + * Returns UID. + */ + TUint32 Uid(); + + /** + * Returns event logger interface. + */ + MKmdEventLoggerIf& EventLogger(); + + +// Methods to build and send PFKEY API primitives to IPsec + + void AcquireSAError( TIpsecSAData& aSAData, + TInt aError ); + + void UpdateSAL( TIpsecSAData& aSaData ); + + void AddSAL( TIpsecSAData& aSaData ); + + void DeleteIpsecSA( TIpsecSPI& aIpsecSpi ); + + void DeleteIpsecSA( TUint32 aSPI, + TInetAddr& aSrc, + TInetAddr& aDst, + TUint8 aProtocol ); + +// from base class MIkePluginIf + + /** + * From MIkePluginIf. + * Creates IKEv1 plugin session. + * @param aVpnIapId VPN IAP id + * @param aVpnNetId VPN NET id + * @param aVpnInterfaceIndex VPN interface index + * @param aDataInterface IKE data interface. + * @return IKEv1 plugin session. Ownership transferred. + */ + MIkePluginSessionIf* CreateSessionL( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + MIkeDataInterface& aDataInterface ); + +// from base class MPFKeyMessageListener + + /** + * From MPFKeyMessageListener. + * Handles received PFKEY message. + * @param aPfkeyMessage PFKEY message + */ + void PfkeyMessageReceived( const TPfkeyMessage& aPfkeyMessage ); + +private: + CIkev1Plugin( MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ); + void ConstructL(); + + +private: + + /** + * VPN PF key socket. + * Own. + */ + CPFKeySocketIf* iPFKeySocket; + + /** + * IPSec policy util. + * Own. + */ + CIpsecPolicyUtil* iIpsecPolicyUtil; + + /** + * IKEv1 plugin sessions. + * Not own. + */ + RArray iPluginSessions; + + /** + * Event logger. + * Not own. + */ + MKmdEventLoggerIf& iEventLogger; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + }; + + +#endif // C_IKEV1PLUGIN_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1pluginsession.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1pluginsession.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,723 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv1 plugin session +* +*/ + + +#ifndef C_IKEV1PLUGINSESSION_H +#define C_IKEV1PLUGINSESSION_H + +#include + +#include "vpnmandefs.h" +#include "ikemsgheader.h" +#include "ikepluginsessionif.h" +#include "ikev1receiver.h" +#include "ikev1sender.h" +#include "ikesendqueueitem.h" + +// FORWARD DECLARATIONS +class CIkev1Plugin; +class CIkev1Dialog; +class CIkev1Negotiation; +class CIkev1PluginSession; +class CInternalAddress; +class TDeleteISAKMP; +class CAuthDialogInfo; +class CIkev1SA; +class TIkev1SAData; +class CSARekeyInfo; +class TIpsecSPI; +class MIkeDebug; +class ThdrISAKMP; +class TPfkeyMessage; +class TIpsecSAData; +class MKmdEventLoggerIf; +class CIpsecSaSpecList; +class CPFKeySocketIf; + +NONSHARABLE_CLASS(CIkev1PluginSession) : public CBase, + public MIkePluginSessionIf, + public MIkev1ReceiverCallback, + public MIkev1SenderCallback + + { +public: + /** + * Two-phased constructor. + * @param aVpnIapId VPN IAP id + * @param aVpnNetId VPN NET id + * @param aVpnInterfaceIndex VPN interface index + * @param aDataInterface Data interface + * @param aPlugin IKE plugin + * @param aPFKeySocketIf PF key socket interface + * @param aDebug Debug trace interface + */ + static CIkev1PluginSession* NewL( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + MIkeDataInterface& aDataInterface, + CIkev1Plugin& aPlugin, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug ); + + /** + * Destructor. + */ + ~CIkev1PluginSession(); + + /** + * Handles IKE SA deletion request. + * @param aIkev1SaData IKEv1 SA data + * @param aSilentClose Silent close + */ + TBool DeleteIkeSA( TIkev1SAData* aIkev1SAdata, + TBool aSilentClose = EFalse ); + + /** + * Handles IKE SA rekeying request. + * @param aIkev1SaData IKEv1 SA data + * @param aSaRekeyInfo Rekey info + */ + void RekeyIkeSAL( TIkev1SAData* aIkev1SaData, + CSARekeyInfo* aSaRekeyInfo ); + + /** + * Handles IKE SA keepalive request. + * @param aIkev1SaData IKEv1 SA data + */ + void KeepAliveIkeSAL( TIkev1SAData* aIkev1SaData ); + + /** + * Creates IKE SA. + * @param aIkev1SaData IKEv1 SA data + * @param aSaRekeyInfo Rekey info + */ + void CreateIkev1SAL( TIkev1SAData& aIkev1SaData, + CSARekeyInfo* aSaRekeyInfo ); + + /** + * Updates IKE SA. + * @param aSaId SA id + * @param aExpired Expired + * @param aIkev1SaData IKEv1 SA data + */ + void UpdateIkev1SAL( TUint32 aSaId, + TBool aExpired, + TIkev1SAData* aIkev1SaData = NULL ); + + /** + * Expires IKE SA. + * @param aSaId SA id + */ + void ExpireIkev1SA( TUint32 aSaId ); + + /** + * Removes IKE SA. + * @param aIkev1Sa IKE SA + * @param aStatus Error status + */ + void RemoveIkeSA( CIkev1SA* aIkev1Sa, + TInt aStatus ); + +// IKE SA find methods + + CIkev1SA* FindIkev1SA(); + CIkev1SA* FindIkev1SA( const TCookie& aCookie_I, + const TCookie& aCookie_R ); + CIkev1SA* FindIkev1SAWithId( TUint32 aSaId ); + CIkev1SA* FindIkev1SA( const TInetAddr& aAddr ); + CIkev1SA* FindIkev1SA( const TInetAddr& aAddr, + TUint32 aInboundSpi ); + + TIkev1SAData* FindIkev1SAData(); + TIkev1SAData* FindIkev1SAData( const TCookie& aCookie_I, + const TCookie& aCookie_R ); + TIkev1SAData* FindIkev1SAData( TUint32 aSaId ); + TIkev1SAData* FindIkev1SAData( const TInetAddr& aAddr, + TUint32 aInboundSpi ); + TIkev1SAData* FindIkev1SADataWithAddr( const TInetAddr& aAddr ); + + /** + * Handles IPsec SA deletion request. + * @param aIkev1SaData IKEv1 SA data + * @param aIpsecSpi IPsec SPI + */ + void DeleteIpsecSAL( TIkev1SAData* aIkev1SaData, + TIpsecSPI* aIpsecSpi ); + + /** + * Deletes IPsec SAs. + * @param aSaId SA id + */ + void DeleteIpsecSAs( TUint32 aSAId ); + + /** + * Deletes IPsec SPI. + * @param aSaId SA id + * @param aSpi SPI + * @param aInbound Inbound + */ + TBool DeleteIpsecSpi( TUint32 aSaId, + TUint32 aSpi, + TBool aInbound = EFalse ); + + /** + * Adds IPsec SPI to IKE SA. + * @param aSaId SA id + * @param aIpsecSpi IPsec SPI + */ + void AddIpsecSPIToSAL( TUint32 aSaId, + TIpsecSPI& aIpsecSpi ); + + /** + * Returns dialog anchor. + */ + CIkev1Dialog** DialogAnchor(); + + /** + * Returns debug trace interface. + */ + MIkeDebug& Debug(); + + /** + * Gets SA id. + */ + TUint32 GetSAId(); + + /** + * Deletes ISAKMP SAs. + * @param aDeletePayload Delete payload which identifies ISAKMP/IKE SA. + * @param aInfoNegotiation Negotiation object used by CIkev1InfoNegotiation + * object. + */ + void DeleteISAKMPSAsL( TDeleteISAKMP* aDeletePayload, + const CIkev1Negotiation& aInfoNegotiation ); + + /** + * Requests sending of IKE message. + * @param aIkeMsg IKE message + * @param aDestAddr Destination IP address/port + * @param aUseNatPort NAT used or not + */ + void SendIkeMsgL( const TDesC8& aIkeMsg, + TInetAddr& aDestAddr, + TBool aUseNatPort ); + + /** + * Gets local IP address. + * @param aAddr Local IP address (returned) + * @return Error value + */ + TInt GetLocalAddress( TInetAddr& aAddr ); + + /** + * Sends NAT keep-alive packet. + * @param aDestAddr Destination IP address/port + * @param Keep-alive data + * @param aDscp DSCP value + */ + void SendNatKeepAliveL( TInetAddr& aDestAddr, + const TDesC8& aData, + TUint8 aDscp ); + + /** + * Sends Nokia NAT keep-alive packet. + * @param aDestAddr Destination IP address/port + * @param Keep-alive data + * @param aDscp DSCP value + */ + void SendNokiaNatKeepAliveL( TInetAddr& aDestAddr, + const TDesC8& aData, + TUint8 aDscp ); + + /** + * Handles completion of IKE SA establishment. + * @param aStatus Completion status + * @param aInternalAddress Internal address. Ownership transferred. + */ + void IkeSaCompleted( TInt aStatus, + CInternalAddress* aInternalAddress = NULL ); + + /** + * Deletes negotiation object. + * @param aNegotiation Negotiation + */ + void DeleteNegotiation( CIkev1Negotiation* aNegotiation ); + + // Negotiation linking and finding methods + void LinkNegotiation( CIkev1Negotiation* aNegotiation ); + CIkev1Negotiation* FirstNegotiation(); + CIkev1Negotiation* FindNegotiation( TUint32 aSaId ); + CIkev1Negotiation* FindNegotiation( TCookie aInit, + TCookie aResp, + TUint8 aExchange, + TUint32 aMsgId ); + void RemoveNegotiation( CIkev1Negotiation* aNegotiation ); + + /** + * Handles completion of authentication dialog processing. + * @param aUserInfo User info + * @return Error value + */ + TInt AuthDialogCompletedL( CAuthDialogInfo* aUserInfo ); + + /** + * Handles change of internal address. + * @param aInternalAddr Internal address + * @return Informs if internal address differs from existing internal address + */ + TBool InternalAddressChangedL( const CInternalAddress& aInternalAddr ); + + /** + * Gets acceptable IPsec policies for specified selectors. + * + * @param aLocalAddr IP address, including possible port, of the local end selector + * @param aLocalMask Local end selector mask + * @param aRemoteAddr IP address, including possible port, of the remote end selector + * @param aRemoteMask Remote end selector mask + * @param aProtocol Protocol id + * @param aVpnNetId VPN net id + */ + CIpsecSaSpecList* GetIpseSaSpecListLC( const TInetAddr& aLocalAddr, const TInetAddr& aLocalMask, + const TInetAddr& aRemoteAddr, const TInetAddr& aRemoteMask, + TInt aProtocol ); + + /** + * Handles fatal error. + * @param aStatus Error status + */ + void HandleError( TInt aStatus ); + + /** + * Returns error status. + * @return Error status + */ + TInt ErrorStatus(); + + /** + * Sets error status. + * @param aStatus Error status + */ + void SetErrorStatus( TInt aStatus ); + + /** + * Returns VPN IAP id. + * @return VPN IAP id + */ + TUint32 VpnIapId(); + + /** + * Returns VPN interface index. + */ + TUint32 VpnInterfaceIndex(); + + /** + * Returns IKE policy data. + * @return IKE policy data + */ + CIkeData& IkeData(); + + /** + * Returns UID. + * @return UID + */ + TUint32 Uid(); + + /** + * Returns event logger interface. + * @return Eveng logger interface + */ + MKmdEventLoggerIf& EventLogger(); + + /** + * Returns internal address (NULL if does not exist). + * @return Internal address. Ownership transferred. + */ + CInternalAddress* InternalAddressL(); + + +// PFKEY related methods + + /** + * Matches destination address to remote address in IKE policy data. + * @param aDestAddr Destination IP address + * @return ETrue if matches. + */ + TBool MatchDestinationAddress( const TInetAddr& aDestAddr ); + + /** + * Handles received PFKEY message. + * @param aPfkeyMessage PFKEY message + */ + void PfkeyMessageReceived( const TPfkeyMessage& aPfkeyMessage ); + +// Methods to build and send PFKEY API primitives to IPsec + + void GetIpsecSPI( TUint8 aType, + TUint32 aSeq, + TInetAddr& aSrc, + TInetAddr& aDst ); + + void AcquireSAError( TIpsecSAData& aSAData, + TInt aError ); + + void UpdateSAL( TIpsecSAData& aSaData ); + + void AddSAL( TIpsecSAData& aSaData ); + + void DeleteIpsecSA( TIpsecSPI& aIpsecSpi ); + + void DeleteIpsecSA( TUint32 aSPI, + TInetAddr& aSrc, + TInetAddr& aDst, + TUint8 aProtocol ); + +// from base class MIkePluginSessionIf + + /** + * From MIkePluginSessionIf. + * Starts negotiation with a peer. + * @param aIkeData IKE policy data + * @param aInternalAddress Internal address (returned) + * @param aStatus Completion status (returned) + */ + void NegotiateWithHost( const CIkeData& aIkeData, + TVPNAddress& aInternalAddress, + TRequestStatus& aStatus ); + + /** + * From MIkePluginSessionIf. + * Cancels negotiate request. DeleteSession() method needs to be called + * after this method to delete session. + */ + void CancelNegotiateWithHost(); + + /** + * From MIkePluginSessionIf. + * Deletes session. IKE/IPSec SA:s are deleted. + * @param aSilentClose Specified if a silent close in question (Delete + * payloads not transmitted to peer) + * @param aStatus Completion status (returned) + */ + void DeleteSession( const TBool aSilentClose, + TRequestStatus& aStatus ); + + /** + * From MIkePluginSessionIf. + * Cancels deletion requests. IKE/IPSec SA:s are deleted. + */ + void CancelDeleteSession(); + + /** + * From MIkePluginSessionIf. + * Requests notification about error condition. + * @param aStatus Completion status (returned) + */ + void NotifyError( TRequestStatus& aStatus ); + + /** + * From MIkePluginSessionIf. + * Cancels error notification request. + */ + void CancelNotifyError(); + + /** + * From MIkePluginSessionIf. + * Requests notification about change of internal address. + * @param aInternalAddress Internal address (returned) + * @param aStatus KErrNone. Error condition needs to be indicated via + * NotifyError() method. (returned) + */ + virtual void NotifyInternalAddressChanged( TVPNAddress& aInternalAddress, + TRequestStatus& aStatus ); + + /** + * From MIkePluginSessionIf. + * Cancels internal address change notification request. + */ + void CancelNotifyInternalAddressChanged(); + +// from base class MIkev1ReceiverCallback + + /** + * From MIkev1ReceiverCallback. + * Notification about received IKE message. + * @param aIkeMsg IKE message + * @param aSrcAddr Source IP address/port + * @param aLocalPort Local port + */ + void IkeMsgReceivedL( const ThdrISAKMP& aIkeMsg, + const TInetAddr& aSrcAddr, + TInt aLocalPort ); + + /** + * From MIkev1ReceiverCallback. + * Notification about receive error. + * @param aStatus Error value + */ + void ReceiveError( TInt aError ); + + +// from base class MIkev1SenderCallback + + /** + * From MIkev1SenderCallback. + * Notification about completion sending. + * @param aStatus Completion status + */ + void SendUdpDataCompleted( TInt aStatus ); + +private: + + CIkev1PluginSession( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + MIkeDataInterface& aDataInterface, + CIkev1Plugin& aPlugin, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug ); + void ConstructL(); + + /** + * Handles received PFKEY message. + * @param aPfkeyMessage PFKEY message + */ + void DoPfkeyMessageReceivedL( const TPfkeyMessage& aPfkeyMessage ); + + /** + * Deletes IKE SAs. + * @param aSilentClose silent close + * @return Deactivation started or not. + */ + TBool DeleteSAsWithHost( TBool aSilentClose ); + + /** + * Requests sending of UDP data. + * @param aUdpData UDP data. Ownership transferred. + * @param aDestAddr Destination IP address/port + * @param aLocalPort Local port + * @param aDscp DSCP value + */ + void DoSendUdpDataL( HBufC8* aUdpData, + const TInetAddr& aDestAddr, + TInt aLocalPort, + TUint8 aDscp ); + /** + * Sends UDP data. + * @param aUdpData UDP data. Ownership transferred. + * @param aDestAddr Destination IP address/port + * @param aLocalPort Local port + * @param aDscp DSCP value + */ + void DoSendUdpData( HBufC8* aUdpData, + const TInetAddr& aDestAddr, + TInt aLocalPort, + TUint8 aDscp ); + + /** + * Handles starting of negotiation with a peer. + * @param aIkeData IKE policy data + */ + void DoNegotiateWithHostL( const CIkeData& aIkeData ); + + /** + * Handles fatal error. + * @param aError Error status + */ + void DoHandleError( TInt aError ); + + /** + * Handles completion of client's negotiate request. + * @param aStatus Status + */ + void DoCompleteNegotiateWithHost( TInt aStatus ); + + /** + * Handles completion of client's delete session request. + * @param aStatus Status + */ + void DoCompleteDeleteSession( TInt aStatus ); + + /** + * Handles completion of client's notify error request. + * @param aStatus Status + */ + void DoCompleteNotifyError( TInt aStatus ); + + /** + * Handles completion of client's notify internal address change request. + * @param aStatus Status + */ + void DoCompleteInternalAddressChanged( TInt aStatus ); + + /** + * Cancels data transfer. + */ + void DoCancelDataTransfer(); + + /** + * Empties send queue. + */ + void DoEmptySendQueue(); + +private: // data + + /** + * VPN IAP id. + * Own. + */ + TUint32 iVpnIapId; + + /** + * VPN NET id. + * Own. + */ + TUint32 iVpnNetId; + + /** + * VPN interface index. + * Own. + */ + TInt iVpnInterfaceIndex; + + /** + * IKE policy data. + * Own. + */ + CIkeData* iIkeData; + + /** + * IKEv1 negotiations. + * Own. + */ + CIkev1Negotiation* iFirstNegotiation; + + /** + * Dialog wait queue. Used by CIkeDialog class. + * Own. + */ + CIkev1Dialog* iDialogWaitQueue; + + /** + * SA id seed. + * Own. + */ + TUint32 iSAIdSeed; + + /** + * IKE message send queue. + * Own. + */ + RArray iSendQueue; + + /** + * IKEv1 SAs. + * Own. + */ + RPointerArray iIkev1SAs; + + /** + * Local IP address. + * Own. + */ + TInetAddr iLocalAddr; + + /** + * Receiver. + * Own. + */ + CIkev1Receiver* iReceiver; + + /** + * Sender. + * Own. + */ + CIkev1Sender* iSender; + + /** + * Internal address. + * Own. + */ + CInternalAddress* iInternalAddress; + + /** + * Error status. + * Own. + */ + TInt iErrorStatus; + + /** + * Client's negotiate requests status. + * Not own. + */ + TRequestStatus* iClientStatusNegotiate; + + /** + * Client's internal address variable for negotiate request. + * Not own. + */ + TVPNAddress* iClientIaNegotiate; + + /** + * Client's delete session requests status. + * Not own. + */ + TRequestStatus* iClientStatusDelete; + + /** + * Client's notify error requests status. + * Not own. + */ + TRequestStatus* iClientStatusNotifyError; + + /** + * Client's notify IA change requests status. + * Not own. + */ + TRequestStatus* iClientStatusNotifyIaChange; + + /** + * Client's internal address variable for notify request. + * Not own. + */ + TVPNAddress* iClientIaNotify; + + /** + * Data interface. + * Not own. + */ + MIkeDataInterface& iDataInterface; + + /** + * IKEv1 plugin. + * Not own. + */ + CIkev1Plugin& iPlugin; + + /** + * VPN PF key socket. + * Not own. + */ + CPFKeySocketIf& iPFKeySocketIf; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + }; + +#endif // C_IKEV1PLUGINSESSION_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1private.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1private.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,179 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This module contains the private vendor specific extension of IKE. +* All of the current private extensions are related to Nokia VPN gateway +* and shall be used ONLY when the EPOC IKE is acting as a Nokia VPN remote +* access client. +* The following private extension are implemented: +* +* 1) Internal Address payload usage +* Internal address payload is used to the deliver a secure network +* adderess and secure network DNS address(es) from VPN gateway to a client. +* The Internal address payloads are used in the last two IKE main mode +* messages as follows: +* +* Client (initiator) Gateway (responder) +* .. SA, KE ... ---> +* <--- ..SA, KE ... +* HDR*, INT_ADDR ---> +* <--- HDR*, INT_ADDR +* +* Client sends an INT_ADDR payload with PRI_INTERNAL_ADDRESS attribute +* Attribute value is 0.0.0.0. +* +* Gateway responds with an INT_ADDR payload with PRI_INTERNAL_ADDRESS +* attribute containing client internal address x.y.z.w +* Gateway INT_ADDR payload may also contain attributes PRI_INTERNAL_DNS and +* PRI_INTERNAL_WINS. PRI_INTERNAL_DNS contains a list of DNS IP addresses and +* PRI_INTERNAL_WINS a list of WINS IP addresses. +* +* +* 2) The NAT Traversal probing +* The expanded Vendor-Id payload usage for the NAT Traversal probing. +* The expanded Vendor-Id payloads contains the following information: +* +* Client (initiator) Gateway (responder) +* VID(hash, ip_addr, port) ---> +* <--- VID(hash, detected_ip_addr, +* detected_port) +* +* Client sends a expanded Vendor-Id payload containing the following information: +* hash = Nokia VPN vendor specific hash data (used to recognize peer) +* ip_addr = Client IKE own IP address +* port = Client IKE own port (=500) +* +* Gateway responds with expanded Vendor-Id payload containing the following information: +* hash = Nokia VPN vendor specific hash data (used to recognize peer) +* detected_ip_addr = Client IP address as detected in received IKE message +* IP header (=source IP address) +* detected_port = Client port as detected in received IKE message +* UDP header (=source port) +* +* Both client and gateway do the following examination +* if ( ip_addr != detected_ip_addr ) || ( port != detected_port ) +* then NAT Traversal shall be used IPSEC ESP traffic between +* the client and gateway +* +* Nokia VPN specific NAT Traversal means that IPSEC ESP traffic shall be +* capsulated with UDP header. +* The used UDP port for that purpose is 9872 +*/ + +#ifndef IKEV1PRIVATE_H +#define IKEV1PRIVATE_H + +#include +#include "ikemsgheader.h" + + +class TIkev1IsakmpStream; +class CIkeIPSocket; +class CIkeData; +class TVendorISAKMP; +class TINTNETISAKMP; +class CInternalAddress; +class TInetAddr; + +TInt ConstructVendorId(TBool aNATProbe, + TUint8 *aICOOKIE, + TUint8 *aRCOOKIE, + TInetAddr &aLocalAddr, + TVendorISAKMP *vendor_payload); +TInt BuildVendorIdHash(TUint8 *aICOOKIE, + TUint8 *aRCOOKIE, + TUint8 *hash_data); +TBool ProcessVendorId(TBool *aFamiliarPeer, + TUint8 *aICOOKIE, + TUint8 *aRCOOKIE, + TInetAddr &aLocalAddr, + TVendorISAKMP *aVendorPayload); +void BuildDPDVendorId(TIkev1IsakmpStream &aMsg); +TBool CheckDPDVendorId(const TVendorISAKMP *aVendorPayload); +CInternalAddress* ProcessIntNetL(TINTNETISAKMP *aIntNetpayload); + +TBool InsertVPNInterfaceL(CInternalAddress *aInternalAddr, CIkeIPSocket *aSocket, TUint32 *aIfNbr, RFs *aFS); +TBool RemoveVPNInterfaceL(CInternalAddress *aInternalAddr, CIkeIPSocket *aSocket, TUint32 *aIfNbr, RFs *aFS); +TBool AddVPNRoute(CInternalAddress *aInternalAddr, CIkeIPSocket *aSocket, + TInetAddr &aDstAddr, TInetAddr &aDstMask); +TInt CheckCredentials(CIkeData *aHostData); +/*--------------------------------------------------------------------------- + * + * Expanded Vendor Id payload option VENDOR_OPTION_NAT_TRAVERSAL handling: + * 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! sin_lth ! sin_family ! sin_port ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! sin_addr ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! ! + * . Zero * 2(?) . + * ! ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * + *---------------------------------------------------------------------------*/ +#define SIN_LTH 16 // VENDOR_OPTION_NAT_TRAVERSAL data part length +#define SIN_FAMILY 2 // = IPv4 Address + + +class TNATTOption + { +public: + inline void InitOption() { Mem::FillZ(&u.iData8[0], SIN_LTH); + u.iData8[0] = SIN_LTH; u.iData8[1] = SIN_FAMILY;} + inline void SetPort(TUint16 aPort) { PUT16(&u.iData8[2], aPort);} + inline void SetAddress(TUint32 aAddr) { PUT32(&u.iData8[4], aAddr);} + inline TUint16 GetPort() {return (TUint16)GET16(&u.iData8[2]);} + inline TUint32 GetAddress() {return (TUint32)GET32(&u.iData8[4]);} +private: + union + { + TUint32 iData32[4]; + TUint16 iData16[8]; + TUint8 iData8[16]; + } u; + }; + +/*--------------------------------------------------------------------------- + * + * Expanded Vendor Id payload option VENDOR_OPTION_VERSION handling: + * 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! MAJOR VERSION ! MINOR VERSION ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + *---------------------------------------------------------------------------*/ +#define VERSION_LTH 4 // VENDOR_OPTION_VERSION data part length +#define MAJOR_VERSION 3 // ???????????!!!!!!!!!!!!!!!!???????????? +#define MINOR_VERSION 3 // ???????????!!!!!!!!!!!!!!!!???????????? + +class TVersionOption + { +public: + inline void SetVersion(TUint16 aMajor, + TUint16 aMinor) { PUT16(&u.iData8[0], aMajor); + PUT16(&u.iData8[2], aMinor);} +private: + union + { + TUint32 iData32[1]; + TUint16 iData16[2]; + TUint8 iData8[4]; + } u; + }; + +#endif // IKEV1PRIVATE_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1receiver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1receiver.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,150 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Receiver of UDP datagrams +* +*/ + + +#ifndef C_IKEV1RECEIVER_H +#define C_IKEV1RECEIVER_H + +#include +#include + +// FORWARD DECLARATIONS +class MIkeDataInterface; +class ThdrISAKMP; + +/** + * IKEv1 receiver callback interface. + * Callback interface which is used by CIkev1Receiver object to notify + * about received IKE message. + * + * @lib internal (ikev1lib.lib) + */ +NONSHARABLE_CLASS(MIkev1ReceiverCallback) + { +public: + /** + * Notifies about received IKE message. + * @param aIkeMsg IKE message + * @param aSrcAddr Source IP address/port + * @param aLocalPort Local port + */ + virtual void IkeMsgReceivedL( const ThdrISAKMP& aIkeMsg, + const TInetAddr& aSrcAddr, + TInt aLocalPort ) = 0; + + /** + * Notifies about receive error. + * @param aStatus Error value + */ + virtual void ReceiveError( TInt aError ) = 0; + }; + +/** + * IKEv1 receiver. + * Active object provides functionality for receiving UDP datagrams. + * + * @lib internal (ikev1lib.lib) + */ +NONSHARABLE_CLASS(CIkev1Receiver) : public CActive + { +public: + /** + * Two-phased constructor. + * @param aDataInterface IKE data interface + * @param aCallback Callback interface + */ + static CIkev1Receiver* NewL( MIkeDataInterface& aDataInterface, + MIkev1ReceiverCallback& aCallback ); + + /** + * Destructor. + */ + ~CIkev1Receiver(); + + /** + * Starts receiving. + */ + void StartReceive(); + +private: + + CIkev1Receiver( MIkeDataInterface& aDataInterface, + MIkev1ReceiverCallback& aCallback ); + + void ConstructL(); + + /** + * Receives UDP data. + */ + void DoReceive(); + +// from base class CActive + + /** + * From CActive + * Handles completion of receive. + */ + void RunL(); + + /** + * From CActive + * Handles cancellation of receive. + */ + void DoCancel(); + + /** + * From CActive + * Handles a leave occurring in RunL(). + * @param aError The leave code + * @return KErrNone + */ + TInt RunError( TInt aError ); + +private: // data + + /** + * UDP data. + * Own. + */ + HBufC8* iUdpData; + + /** + * Source IP address/port. + * Own. + */ + TInetAddr iSrcAddr; + + /** + * Local port. + * Own. + */ + TInt iLocalPort; + + /** + * IKE data interface. + * Not own. + */ + MIkeDataInterface& iDataInterface; + + /** + * Callback interface. + * Not own. + */ + MIkev1ReceiverCallback& iCallback; + }; + +#endif // C_IKEV1RECEIVER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1sender.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1sender.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,130 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Sender of UDP datagrams +* +*/ + + +#ifndef C_IKEV1SENDER_H +#define C_IKEV1SENDER_H + +#include + +// FORWARD DECLARATIONS +class MIkeDataInterface; +class MIkeDebug; +class TInetAddr; + +/** + * IKEv1 sender callback interface. + * Callback interface which is used by CIkev1Sender object to notify + * about completion of sending. + * + * @lib internal (ikev1lib.lib) + */ +NONSHARABLE_CLASS(MIkev1SenderCallback) + { +public: + /** + * Notifies about completion of sending. + * @param aStatus Completion status + */ + virtual void SendUdpDataCompleted( TInt aStatus ) = 0; + + }; + +/** + * IKEv1 sender. + * Active object provides functionality for sending UDP datagrams. + * + * @lib internal (ikev1lib.lib) + */ +NONSHARABLE_CLASS(CIkev1Sender) : public CActive + { +public: + /** + * Two-phased constructor. + * @param aDataInterface IKE data interface + * @param aCallback Callback interface + * @param aDebug Debug trace interface + */ + static CIkev1Sender* NewL( MIkeDataInterface& aDataInterface, + MIkev1SenderCallback& aCallback, + MIkeDebug& aDebug ); + + /** + * Destructor. + */ + ~CIkev1Sender(); + + /** + * Sends UDP data. + * @param aUdpData UDP data. Ownership transferred. + * @param aDestAddr Destination IP address/port + * @param aLocalPort Local port + * @param aDscp DSCP value + */ + void SendUdpData( HBufC8* aUdpData, + const TInetAddr& aDestAddr, + TInt aLocalPort, + TUint8 aDscp ); + +private: + + CIkev1Sender( MIkeDataInterface& aDataInterface, + MIkev1SenderCallback& aCallback, + MIkeDebug& aDebug ); + +// from base class CActive + + /** + * From CActive + * Handles completion of asynchronous sending. + */ + void RunL(); + + /** + * From CActive + * Handles cancellation of asynchronous sending. + */ + void DoCancel(); + +private: // data + + /** + * UDP data. + * Own. + */ + HBufC8* iUdpData; + + /** + * IKE data interface. + * Not own. + */ + MIkeDataInterface& iDataInterface; + + /** + * Callback interface. + * Not own. + */ + MIkev1SenderCallback& iCallback; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + }; + +#endif // C_IKEV1SENDER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1timeout.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1timeout.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Header for timer class used by IKEv1 +* +*/ + +#ifndef C_IKEV1TIMEOUT_H +#define C_IKEV1TIMEOUT_H + +#include + +class CIkev1Negotiation; + +NONSHARABLE_CLASS(CIkev1Timeout) : public CTimer + { +public: + static CIkev1Timeout* NewL(CIkev1Negotiation& aNegotiation); + + //destructor + ~CIkev1Timeout(); + + void IssueRequest(TTimeIntervalMicroSeconds32 anInterval); +protected: + + //Cancel Packet Sending + void RunL(); + +private: + CIkev1Timeout(CIkev1Negotiation& aNegotiation); + + CIkev1Negotiation& iNegotiation; + }; + + +#endif // C_IKEV1TIMEOUT_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/inc/ikev1trans.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/inc/ikev1trans.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,155 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE transaction exchange implementation. +* +*/ + + +#ifndef IKEV1TRANS_H +#define IKEV1TRANS_H + +#include "ikev1dialog.h" +#include "ikev1payloads.h" + +/*--------------------------------------------------------------------------- + * + * Transaction exchange return codes (returned by ExecuteL() method) + * + *---------------------------------------------------------------------------*/ +#define TRANSACTION_SUCCESS 0 +#define TRANSACTION_CONTINUE 0x1 +#define TRANSACTION_IGNORE 0x2 +#define TRANSACTION_FAILED 0x4 + +#define IV_LTH 20 +/**-------------------------------------------------------------------------- + * + * Structure TTransExchange + * Contains parameter data related one ISAKMP Transaction exchange + * + *--------------------------------------------------------------------------*/ +struct TTransExchange +{ + TUint32 iMessageId; + TUint16 iIdentifier; + TUint16 iXauthType; + TInt iRole; + TBuf8 iIV; + TTransExchange() + { + iMessageId = 0; + iIdentifier = 0; + iXauthType = 0; + iRole = 0; + }; +}; + + +class CIkev1Negotiation; +class ThdrISAKMP; +class CAuthDialogInfo; +class CInternalAddress; +class TIkev1IsakmpStream; +class MIkeDebug; +class TInetAddr; + +/**-------------------------------------------------------------------------- + * + * CTransNegotiation class + * Handles ISAKMP transaction exchange messages + * Both the ISAKMP Configuration Method and + * Extended Authentication within IKE (XAUTH) + * has been implemented using ISAKMP transaction exchange messages. + * This class handles both the transaction exchange message handling and + * config mode/XAUTH protocol processing. + * + *--------------------------------------------------------------------------*/ +NONSHARABLE_CLASS(CTransNegotiation) : public CArrayFixFlat, public MIkeDialogComplete +{ +public: + ~CTransNegotiation(); + static CTransNegotiation* NewL( TBool aUseXauth, + TBool aUseCfgMode, + CIkev1PluginSession* aPluginSession, + CIkev1Negotiation* aNegotiation, + MIkeDebug& aDebug ); + TInt ExecuteL( const ThdrISAKMP& aHdr, + const TInetAddr& aSrcAddr, + TInt aLocalPort ); + TInt ProcessUserResponseL(CAuthDialogInfo *aDialogInfo ); + TInt TransactionFailedL(const TNotificationISAKMP *aNotifPayload); + TBool GetIV(TUint32 aMsgId, TDes8& aIV); + TBool SetIV(TUint32 aMsgId, TDes8& aIV); + CInternalAddress* GetInternalAddr() + { + CInternalAddress* ia = iInternalAddr; + iInternalAddr = NULL; + return ia; + } + static TUint16 GetAuthMethod(TUint16 aAuthMethod, TBool aXauthUsed, TInt aRole); + static void BuildXauthVendorId(TIkev1IsakmpStream &aMsg); + + TInt DialogCompleteL(CIkev1Dialog* aDialog, TAny* aUserInfo, HBufC8* aUsername, + HBufC8* aSecret, HBufC8* aDomain); + TInt BuildConfigRequestL(); + +private: + TTransExchange* FindExchange(TUint32 aMsgId); + TTransExchange* AddExchangeL(TUint32 aMsgId, TUint8 aRole); + TUint16 GetIdentifier() + { + iIdentifierBase --; + if ( (iIdentifierBase & 0xffff) == 0 ) + iIdentifierBase --; + return (TUint16)iIdentifierBase; + } + TInt TransactionExchangeL(const ThdrISAKMP &aHdr); + TInt ProcessAttributesL(const TAttributeISAKMP *aAttr); + TInt ProcessCfgModeAttrsL(TDataISAKMP* aAttr, TInt aLth); + TInt ProcessXauthRequestL(TDataISAKMP* aAttr, TInt aLth); + TInt ProcessXauthStatusL(TDataISAKMP* aAttr, TInt aLth); + TInt CheckTransactionStatusL(TInt aStatus); + void AddAttributeData(TDes8& aAttrBfr, TInt aType, TInt aLth, TUint8* aData); + void BuildAndSendMessageL(TDesC8& aAttrBfr, TUint8 aMsgType); + CTransNegotiation( TInt aGranularity, + TBool aUseXauth, + TBool aUseCfgMode, + CIkev1PluginSession* aPluginSession, + CIkev1Negotiation* aNegotiation, + MIkeDebug& aDebug ); + void ConstructL(); + +private: + CIkev1PluginSession* iPluginSession; + CIkev1Negotiation* iNegotiation; + CInternalAddress* iInternalAddr; + TTransExchange* iCurrExchange; + CIkev1Dialog* iDialog; + CAuthDialogInfo* iDialogInfo; + HBufC8* iUserName; // Saved for User name caching + + TBool iUseXauth; + TBool iUseCfgMode; + TUint32 iIdentifierBase; + TUint32 iRequestFlags; + TBool iXauthCompleted; + TBool iCfgModeCompleted; + TBool iUseOlderPIXXauth; // use draft-ietf-ipsec-isakmp-xauth-04.txt + + TLastIKEMsg iLastTransMsgInfo; + MIkeDebug& iDebug; +}; + + +#endif // IKEV1TRANS_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/rom/ikev1lib.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/rom/ikev1lib.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Image description file for project +* IKEv1 Protocol Plug-in +* +*/ + + + +#ifndef __IKEV1LIB_IBY__ +#define __IKEV1LIB_IBY__ + +#ifdef SYMBIAN_EXCLUDE_IPSEC + +REM Feature IKEV1LIB not included in this rom + +#else + +file=ABI_DIR\BUILD_DIR\ikev1lib.dll SHARED_LIB_DIR\ikev1lib.dll + +#endif // SYMBIAN_EXCLUDE_IPSEC + +#endif // __IKEV1LIB_IBY__ + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1crack.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1crack.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,510 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv1 Crack authentication +* +*/ + + +#include "ikev1crack.h" +#include "ikedebug.h" +#include "ikev1pluginsession.h" +#include "ikev1timeout.h" +#include "ikev1negotiation.h" +#include "ikev1payload.h" +#include "ikev1isakmpstream.h" +#include "ikepolparser.h" + + +// +// Class that implements IKE CRACK authentication method +// + +CIKECRACKNegotiation::CIKECRACKNegotiation( MIkeDebug& aDebug ) + : iState( 0 ), + iDebug( aDebug ) + { + } + +CIKECRACKNegotiation::~CIKECRACKNegotiation() +{ +/*------------------------------------------------------------------- + * + * Delete pending dialog - and dialog info objects + * + *-------------------------------------------------------------------*/ +#ifdef _DEBUG + if ( iNegotiation ) DEBUG_LOG(_L("CRACK object deleted")); +#endif // _DEBUG + + delete iDialog; + delete iDialogInfo; + delete iUserName; + delete iDomain; +} + + +TInt CIKECRACKNegotiation::ConstructL(TInt aLAMType, CIkev1Negotiation *aNegotiation, const TDesC &aDomain) +{ +/*------------------------------------------------------------------------ + * + * This method initializes actions to get authencation information from user. + * The authentication information is requested from user with LAM type + * specific dialog. + * + *------------------------------------------------------------------------*/ + if ( aLAMType != CRACK_PASSWORD || !aNegotiation ) + { +#ifdef _DEBUG + if ( aNegotiation ) + DEBUG_LOG(_L("CRACK object construction failed, unsupported LAM type")); +#endif // _DEBUG + return CRACK_FAILED; + } + iNegotiation = aNegotiation; + iPluginSession = aNegotiation->iPluginSession; + iLAMType = aLAMType; + if ( aDomain.Length() > 0 ) + { + // + // Allocate buffer for domain name attribute + // (to convey Group Name information) + // + iDomain = HBufC8::NewL(aDomain.Length()); + iDomain->Des().Copy(aDomain); + DEBUG_LOG(_L("CRACK Domain attribute saved")); + } + + DEBUG_LOG(_L("CRACK authentication started")); + + return GetDataL(NULL); /* No challenge data */ +} + + +TInt CIKECRACKNegotiation::ExecuteCRACKMsgL(const ThdrISAKMP &aHdr) +{ +/*--------------------------------------------------------------------------- + * + * IKE message received during CRACK authentication phase: + * <--- HDRx*, CHRE or <--- HDRx*, NOTIFICATION + * Process CHRE/Notification payload in IKE message + * + *--------------------------------------------------------------------------*/ + if ( ( iState & WAITING_PEER_RSP ) == 0 ) { + /*-------------------------------------------------------- + * Not waiting a response from gateway, ignore packet + *--------------------------------------------------------*/ + return CRACK_IGNORE_MSG; + } + iState &= ~WAITING_PEER_RSP; + + CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *iNegotiation, iDebug); + if (!payload) + { + return CRACK_FAILED; + } + CleanupStack::PushL(payload); + TInt status; + + if ( payload->iChre ) + { + TInt i = 0; + while ( i < payload->iNotifs->Count() ) + { + /*---------------------------------------------------------------------- + * + * A Notification payload received in IKE main/aggressive/information + * exchange. If this is not a INITIAL-CONTACT notification it is + * interpreted as a CRACK authentication failure indicated by the gateway. + * + *----------------------------------------------------------------------*/ + if ( !iNegotiation->ProcessNotificationL(payload->iNotifs->At(i)) ) { + CleanupStack::PopAndDestroy(); //payload + return CrackAuthenticationFailedL(payload->iNotifs->At(i)); + } + i ++; + } + + if ( payload->iIaddr ) { + /*---------------------------------------------------------------------- + * + * An Internal Address payload received in IKE main/aggressive exchange. + * + *----------------------------------------------------------------------*/ + iNegotiation->ProcessIntAddrL(payload->iIaddr); + } + /*---------------------------------------------------------------------- + * + * Process attributes in CHRE payload + * + *----------------------------------------------------------------------*/ + status = ProcessCHREAttibutesL(payload->iChre); + } + else { + status = CRACK_CONTINUE; + DEBUG_LOG(_L("No CHRE payload in IKE CRACK message")); + } + + CleanupStack::PopAndDestroy(); //payload + return status; + +} + +TInt CIKECRACKNegotiation::ProcessUserResponseL(CAuthDialogInfo *aDialogInfo ) +{ +/*--------------------------------------------------------------------------- + * + * A response received from client user (through asynchronous dialog) + * Build an IKE message with an appropriate CHRE payload attributes + * and send message it to gateway. + * + *-------------------------------------------------------------------------*/ + if ( iState & WAITING_USER_RSP ) + { + iState &= ~(WAITING_USER_RSP + SECURID_NEXT_PIN_MODE); + delete iDialog; /* delete dialog object */ + iDialog = NULL; + + TUint16 attr1 = 0; + TUint16 attr2 = 0; + TUint16 attr3 = 0; + HBufC8* bfr1 = NULL; + HBufC8* bfr2 = NULL; + HBufC8* bfr3 = NULL; + + /*-------------------------------------------------------- + * + * Store attributes according to LAM type + * + *--------------------------------------------------------*/ + switch ( iLAMType ) + { + case CRACK_PASSWORD: + /*-------------------------------------------------- + * Possible attributes: User name, Secret, Domain + *-------------------------------------------------*/ + attr1 = CRACK_T_USERNAME; + bfr1 = aDialogInfo->iUsername; + attr2 = CRACK_T_SECRET; + bfr2 = aDialogInfo->iSecret; + bfr3 = iDomain; + if ( bfr3 ) + attr3 = CRACK_T_DOMAIN; + break; + + default: + break; + } + + SendCredentialsL(attr1, attr2, attr3, bfr1, bfr2, bfr3); + } + + delete aDialogInfo; /* release dialog info object */ + iDialogInfo = NULL; /* reset dialog info pointer */ + + return CRACK_CONTINUE; +} + +TInt CIKECRACKNegotiation::GetDataL(HBufC8* aChallenge) +{ + if ( iLAMType == CRACK_PASSWORD && + iNegotiation->iHostData->iCRACKLAMUserName && + iNegotiation->iHostData->iCRACKLAMPassword) + { + return GetUNPWDFromPolicyL(); + } + else + { + return GetDatafromUserL(aChallenge); + } +} + +TInt CIKECRACKNegotiation::GetDatafromUserL(HBufC8* /*aChallenge*/) +{ + TInt status = CRACK_CONTINUE; + /*--------------------------------------------------------------- + * + * Get CRACK authentication information from user according to + * current LAM type + * + *---------------------------------------------------------------*/ + iDialog = CIkev1Dialog::NewL( iPluginSession, iPluginSession->DialogAnchor(), iDebug ); + iDialogInfo = new(ELeave) CAuthDialogInfo(iPluginSession, DIALOG_INFO_ID, iNegotiation->SAId(), 0); + iNegotiation->iTimer->Cancel(); //Cancel previous timer because reply received & processed + DEBUG_LOG(_L("Timer Cancelled!")); + iNegotiation->iRetryNum = 0; + + switch ( iLAMType ) + { + case CRACK_PASSWORD: + /*-------------------------------------------------- + * Request User name and password (domain) from user + *-------------------------------------------------*/ + iDialog->GetAsyncUNPWDialogL(iDialogInfo, (MIkeDialogComplete*)this); + break; + + default: + status = CRACK_FAILED; + break; + } + + iState |= WAITING_USER_RSP + SHOW_ERROR_DIALOG; + + return status; +} + +TInt CIKECRACKNegotiation::GetUNPWDFromPolicyL() +{ + ASSERT(iLAMType == CRACK_PASSWORD); + + iNegotiation->iTimer->Cancel(); //Cancel previous timer because reply received & processed + DEBUG_LOG(_L("Timer Cancelled!")); + iNegotiation->iRetryNum = 0; + + /*-------------------------------------------------------- + * + * Store attributes: User name, Secret, Domain + * + *--------------------------------------------------------*/ + + TUint16 attr1 = CRACK_T_USERNAME; + HBufC8* bfr1 = iNegotiation->iHostData->iCRACKLAMUserName->GetAsciiDataL(); + CleanupStack::PushL(bfr1); + TUint16 attr2 = CRACK_T_SECRET; + HBufC8* bfr2 = iNegotiation->iHostData->iCRACKLAMPassword->GetAsciiDataL(); + CleanupStack::PushL(bfr2); + HBufC8* bfr3 = iDomain; + TUint16 attr3 = 0; + if ( bfr3 ) + { + attr3 = CRACK_T_DOMAIN; + } + + SendCredentialsL(attr1, attr2, attr3, bfr1, bfr2, bfr3); + + CleanupStack::PopAndDestroy(2); // bfr1, bfr2 + + return CRACK_CONTINUE; +} + +void CIKECRACKNegotiation::SendCredentialsL(TUint16 aAttr1, TUint16 aAttr2, TUint16 aAttr3, + HBufC8* aBfr1, HBufC8* aBfr2, HBufC8* aBfr3) +{ + TIkev1IsakmpStream* msg = iNegotiation->SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) ); + msg->IsakmpInit(iNegotiation); + msg->IsakmpOwnIdentL(); /* Dummy ID for Crypto Cluster */ + msg->IsakmpChre((TUint16)iLAMType, aAttr1, aBfr1, aAttr2, aBfr2, aAttr3, aBfr3); + + if ( iNegotiation->iFamiliarPeer && iNegotiation->iHostData->iUseInternalAddr ) + { + // + // Request Internal address from gateway + // + msg->IsakmpIntnet(0); /* null IPV4 address as parameter */ + } + + if ( iNegotiation->iHostData->iInitialContact ) + { + // + // Initial contact notification added as the last payload into IKE message + // + if (!iPluginSession->FindIkev1SADataWithAddr(iNegotiation->iRemoteAddr)) //Only sent if no ISAKMP SA established + { + DEBUG_LOG(_L("Constructing INITIAL-CONTACT")); + msg->IsakmpNotification(DOI_INITIAL_CONTACT, PROTO_ISAKMP); + } + } + + iNegotiation->SendL(*msg); + + // + // Take a copy of user name buffer in dialog info. This user name + // is cached into user name file if current CRACK negotiation is + // succeeded + // + if ( aBfr1 ) + { + delete iUserName; // Delete old user name buffer for sure + iUserName = NULL; + iUserName = HBufC8::New(aBfr1->Length() + 16); // 16 bytes space for padding + if ( iUserName ) + { + iUserName->Des().Copy(aBfr1->Des()); + } + } + + iState |= WAITING_PEER_RSP; + iMsgCount++; +} + +TInt CIKECRACKNegotiation::ProcessCHREAttibutesL(const TCHREISAKMP *aCHRE) +{ +/*--------------------------------------------------------------------------- + * + * CHRE payload received from gateway. Process attributes in payload + * according to current LAM type. + * Assure first that LAM type in payload corresponds configured LAM type + * in CRACK object + * + *--------------------------------------------------------------------------*/ + TInt length = (TInt)aCHRE->GetLength(); + if ( STATIC_CAST(TUint, length) < sizeof(TCHREISAKMP) ) { + return CRACK_FAILED; + } + + length -= sizeof(TCHREISAKMP); /* Attribute data lengt in payload */ + if ( (aCHRE->GetCHREReserved() != 0) || (aCHRE->GetLAMtype() != iLAMType )) { + return CRACK_FAILED; + } + + TDataISAKMP *attr = aCHRE->CHREAttrib(); + HBufC8 *challenge = NULL; + TInt status = CRACK_CONTINUE; + TBool get_user_data = EFalse; + TUint16 fin; + + while ( length > 0 ) { + + length = length - attr->Size(); + if ( length < 0 ) { + DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (Length mismatch in the attibutes)")); + return CRACK_FAILED; + } + switch ( attr->Type() ) { + + case CRACK_T_MESSAGE: + if ( attr->IsBasic() ) { /* MUST be variable */ + return CRACK_FAILED; + } + break; + + case CRACK_T_FIN: + if ( !attr->IsBasic() ) { /* MUST be basic */ + return CRACK_FAILED; + } + fin = attr->Value(); + if ( fin == CRACK_FIN_SUCCESS ) { + DEBUG_LOG(_L("CRACK authentication OK")); + status = CRACK_SUCCESS; + if ( iUserName ) { + // + // Cache user name into user name file + // + CIkev1Dialog* Dialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); + CleanupStack::PushL(Dialog); + TInt err(KErrNone); + TRAP(err, Dialog->StoreUserNameL(iUserName->Des())); +#ifdef _DEBUG + if (err == KErrNone) + DEBUG_LOG(_L("User Name caching succeeded")); + DEBUG_LOG(_L("User Name caching failed")); +#endif + CleanupStack::PopAndDestroy(); + } + } + else { + if ( fin == CRACK_FIN_MORE ) { + iState |= SECURID_NEXT_PIN_MODE; + DEBUG_LOG(_L("CRACK SecurID Next pin mode entered")); + get_user_data = ETrue; /* SecurID "Next code2 */ + } + else { + status = CRACK_FAILED; /* Illegal FIN value */ + } + } + break; + + default: + DEBUG_LOG(_L("ATTRIBUTES_NOT_SUPPORTED (Invalid attribute in CHRE)")); + return CRACK_FAILED; + } + + attr = attr->Next(); + } + + if ( get_user_data ) { + /*--------------------------------------------------- + * Get information from user + *---------------------------------------------------*/ + status = GetDatafromUserL(challenge); + if ( challenge ) + CleanupStack::PopAndDestroy(); /* delete challenge */ + } + + return status; + +} + + +TInt CIKECRACKNegotiation::CrackAuthenticationFailedL(const TNotificationISAKMP *aNotifPayload) +{ + (void)aNotifPayload; +/*--------------------------------------------------------------------------- + * + * The gateway has sent a Notification payload which indicates that CRACK + * authentication is failed. + * Display proper error dialog and return CRACK_FAILED status + * + *--------------------------------------------------------------------------*/ + iNegotiation->iTimer->Cancel(); //Cancel timer because authentication failed + DEBUG_LOG(_L("CRACK authentication failed!")); + + if ( (iState & (CRACK_AUTHENTICATED + WAITING_USER_RSP + SHOW_ERROR_DIALOG)) == + SHOW_ERROR_DIALOG ) { + // Dialog object shall be delete in Dialog->RunL when dialog completed + CIkev1Dialog* Dialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); + Dialog->ShowErrorDialogL(TVpnNoteDialog::EKmdAuthenticationFailed, NULL, NULL); + iState &= ~SHOW_ERROR_DIALOG; + } + + return CRACK_FAILED; + +} + +// +// The implementation for class MIkeDialogComplete virtual function +// +TInt CIKECRACKNegotiation::DialogCompleteL(CIkev1Dialog* /*aDialog*/, TAny* aUserInfo, + HBufC8* aUsername, HBufC8* aSecret, HBufC8* aDomain) +{ +/*--------------------------------------------------------------------------- + * + * A response received from client user (through asynchronous dialog) + * This method is introduced as a TUserCallback for CGetIKEPassword dialog + * object is created. When the dialog is completed this callback function + * is called to deliver Credentials data for CHRE payload attributes. + * Store credential buffers to CAuthDialogInfo object and call engine + * entry + * + *-------------------------------------------------------------------------*/ + TUint32 obj_id = 1; + CAuthDialogInfo* info = (CAuthDialogInfo*)aUserInfo; + DEBUG_LOG1(_L("CIKECRACKNegotiation::DialogCompleteL(), aUserInfo = %x"), aUserInfo); + + if ( info ) + { + obj_id = info->GetObjId(); + DEBUG_LOG1(_L("Preparing to call AuthDialogCompletedL(), ObjId = %x"), obj_id); + if ( obj_id == DIALOG_INFO_ID ) + { + info->iUsername = aUsername; + info->iSecret = aSecret; + info->iDomain = aDomain; + obj_id = info->PluginSession()->AuthDialogCompletedL(info); + } + } + + return obj_id; +} + + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1crypto.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1crypto.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,369 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Crypto Layer to use and change any cryptolibrary easily. +* Contains all the cryptographic functions used in IKEv1. +* +*/ + + + +#include "ikev1crypto.h" +#include "ikemsgheader.h" +#include "dhparameters.h" +#include "utlcrypto.h" + +CIkeKeys* CIkeKeys::NewL(const TDesC8& aN, const TDesC8& aG) +{ + CIkeKeys *keys = new (ELeave) CIkeKeys(); + keys->iDHKey = TUtlCrypto::MakeDiffieHellmanL(aN, aG); + keys->iModuluslength = aN.Length(); + return keys; +} + +CIkeKeys::~CIkeKeys() +{ + delete iDHKey; +} + + +HBufC8* CIkeKeys::GetPubKey() +{ + HBufC8* DHPublicKey = (HBufC8*)iPubKey; + iPubKey = NULL; // Exclusive ownership of iPubKey buffer is returned to caller + return DHPublicKey; +} + +void CIkeKeys::XValueL() +{ + iPubKey = iDHKey->GenerateXL(); +} + + +const HBufC8* CIkeKeys::KValueL(const TDesC8& aY) const +{ + return iDHKey->CompleteKL(aY); +} + + + + +//Generates a group of parameters depending on the group. +CIkeKeys *CreateDHKeyL(TUint aGroupDesc) +{ + TPtrC8 prime_ptr(NULL, 0); + TPtrC8 gen_ptr(NULL, 0); + + switch (aGroupDesc) + { + case MODP_768: + prime_ptr.Set((TUint8 *)&MODP_768_PRIME[0], MODP_768_PRIME_LENGTH); + gen_ptr.Set((TUint8 *)&MODP_768_GENERATOR[0], MODP_768_GENERATOR_LENGTH); + break; + case MODP_1024: + prime_ptr.Set((TUint8 *)&MODP_1024_PRIME[0], MODP_1024_PRIME_LENGTH); + gen_ptr.Set((TUint8 *)&MODP_1024_GENERATOR[0], MODP_1024_GENERATOR_LENGTH); + break; + case MODP_1536: + prime_ptr.Set((TUint8 *)&MODP_1536_PRIME[0], MODP_1536_PRIME_LENGTH); + gen_ptr.Set((TUint8 *)&MODP_1536_GENERATOR[0], MODP_1536_GENERATOR_LENGTH); + break; + case MODP_2048: + prime_ptr.Set((TUint8 *)&MODP_2048_PRIME[0], MODP_2048_PRIME_LENGTH); + gen_ptr.Set((TUint8 *)&MODP_2048_GENERATOR[0], MODP_2048_GENERATOR_LENGTH); + break; + case EC2N_155: + case EC2N_185: + return NULL; + default: //Cannot happen because checked before!!! + return NULL; + } + + CIkeKeys *arg = CIkeKeys::NewL(prime_ptr, gen_ptr); + + return arg; +} + +CIkeKeys *GeneratePubPrivKeysL(TUint aGroupDesc) +{ + CIkeKeys *dh_key = CreateDHKeyL(aGroupDesc); + if (!dh_key) + return NULL; + dh_key->XValueL(); //Initializes the public and private keys. + + return dh_key; + +} + +HBufC8* ComputeAgreedKeyL(TUint /*aGroupDesc*/, const TDesC8 &aPeerPublicKey, CIkeKeys *aOwnKeys) +{ + if(!aOwnKeys) + return NULL; + + return (HBufC8*)aOwnKeys->KValueL(aPeerPublicKey); +} + +void DecryptL(const TUint8* aInputPayload, TUint8* aOutputPayload, TUint32 aLength, TDes8& aIV, TDesC8& aKey, TUint16 aEncrAlg) +{ + TUtlCrypto::TUtlSymmetricCipherId CipherId = TUtlCrypto::EUtlSymmetricCipherAesCbc; // Defaults + TInt IVLth = AESCBC_IV_LEN; + + if ( aEncrAlg == DES3_CBC ) + { + CipherId = TUtlCrypto::EUtlSymmetricCipher3DesCbc; + IVLth = DESCBC_IV_LEN; + } + else if ( aEncrAlg == DES_CBC) + { + CipherId = TUtlCrypto::EUtlSymmetricCipherDesCbc; + IVLth = DESCBC_IV_LEN; + } + // + // Construct cipher object for symmetric decrypt operation + // + TPtrC8 iv_ptr(aIV.Ptr(), IVLth); + TPtrC8 ciphertext(aInputPayload, aLength); + TPtr8 plaintext(aOutputPayload, aLength); + + CUtlSymmetricCipher* UtlCipher = TUtlCrypto::MakeSymmetricDecryptorL(CipherId, + aKey, + iv_ptr); + + CleanupStack::PushL(UtlCipher); + UtlCipher->ProcessFinalL(ciphertext, plaintext); + CleanupStack::PopAndDestroy(); + aIV.Copy(&aInputPayload[aLength - IVLth], IVLth); //Next IV (last 8 bytes of ciphertext) + +} + +TBool EncryptL(TDes8& aInputPayload, TDes8& aOutputPayload, TDes8& aIV, TDesC8& aKey, TUint16 aEncrAlg) +{ + TUtlCrypto::TUtlSymmetricCipherId CipherId = TUtlCrypto::EUtlSymmetricCipherAesCbc; // Defaults + TInt CbLth = AESCBC_IV_LEN; + + if ( aEncrAlg == DES3_CBC ) + { + CipherId = TUtlCrypto::EUtlSymmetricCipher3DesCbc; + CbLth = DESCBC_IV_LEN; + } + else if ( aEncrAlg == DES_CBC) + { + CipherId = TUtlCrypto::EUtlSymmetricCipherDesCbc; + CbLth = DESCBC_IV_LEN; + } + TPtrC8 iv_ptr(aIV.Ptr(), CbLth); + // + // Add padding, if needed + // + TUint padding_bytes = (aInputPayload.Length() - ISAKMP_HDR_SIZE) % CbLth; + if (padding_bytes != 0) //Padd with 0 at the end if needed + { + TChar c(0); + aInputPayload.AppendFill(c,CbLth-padding_bytes); //Append at the end + } + // + // ISAKMP fixed header not encrypted + // + TPtrC8 plaintext(aInputPayload.Ptr() + ISAKMP_HDR_SIZE, aInputPayload.Length() - ISAKMP_HDR_SIZE);//skip hdr + aOutputPayload.Copy(aInputPayload.Ptr(), ISAKMP_HDR_SIZE); //The same HDR in output + + TPtr8 ciphertext((TUint8 *)aOutputPayload.Ptr() + ISAKMP_HDR_SIZE, 0, aInputPayload.Length() - ISAKMP_HDR_SIZE);//skip hdr + // + // Construct cipher object for symmetric decrypt operation + // + CUtlSymmetricCipher* UtlCipher = TUtlCrypto::MakeSymmetricEncryptorL(CipherId, + aKey, + iv_ptr); + CleanupStack::PushL(UtlCipher); + UtlCipher->ProcessFinalL(plaintext, ciphertext); + CleanupStack::PopAndDestroy(); + // + // Next IV (last cipher block of encrypted buffer) + // + aOutputPayload.SetLength(ISAKMP_HDR_SIZE + ciphertext.Length()); + aIV.Copy(aOutputPayload.Ptr() + aOutputPayload.Length() - CbLth, CbLth); + + return ETrue; + +} + + +void MD5HashL(const TDesC8 &aInData, TDes8& aOutData) +{ + CUtlMessageDigest* Digest = TUtlCrypto::MakeMessageDigesterL(TUtlCrypto::EUtlMessageDigestMd5); + aOutData.Copy(Digest->Final(aInData)); + delete Digest; +} + +void SHA1HashL(const TDesC8 &aInData, TDes8& aOutData) +{ + CUtlMessageDigest* Digest = TUtlCrypto::MakeMessageDigesterL(TUtlCrypto::EUtlMessageDigestSha1); + aOutData.Copy(Digest->Final(aInData)); + delete Digest; +} + +void MD5HmacL(const TDesC8 &aInData, TDes8& aOutData, const TDesC8& aKeyData) +{ + CUtlMessageDigest* Digest = TUtlCrypto::MakeMessageDigesterL(TUtlCrypto::EUtlMessageDigestMd5, + aKeyData); + aOutData.Copy(Digest->Final(aInData)); + delete Digest; +} + +void SHA1HmacL(const TDesC8 &aInData, TDes8& aOutData, const TDesC8& aKeyData) +{ + CUtlMessageDigest* Digest = TUtlCrypto::MakeMessageDigesterL(TUtlCrypto::EUtlMessageDigestSha1, + aKeyData); + aOutData.Copy(Digest->Final(aInData)); + delete Digest; +} + +void Hmac3DesCbcL(const TDesC8 &aInData, TDes8& aOutData, const TDesC8& aKeyData) +{ + TUint8 *pad = new (ELeave) TUint8[PAD_SIZE]; + TInt pad_len = 0; + CleanupStack::PushL(pad); + TBuf8<8> iv; + TBuf8<24> prf_key2; + TPtrC8 prf_key_ptr; + + if ( aKeyData.Length() < 24) //if less than 24 bits the rest must be 0's + { + prf_key2.FillZ(24); + prf_key2.Copy(aKeyData); + prf_key2.SetLength(24); + prf_key_ptr.Set(prf_key2); + } + else + { + prf_key_ptr.Set(aKeyData); + } + iv.FillZ(8); + Mem::Copy(pad, aInData.Ptr(), aInData.Length()); + pad_len = aInData.Length(); + if ( pad_len & 0x07 ) //Add padding to align to byte pieces?????????? + { + Mem::FillZ(&pad[pad_len], 7); + pad_len += 7; + pad_len = (pad_len & 65528) + 8; + } + Cipher3DesL(pad, pad_len, prf_key_ptr, iv, aOutData); + + CleanupStack::PopAndDestroy(); //pad + +} + +void Cipher3DesL(TUint8 *aInData, TInt aInDataLen, const TDesC8 &aPrfKey, TDes8 &aIV, TDes8 &aOutData) +{ + + TPtrC8 iv_ptr(aIV.Ptr(), DESCBC_IV_LEN); + TPtrC8 key_ptr(aPrfKey.Ptr(), 3*DESCBC_KEY_LEN); + + HBufC8 *des_input = HBufC8::NewL(aInDataLen + 8); + CleanupStack::PushL(des_input); + TPtr8 des_input_ptr((TUint8 *)des_input->Des().Ptr(), aInDataLen + 8, aInDataLen + 8); //Contains the PRF input text + TPtrC8 plain_input_text(aInData, aInDataLen);//skip hdr + // + // Construct cipher object for symmetric decrypt operation + // + CUtlSymmetricCipher* UtlCipher = TUtlCrypto::MakeSymmetricEncryptorL(TUtlCrypto::EUtlSymmetricCipher3DesCbc, + key_ptr, + iv_ptr); + CleanupStack::PushL(UtlCipher); + + HBufC8 *des_output= HBufC8::NewL(des_input_ptr.Length() + UtlCipher->BlockSize()); + CleanupStack::PushL(des_output); + TPtr8 des_output_ptr((TUint8 *)des_output->Des().Ptr(), des_input_ptr.Length() + UtlCipher->BlockSize()); + + UtlCipher->ProcessFinalL(plain_input_text, des_output_ptr); + TPtrC8 tmp_input_data(&des_output_ptr[des_output_ptr.Length() - 8], 8); //Input Data to the 2nd 8-bit chunk encryption + UtlCipher->Reset(); //Restart + UtlCipher->ProcessFinalL(tmp_input_data, aOutData); + + // Do second eight bytes + des_input_ptr.Copy(aOutData); + des_input_ptr.Append(plain_input_text); //reattach the input data + UtlCipher->Reset(); //Restart + UtlCipher->ProcessFinalL(des_input_ptr, des_output_ptr); + + tmp_input_data.Set(&des_output_ptr[des_output_ptr.Length() - 8], 8); + TPtr8 out_data_ptr((TUint8 *)aOutData.Ptr() + 8, 0, 8); + UtlCipher->Reset(); //Restart + UtlCipher->ProcessFinalL(tmp_input_data, out_data_ptr); + + // Do third eight bytes + Mem::Copy((TUint8 *)des_input_ptr.Ptr(), aOutData.Ptr() + 8, 8); //last 8 bytes of previous result put at the beginning + //The length of des_input_ptr won't change so the data after byte 8 is still used!!! + UtlCipher->Reset(); //Restart + UtlCipher->ProcessFinalL(des_input_ptr, des_output_ptr); + + tmp_input_data.Set(&des_output_ptr[des_output_ptr.Length() - 8], 8); + out_data_ptr.Set((TUint8 *)aOutData.Ptr() + 16, 0, 8); //the last 8 bytes (16 to 23) + UtlCipher->Reset(); //Restart + UtlCipher->ProcessFinalL(tmp_input_data, out_data_ptr); + + aOutData.SetLength(24); + + CleanupStack::PopAndDestroy(3); // des_output, UtlCipher and des_input +} + +TInt SymmetricCipherL(TUint8 *aInput, TUint8 *aOutput, TInt aLength, + TUint8 *aKey, TUint8 *aIV, TBool aEncr, TInt aEncAlg) +{ + (void)aEncAlg; + TPtrC8 iv_ptr(aIV, DESCBC_IV_LEN ); + TPtrC8 key_ptr(aKey, DESCBC_IV_LEN); + + CUtlSymmetricCipher* UtlCipher; + if ( aEncr ) { + // + // Add padding (according RFC 1423) and encrypt data + // + TInt PaddingBytes = 8 - (aLength % 8); + for ( TInt i = 0; i < PaddingBytes; i++ ) { + *(aInput + aLength + i) = (TUint8)PaddingBytes; + } + aLength += PaddingBytes; + UtlCipher = TUtlCrypto::MakeSymmetricEncryptorL(TUtlCrypto::EUtlSymmetricCipherDesCbc, + key_ptr, iv_ptr); + } + else { + // + // Decrypt data + // + UtlCipher = TUtlCrypto::MakeSymmetricDecryptorL(TUtlCrypto::EUtlSymmetricCipherDesCbc, + key_ptr, iv_ptr); + } + CleanupStack::PushL(UtlCipher); + TPtrC8 inp(aInput, aLength); + TPtr8 outp(aOutput, aLength); + UtlCipher->ProcessFinalL(inp, outp); + CleanupStack::PopAndDestroy(); + + if ( !aEncr ) { + // + // Remove padding from decrypted data + // + TUint8 PaddingLth = *(aOutput + aLength - 1); + if ( PaddingLth < 9 ) + aLength -= (TInt)PaddingLth; // Ok padding count + else aLength = 0; + } + + return aLength; + +} + + + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1dialog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1dialog.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,665 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: CIkeDialog class implementation +* +*/ + +#include + +#include "ikev1dialog.h" +#include "dhparameters.h" +#include "ikedebug.h" +#include "ikev1pluginsession.h" +#include "ikev1crypto.h" +#include "ikev1filesdef.h" + + +CIkev1Dialog::CIkev1Dialog( MIkeDebug& aDebug ) + : CActive( EPriorityStandard ), + iDebug( aDebug ) +{ + CActiveScheduler::Add(this); //Added to the Active Scheduler +} + +CIkev1Dialog::~CIkev1Dialog() +{ + DEBUG_LOG(_L("CIkev1Dialog destructed")); + + DeQueueDialog(this); + + if(iTimeout) + { + iTimeout->Cancel(); + } + Cancel(); // Dialog itself + + delete iTimeout; + delete iInputData; + + iFs.Close(); +} + +void CIkev1Dialog::PurgeDialogQueue(CIkev1Dialog* aQueuedDialog) +{ + CIkev1Dialog* NextDialog; + while ( aQueuedDialog ) { + NextDialog = aQueuedDialog->iNext; + delete aQueuedDialog; + aQueuedDialog = NextDialog; + } +} + +void CIkev1Dialog::DoCancel() +{ + iNotifier.CancelNotifier(KUidVpnDialogNotifier); + iNotifier.Close(); + DEBUG_LOG(_L("CIkev1Dialog::DoCancel() OK")); +} + +void CIkev1Dialog::ConstructL(CIkev1PluginSession* aPluginSession, CIkev1Dialog* *aToQueAnchor) +{ + User::LeaveIfError(iFs.Connect()); + iTimeout = new (ELeave) CDialogTimeout( iDebug ); + iTimeout->ConstructL(this); + iToQueAnchor = aToQueAnchor; + iPluginSession = aPluginSession; +} + +CIkev1Dialog* CIkev1Dialog::NewL( CIkev1PluginSession* aPluginSession, + CIkev1Dialog** aToQueAnchor, + MIkeDebug& aDebug ) +{ + CIkev1Dialog* Dialog = new (ELeave) CIkev1Dialog( aDebug ); + Dialog->ConstructL( aPluginSession, aToQueAnchor ); + + return Dialog; +} + +void CIkev1Dialog::StoreUserNameL(TPtr8 aUserName) +{ +/*-------------------------------------------------------------------- + * + * Store specified user name into cache file (used as init value in + * the next user name specific dialog). + * User name shall be encrypted (DES) before stored into cache file. + * + *---------------------------------------------------------------------*/ + + + if (aUserName.Length() == 0) + { + User::Leave(KErrArgument); + } + + // + // Allocate buffer for file header and encrypted key + // + + HBufC8* HeaderBfr = HBufC8::NewLC(aUserName.Length() + sizeof(TUserNameFileHdr) + 32); + + TUserNameFileHdr* FileHeader = (TUserNameFileHdr*)HeaderBfr->Ptr(); + // + // Get random data values for salt and IV. + // + TPtr8 ptr((TUint8*)FileHeader, sizeof(TUserNameFileHdr)); + ptr.SetLength(sizeof(TUserNameFileHdr)); + TRandom::RandomL(ptr); + + FileHeader->iFileId = USER_NAME_FILE_ID; + // + // Build encryption key from just created salt data and fixed + // secret passphrase using MD5 hash + // + TBuf8<16> EncryptionKey; + TPtr8 SaltPtr((TUint8*)FileHeader->iSalt, 8, 8); + User::LeaveIfError(CIkev1Dialog::BuildEncryptionKey(SaltPtr, EncryptionKey)); + // + // Encrypt user name data with just created key. + // Because DES is used as encryption algorithm, the eight first + // octets of created encryption octets is used as encryption key. + // + TInt EncrLth = 0; + EncrLth = SymmetricCipherL((TUint8*)aUserName.Ptr(), + ((TUint8*)FileHeader + sizeof(TUserNameFileHdr)), + aUserName.Length(), FileHeader->iIV, (TUint8*)EncryptionKey.Ptr(), ETrue); + if ( EncrLth ) + { + // + // Write encrypted data into user name file + // + RFile NameFile; + + TBuf<128> Ppath; + User::LeaveIfError(iFs.PrivatePath(Ppath)); + + Ppath.Append(USER_NAME_CACHE_FILE); + TInt err = iFs.CreatePrivatePath(EDriveC); + if (err != KErrNone && + err != KErrAlreadyExists) + { + User::Leave(err); + } + User::LeaveIfError(NameFile.Replace(iFs, Ppath, EFileShareAny|EFileWrite)); + + TPtrC8 EncryptedData((TUint8*)FileHeader, sizeof(TUserNameFileHdr) + EncrLth); + + NameFile.Write(EncryptedData); + NameFile.Close(); + } + + CleanupStack::PopAndDestroy(); // Delete encryption buffer +} + +/*-------------------------------------------------------------------- + * + * Asynchronous dialog is completed. + * + *---------------------------------------------------------------------*/ +void CIkev1Dialog::RunL() +{ + TInt delete_obj = 1; + HBufC8 *un_bfr = NULL; + HBufC8 *pw_bfr = NULL; + CIkev1Dialog* NextDialog = iNext; + + iNotifier.CancelNotifier(KUidVpnDialogNotifier); + iNotifier.Close(); + + if ( iStatus.Int() == KErrNone ) + { + if ( iCallback ) + { + TIPSecDialogOutput& resp = iResponseBuf(); + un_bfr = ConvertPwdToOctetString(resp.iOutBuf); + pw_bfr = ConvertPwdToOctetString(resp.iOutBuf2); + } + } + + if ( iCallback ) + { + TInt err; + TRAP(err, delete_obj = iCallback->DialogCompleteL(this, iUserInfo, + un_bfr, //User name + pw_bfr, //Password + NULL)); //domain + delete un_bfr; + delete pw_bfr; + if ( err != KErrNone ) + delete_obj = 1; + } + + if ( delete_obj ) + { + delete this; + } + + // + // Start a dialog from wait queue if there is some + // + if ( NextDialog ) + NextDialog->StartDialogL(); +} + + +/*-------------------------------------------------------------------- + * + * Get user name and password data for Legacy authentication + * This is a synchronous dialog which does NOT convert user name and + * password data into the 8-bit ASCII text + * + *---------------------------------------------------------------------*/ +TInt CIkev1Dialog::GetSyncUNPWDialog(TDes& aUserName, TDes& aPassword) +{ +TIPSecDialogOutput output; + + + TIPSecDialogInfo dialog_input(TKMDDialog::EUserPwd, 0); + + TPckgBuf InfoBuf(dialog_input);//package it in appropriate buf + + TPckgBuf ResponseBuf(output);//create the buf to receive the response + + TInt status = LauchSyncDialog(InfoBuf, ResponseBuf); + if ( status == KErrNone ) { + TIPSecDialogOutput& resp = ResponseBuf(); + aUserName = resp.iOutBuf; + aPassword = resp.iOutBuf2; + } + + return status; +} + +/*-------------------------------------------------------------------- + * + * Get user name and password data for Legacy authentication + * This is a synchronous dialog which does NOT convert user name and + * password data into the 8-bit ASCII text + * Uses username cache + * + *---------------------------------------------------------------------*/ +TInt CIkev1Dialog::GetSyncUNPWCacheDialog(TDes& aUserName, TDes& aPassword) +{ + TInt status = KErrGeneral; + TIPSecDialogOutput output; + + TIPSecDialogInfo dialog_input(TKMDDialog::EUserPwd, 0); + + iInputData = CreateDialogInput(dialog_input, ETrue);// TRUE = Use user name cache + + TPckgBuf ResponseBuf(output);//create the buf to receive the response + + if ( iInputData ) + status = LauchSyncDialog((TPckgBuf&)*iInputData, ResponseBuf); + + if ( status == KErrNone ) { + TIPSecDialogOutput& resp = ResponseBuf(); + aUserName = resp.iOutBuf; + aPassword = resp.iOutBuf2; + } + + return status; +} + +void CIkev1Dialog::ShowErrorDialogL(TInt aDialogText, TAny *aUserInfo, MIkeDialogComplete* aCallback ) +{ + iDialogType = TNoteDialog::EInfo; + iUserInfo = aUserInfo; + iCallback = aCallback; // For asynchronous dialog RunL + + TIPSecDialogInfo dialog_input(TNoteDialog::EInfo, aDialogText); + iInputData = CreateDialogInput(dialog_input, EFalse);// FALSE = Do not use user name cache + if ( iInputData ) + LaunchDialogL(); //launch the dialog +} + +/*-------------------------------------------------------------------- + * + * Get user name and password data for Legacy authentication + * + *---------------------------------------------------------------------*/ +void CIkev1Dialog::GetAsyncUNPWDialogL(TAny *aUserInfo, MIkeDialogComplete* aCallback) +{ + DEBUG_LOG2(_L("CIkev1Dialog::GetAsyncUNPWDialogL(), aUserInfo = %x, aCallback = %x"), aUserInfo, aCallback); + + iDialogType = TKMDDialog::EUserPwd; + iUserInfo = aUserInfo; + iCallback = aCallback; // For asynchronous dialog RunL + + TIPSecDialogInfo dialog_input(TKMDDialog::EUserPwd, 0); + iInputData = CreateDialogInput(dialog_input, ETrue);// TRUE = Use user name cache + if ( iInputData ) + LaunchDialogL(); //launch the dialog +} + +/*-------------------------------------------------------------------- + * + * Get user name and Secure ID pin data for Legacy authentication + * + *---------------------------------------------------------------------*/ +void CIkev1Dialog::GetAsyncSecureidDialogL(TAny *aUserInfo, MIkeDialogComplete* aCallback) +{ + DEBUG_LOG2(_L("CIkev1Dialog::GetAsyncSecureidDialogL(), aUserInfo = %x, aCallback = %x"), aUserInfo, aCallback); + + iDialogType = TKMDDialog::ESecurIdPin; + iUserInfo = aUserInfo; + iCallback = aCallback; // For asynchronous dialog RunL + + TIPSecDialogInfo dialog_input(TKMDDialog::ESecurIdPin, 0); + iInputData = CreateDialogInput(dialog_input, ETrue);// TRUE = Use user name cache + if ( iInputData ) + LaunchDialogL(); //launch the dialog +} + +/*-------------------------------------------------------------------- + * + * Get user name and Secure ID next pin data for Legacy authentication + * + *---------------------------------------------------------------------*/ +void CIkev1Dialog::GetAsyncSecureNextPinDialogL(TAny *aUserInfo, MIkeDialogComplete* aCallback) +{ + DEBUG_LOG2(_L("CIkev1Dialog::GetAsyncSecureNextPinDialogL(), aUserInfo = %x, aCallback = %x"), aUserInfo, aCallback); + + iDialogType = TKMDDialog::ESecurIdNextPin; + iUserInfo = aUserInfo; + iCallback = aCallback; // For asynchronous dialog RunL + + TIPSecDialogInfo dialog_input(TKMDDialog::ESecurIdNextPin, 0); + iInputData = CreateDialogInput(dialog_input, ETrue);// TRUE = Use user name cache + if ( iInputData ) + LaunchDialogL(); //launch the dialog +} + + +/*-------------------------------------------------------------------- + * + * For future use (for challenge/response type Legacy authentication) + * + *---------------------------------------------------------------------*/ +void CIkev1Dialog::GetAsyncUNAMEDialog(TAny* /*aUserInfo*/, MIkeDialogComplete* /*aCallback*/) +{ +} + +void CIkev1Dialog::GetAsyncRespDialog(TPtr8 /*aChallenge*/, TAny* /*aUserInfo*/, MIkeDialogComplete* /*aCallback*/) +{ +} + + +/////////////////////////////////////////////////////////////////////////////// +// +// Private methods +// +/////////////////////////////////////////////////////////////////////////////// +HBufC8* CIkev1Dialog::CreateDialogInput(TIPSecDialogInfo& aDialogInfo, TBool aUserNameCache) +{ + // + // Create dialog input data buffer. Concatenate cached user name + // string into input data if requested and if cached name exists + // + HBufC8* DialogInput; + HBufC8* UserName = NULL; + TInt UserNameLth = 0; + TPckgBuf infoBuf(aDialogInfo); + + if ( aUserNameCache ) { + UserName = GetUserNameFromFile(); + if ( UserName ) + UserNameLth = UserName->Length(); + } + + DialogInput = HBufC8::New(sizeof(TIPSecDialogInfo) + UserNameLth); + if ( DialogInput ) { + DialogInput->Des().Copy(infoBuf); + if ( UserName ) { + DialogInput->Des().Append(UserName->Des()); + delete UserName; + } + } + + return DialogInput; +} + +void CIkev1Dialog::LaunchDialogL() +{ + // + // Launch the dialog if there is no dialog already going + // + if ( QueueDialog(this) == 1 ) + { + StartDialogL(); + } +} + +void CIkev1Dialog::StartDialogL() +{ + // + // Start an asynchronous dialog + // + User::LeaveIfError(iNotifier.Connect()); + iNotifier.StartNotifierAndGetResponse(iStatus, + KUidVpnDialogNotifier, + (TPckgBuf&)(*iInputData), + iResponseBuf); + SetActive(); +} + + +TInt CIkev1Dialog::LauchSyncDialog(const TDesC8& aInput, TDes8& aOutput) +{ + RNotifier notifier; + TInt err = notifier.Connect(); + if(err != KErrNone) + { + return err; + } + + TRequestStatus status; + notifier.StartNotifierAndGetResponse(status, KUidVpnDialogNotifier, aInput, aOutput); + User::WaitForRequest( status ); + + notifier.CancelNotifier(KUidVpnDialogNotifier); + notifier.Close(); + + return status.Int(); +} + +TInt CIkev1Dialog::QueueDialog(CIkev1Dialog* aDialog) +{ + TInt DialogCount = 1; + aDialog->iNext = NULL; + CIkev1Dialog* QueuedDialog = *aDialog->iToQueAnchor; + + if ( QueuedDialog ) + { + DialogCount ++; + while ( QueuedDialog->iNext ) { + QueuedDialog = QueuedDialog->iNext; + DialogCount ++; + } + QueuedDialog->iNext = aDialog; + } + else *aDialog->iToQueAnchor = aDialog; + + return DialogCount; +} + +void CIkev1Dialog::DeQueueDialog(CIkev1Dialog* aDialog) +{ + CIkev1Dialog* PreviousDialog = NULL; + CIkev1Dialog* QueuedDialog = *aDialog->iToQueAnchor; + + while ( QueuedDialog ) { + if ( QueuedDialog == aDialog ) { + if ( PreviousDialog ) + PreviousDialog->iNext = QueuedDialog->iNext; + else *aDialog->iToQueAnchor = QueuedDialog->iNext; + } + PreviousDialog = QueuedDialog; + QueuedDialog = QueuedDialog->iNext; + } +} + +HBufC8* CIkev1Dialog::GetUserNameFromFile() +{ +/*-------------------------------------------------------------------- + * + * Get user name default value from encrypted cache file + * + *---------------------------------------------------------------------*/ + // + // Allocate buffer for file header and encrypted key + // + HBufC8* UserNameBfr = NULL; + RFile UserNameFile; + if ( UserNameFile.Open(iFs, USER_NAME_CACHE_FILE, EFileRead) == KErrNone ) { + TInt FileSize = 0; + UserNameFile.Size(FileSize); + if ( (FileSize > 0) && (FileSize < 256) ) { + HBufC8* FileData = HBufC8::New(FileSize); + if ( FileData ) { + // + // Read encrypted file data into the allocated buffer. + // + TPtr8 FileDataPtr(FileData->Des()); + if ( UserNameFile.Read(FileDataPtr) == KErrNone ) { + // + // Build decryption key and decrypt user name data. + // Both salt data needed in key generation and IV + // value required in decryption are found from + // encrypted file header + // + TUserNameFileHdr* FileHeader = (TUserNameFileHdr*)FileData->Ptr(); + if ( FileHeader->iFileId == USER_NAME_FILE_ID ) { + TBuf8<16> DecryptionKey; + TPtr8 SaltPtr((TUint8*)FileHeader->iSalt, 8, 8); + if ( CIkev1Dialog::BuildEncryptionKey(SaltPtr, DecryptionKey) ) { + TInt EncrLth = FileSize - sizeof(TUserNameFileHdr); + TUint8* UserNameRawPtr = (TUint8*)FileHeader + sizeof(TUserNameFileHdr); + TInt err; + TRAP(err, EncrLth = SymmetricCipherL(UserNameRawPtr, UserNameRawPtr, EncrLth, + FileHeader->iIV, (TUint8*)DecryptionKey.Ptr(), EFalse)); + if ( (err == KErrNone) && EncrLth ) { + // + // Allocate a HBufC8 for decrypted user name + // + UserNameBfr = HBufC8::New(EncrLth); + if ( UserNameBfr ) + UserNameBfr->Des().Copy(UserNameRawPtr, EncrLth); + } + } + } + } + delete FileData; + } + } + } + + UserNameFile.Close(); + return UserNameBfr; +} + + +HBufC8 *CIkev1Dialog::ConvertPwdToOctetString(TDesC &aUnicodeBfr) +{ +/*-------------------------------------------------------------------- + * + * Convert password from Unicode string to 8-bit octet string + * + *---------------------------------------------------------------------*/ + HBufC8 *octet_data = HBufC8::New(aUnicodeBfr.Length()); + if ( octet_data ) { + TPtr8 ptr8(octet_data->Des()); + ptr8.Copy(aUnicodeBfr); + } + return octet_data; +} + + + +TBool CIkev1Dialog::BuildEncryptionKey(const TDesC8& aSalt, TDes8& aEncryptionKey) +{ +/*-------------------------------------------------------------------- + * + * Build encryption key for user name data cipher. + * The encryption key is created as follows: + * DH group 5 (MODP 1536) prime is used as passphrase seed so + * that MODP_1536_PRIME_LENGTH/4 octets of seed is taken from prime + * starting from position MODP_1536_PRIME_LENGTH/2. + * The specified salt is concatenated with that data. + * The MD5 hash over that shall be the encryption key (max key then + * 128 bits) + * + *---------------------------------------------------------------------*/ + // + // Allocate buffer for key seed data + // + HBufC8* SeedDataBfr = HBufC8::New(aSalt.Length() + MODP_1536_PRIME_LENGTH/4); + if ( !SeedDataBfr ) + return EFalse; + + TPtr8 SeedDataPtr(SeedDataBfr->Des()); + TPtrC8 PassPhrasePtr((TUint8 *)&MODP_1536_PRIME[MODP_1536_PRIME_LENGTH/2], + MODP_1536_PRIME_LENGTH/4); + SeedDataPtr.Copy(PassPhrasePtr); + SeedDataPtr.Append(aSalt); + + TInt err; + TRAP(err, MD5HashL(SeedDataPtr, aEncryptionKey)); + + delete SeedDataBfr; + + if ( err == KErrNone ) + return ETrue; + else return EFalse; + +} + + + +/**------------------------------------------------------- + * + * CDialogTimeout class + * This timeout class used to check user dialog displayed + * shall be completed in reasonable time (now 90 seconds). + * This class is used the following way: + * -- When a CIkev1Dialog class object is constructed one + * CDialogTimeout object is constructed as well. These + * objects are linked together. + * -- If user dialog completes normally (within 90 seconds) + * CDialogTimeout is cancelled in CIkev1Dialog.RunL(). + * -- If timeout expires, CIkev1Dialog is completed via CDialogTimeout.RunL() + * + *--------------------------------------------------------*/ +CDialogTimeout::CDialogTimeout( MIkeDebug& aDebug ) + : CTimer( EPriorityStandard ), + iDebug( aDebug ) +{ + CActiveScheduler::Add(this); //Adds itself to the scheduler only the first time +} + +CDialogTimeout::~CDialogTimeout() +{ + DEBUG_LOG(_L("CDialogTimeout destructed")); + if (IsActive()) + Cancel(); +} + +void CDialogTimeout::ConstructL(CIkev1Dialog *aDialog) +{ + CTimer::ConstructL(); + iDialog = aDialog; + After(90*1000000); //Start dialog timer +} + +void CDialogTimeout::DoCancel() +{ + DEBUG_LOG(_L("CDialogTimeout cancelled")); + CTimer::DoCancel(); +} + +void CDialogTimeout::RunL() +{ + DEBUG_LOG(_L("CKmdDialog timeout occurred")); + TInt delete_dialog = 1; + CIkev1Dialog* NextDialog = iDialog->NextDialog(); + MIkeDialogComplete* Callback = iDialog->Callback(); + + if ( Callback ) + { + TInt err; + DEBUG_LOG2(_L("Calling DialogCompleteL(), UserInfo = %x, Callback = %x"), (TUint32)iDialog->UserInfo(), (TUint32)Callback); + TRAP(err, delete_dialog = Callback->DialogCompleteL(iDialog, + iDialog->UserInfo(), + NULL, //User name + NULL, //Password + NULL)); //domain + DEBUG_LOG2(_L("DialogCompleteL() completed, err = %d, delete_dialog = %d"), err, delete_dialog); + if ( err != KErrNone ) + delete_dialog = 1; + } + if ( delete_dialog ) + { + delete iDialog; + iDialog = NULL; + } + + // + // Start a dialog from wait queue if there is some + // + if ( NextDialog ) + { + DEBUG_LOG(_L("Next dialog started from dialog timer")); + NextDialog->StartDialogL(); + } +} + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1extra.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1extra.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,501 @@ +/* +* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Key management daemon extra module. +* +*/ + + +#include + +#include "ikev1extra.h" + +//////////////////////////////////////////////////////////////7 +// +// Global functions +// +//Puts the data in the descriptor into a TInt64 +TInt Desc8ToTInt64(const TDesC8 &aLifetime, TInt64 &aTime) +{ + TUint32 high,low; + + //Seconds lifetime + //TAttrib_II *attr_II = aProp->iAttrList->At(0); //presume only 1 transform for each proposal + TUint len = aLifetime.Length(); + TInt high_len = 0; + if (len > 0) + { + if (len > sizeof(aTime)) + { + //LogError(_L("Phase_II Lifetime(sec) Overflowed Setting to maximum value")); + aTime = MAKE_TINT64(KMaxTInt,KMaxTUint); + return KErrOverflow; + } + else + { + if (len <= sizeof(TUint)) + high = 0; + else + { + high_len = len - sizeof(TUint); + Mem::Copy(&high, aLifetime.Ptr(), high_len); //The first total_length - sizeof(TUint) bytes + high = ByteOrder::Swap32(high); + high = high >> (sizeof(TUint)*8 - len*8); //To set the correct value (shift in bits) + len = sizeof(TUint); //remaining length + } + + Mem::Copy(&low, aLifetime.Ptr() + high_len , len); + low = ByteOrder::Swap32(low); + low = low >> (sizeof(TUint)*8 - len*8); //To set the correct value (shift in bits) + aTime = MAKE_TINT64(high,low ); + } + } + else + aTime = 0; + + return KErrNone; +} + +//Creates an addr. mask of aPrefixLen length +void PrefixMask(TInetAddr &anAddr, TInt aPrefixLen, TInt aFamily) +{ + if (aFamily == STATIC_CAST(TInt, KAfInet)) + { + TUint32 addr = 0; + if ( aPrefixLen ) { + addr = INET_ADDR(255,255,255,255); + addr <<= 32 - aPrefixLen; + } + anAddr.SetAddress(addr); + anAddr.SetFamily(KAfInet); + } + else //KAfInet6 + anAddr.PrefixMask(aPrefixLen); //This method only works for IPv6 + +} + +TInt PrefixLen(TInetAddr& anAddr) +{ + TIp6Addr ip6addr = anAddr.Ip6Address(); + TInt length; + TInt i; + + switch (anAddr.Family()) + { + case KAfInet: + TReal bit; + TInt err; + TInt mask8; + + length = 32; + + for (i = 0; i < length; i++) + { + err = Math::Pow(bit,2,i % 8); + if (err != KErrNone) + return err; + mask8 = ip6addr.u.iAddr8[(TInt)(i/8)] & (TInt)bit; + if (mask8 == (TInt)bit) //The bit is 1 + break; + } + + return length - i;//length of the mask + + case KAfInet6: + i = 3; // index to a n-bit chunk of an address + length = 128; // first assumption on length of the prefix + + // start counting the 32 bit zero chunks from end + while (ip6addr.u.iAddr32[i] == 0) + { + length -= 32; + if (--i < 0) + return 0; // zero length prefix + } + + // switch to 16 bit chunks + i = i * 2 + 1; + if (ip6addr.u.iAddr16[i] == 0) + { + length -= 16; + i--; + } + + // switch to 8 bit chunks + i = i * 2 + 1; + if (ip6addr.u.iAddr8[i] == 0) + { + length -= 8; + i--; + } + + // switch to 1 bit chunks + { + TUint8 octet = ip6addr.u.iAddr8[i]; + for (i = 1; (octet & i) == 0; i <<= 1) + length--; + } + + return length; + + default: + return KErrNotSupported; + } +} + + + +//////////////////////////////////////////////////////////////////////////////////// +// +//class TAttrib +// +//aIsRelaxed indicates theat the lifetimes won't be compared +TInt TAttrib::Compare(TAttrib& aAttr, TBool aIsRelaxed) +{ + if (iTransformID != aAttr.iTransformID) + return KErrTransformID; + if (iEncrAlg != aAttr.iEncrAlg) + return KErrEncrAlg; + if (iHashAlg != aAttr.iHashAlg) + return KErrHashAlg; + if (iAuthMethod != aAttr.iAuthMethod) + return KErrAuthMethod; + if (iGroupDesc != aAttr.iGroupDesc) + return KErrGroupDesc; + if ((iGroupType != aAttr.iGroupType) && + (!(iGroupType == 0) && (aAttr.iGroupType == MODP))) //MODP is the default type so is the same as 0 + return KErrGroupType; + if (iGroupPrime.Compare(aAttr.iGroupPrime)!=0) + return KErrGroupPrime; + if (iGroupGen1.Compare(aAttr.iGroupGen1)!=0) + return KErrGroupGen1; + if (iGroupGen2.Compare(aAttr.iGroupGen2)!=0) + return KErrGroupGen2; + if (iGroupCurveA.Compare(aAttr.iGroupCurveA)!=0) + return KErrGroupCurveA; + if (iGroupCurveB.Compare(aAttr.iGroupCurveB)!=0) + return KErrGroupCurveB; + if (iPRF != aAttr.iPRF) + return KErrPRF; + if (iKeyLength != aAttr.iKeyLength) + { + if ( iEncrAlg != AES_CBC ) + return KErrKeyLength; + else + { + if ( !( aIsRelaxed && (iKeyLength == 128) && (aAttr.iKeyLength == 0)) ) + return KErrKeyLength; + } + + } + if (iFieldSize != aAttr.iFieldSize) + return KErrFieldSize; + if (iGroupOrder.Compare(aAttr.iGroupOrder)!=0) + return KErrGroupOrder; + + if (!aIsRelaxed) //If relaxed lifetimes don't need to match + { + if (iLifeDurationSecs.Compare(aAttr.iLifeDurationSecs)!=0) + return KErrLifeTime; + if (iLifeDurationKBytes.Compare(aAttr.iLifeDurationKBytes)!=0) + return KErrLifeSize; + } + return KErrNone; +} + +// +//class CTransModifierList : public CArrayPtr +// +CTransModifierList::CTransModifierList(TInt aGranularity) : CArrayPtrFlat(aGranularity) +{ + +} + +CTransModifierList::~CTransModifierList() +{ + ResetAndDestroy(); +} + +// +//class TAttrib_II +// +TAttrib_II::TAttrib_II() +{ + iTransformNum=0; + iTransformID=0; + iGroupDesc=0; + iEncMode=0; + iAuthAlg=0; + iKeyLength=0; + iKeyRounds=0; + iComprDicSize=0; +}; + +TInt TAttrib_II::Compare(TAttrib_II& aAttr, TBool aRelaxed) +{ + TBuf8 iComprPrivAlg; + +// if (iTransformNum != aAttr.iTransformNum) //Transform number +// return KErrTransformNum; // Test retired + if ( iTransformID != aAttr.iTransformID ) //Transform ID + return KErrTransformID; + + if ((iGroupDesc != aAttr.iGroupDesc) && + (!(iGroupDesc == 0) && (aAttr.iGroupDesc == MODP_768))) //OAKLEY GROUP + return KErrGroupDesc; + if (iEncMode != aAttr.iEncMode) //Encapsulation Mode + return KErrEncMode; + if (iAuthAlg != aAttr.iAuthAlg) //HMAC + return KErrAuthAlg; + + if (iKeyLength != aAttr.iKeyLength) + { + if ( iTransformID != ESP_AES_CBC ) + return KErrKeyLength; + else + { + if (!( ((iKeyLength == 128) && (aAttr.iKeyLength == 0) ) + || + ((iKeyLength == 0) && (aAttr.iKeyLength == 128) ) )) + return KErrKeyLength; + } + } + + if (iKeyRounds != aAttr.iKeyRounds) + { + if ( iTransformID != ESP_AES_CBC ) + return KErrKeyRounds; + if ( (iKeyRounds != 0 || aAttr.iKeyRounds != 10) // 10 AES default rounds + && + (iKeyRounds != 10 || aAttr.iKeyRounds != 0) ) + return KErrKeyRounds; + } + if (iComprDicSize != aAttr.iComprDicSize) //Compress Dictionary size + return KErrComprDicSize; + if (iComprPrivAlg.Compare(aAttr.iComprPrivAlg)!=0) + return KErrComprPrivAlg; + + if (!aRelaxed) + { + if (iLifeDurationSecs.Compare(aAttr.iLifeDurationSecs)!=0) + return KErrLifeTime; + if (iLifeDurationKBytes.Compare(aAttr.iLifeDurationKBytes)!=0) + return KErrLifeSize; + } + return KErrNone; +} + +void TAttrib_II::Copy(TAttrib_II &aAttr) +{ + iTransformNum = aAttr.iTransformNum; //Transform number + iTransformID = aAttr.iTransformID; //Transform ID + iLifeDurationSecs.Copy(aAttr.iLifeDurationSecs); + iLifeDurationKBytes.Copy(aAttr.iLifeDurationKBytes); + iGroupDesc = aAttr.iGroupDesc; //OAKLEY GROUP + iEncMode = aAttr.iEncMode; //Encapsulation Mode + iAuthAlg = aAttr.iAuthAlg; //HMAC + iKeyLength = aAttr.iKeyLength; + iKeyRounds = aAttr.iKeyRounds; + iComprDicSize = aAttr.iComprDicSize; //Compress Dictionary size + iComprPrivAlg.Copy(aAttr.iComprPrivAlg); +} + +// +//class CAttrib_IIList +// + +CAttrib_IIList::CAttrib_IIList(TInt aGranularity) : CArrayPtrFlat(aGranularity) +{ + +} + +CAttrib_IIList::~CAttrib_IIList() +{ + ResetAndDestroy(); +} + +// +//class CProposal_II +// + +void CProposal_II::ConstructL(TInt aGranularity) +{ + iAttrList = new (ELeave) CAttrib_IIList(aGranularity); //Default to granularity 1 +} + +CProposal_II::~CProposal_II() +{ + delete iAttrList; +} + +//Compares that aProp matches with one of the sets of attributes of this proposal and the Protocol +//aRelaxed indicates if the comparison includes the lifetimes or not. +//Returns KErrNotFound if no match or the transf num (>=0) if match +TInt CProposal_II::Match(CProposal_II *aRemoteProp, TBool aRelaxed, TInt* aLocalNbr ) +{ + + if (iProtocol != aRemoteProp->iProtocol) + return KErrPropProtocol; + + TInt ret = KErrNoTransforms; + TInt i, j, count2; + TInt count = iAttrList->Count(); + // + // Compare all transforms in the peer proposal to the all local proposals defined + // + for (i = 0; i < count ; i++) + { + j = 0; + count2 = aRemoteProp->iAttrList->Count(); + + for (j = 0; j < count2 ; j++) + { + ret = iAttrList->At(i)->Compare(*aRemoteProp->iAttrList->At(j), aRelaxed); + if (ret == KErrNone) { + if ( aLocalNbr ) + *aLocalNbr = i; + return j; + } + } + } + //No matching set of attributes + return ret; //return the last error +} + + + +// +//class CProposal_IIList +// + +CProposal_IIList::CProposal_IIList(TInt aGranularity) : CArrayPtrFlat(aGranularity) +{ + +} + +CProposal_IIList::~CProposal_IIList() +{ + ResetAndDestroy(); +} + +//IMPORTANT: assume all the proposals in this have the same number so they are AND'd +//If more than one proposal number in this the method won't work +//aTransArray contains the num of transform matching for each proposal +//Returns the Remote proposal num that matches (>=0) or an error (<0, see list) +TInt CProposal_IIList::MultiMatchL(CProposal_IIList *aRemoteProp, TBool aRelaxed, CTransModifierList *aTransArray) +{ + CProposal_II *rem_prop; //remote proposal + TInt trans_num = KErrNoRemoteProposals; + TInt local_num; + TInt i1 = 0, i2; + TInt prop_numII = aRemoteProp->At(0)->iProposalNum; //Proposed by the peer + + if ( Count() == 0 ) + return KErrNoLocalProposals; + + CProposal_II *prop1 = At(0); //First proposal in this + TInt count2 = aRemoteProp->Count(); + TTransModifier *tmodif; + + //loop through the remote proposals list. The local is restarted for every new remote proposal num. + for ( i2 = 0; i2 < count2 ; i2++ ) + { + rem_prop = aRemoteProp->At(i2); + + if ( rem_prop->iProposalNum == prop_numII ) + { + // Find matching transform from proposal + trans_num = prop1->Match(rem_prop, aRelaxed, &local_num); + + if ( trans_num >= 0 ) //There's a match + { + tmodif = new (ELeave) TTransModifier(); + CleanupStack::PushL(tmodif); + tmodif->iPropNum = prop1->iProposalNum; // Store local proposal number + tmodif->iTransNum = trans_num; // Store remote transform index in proposal + tmodif->iReplayWindowLength = prop1->iReplayWindowLength; //to update SAD correctly + tmodif->iReducedLifeSecs.Set(prop1->iAttrList->At(local_num)->iLifeDurationSecs); + tmodif->iReducedLifeKBytes.Set(prop1->iAttrList->At(local_num)->iLifeDurationKBytes); + aTransArray->AppendL(tmodif); //add to the array and go for the next + CleanupStack::Pop(); //tmodif safe + if ( (i1 + 1) < Count() ) //still proposals left in 'this' list + { + prop1 = At(i1++); + if ( (i2 + 1) == count2 ) //last proposal + return KErrPropNumberMismatch; //No match because more local than remote proposals + continue; + } + + if (i2 < (count2 - 1)) + { + //No more local proposals and still remote left + if (aRemoteProp->At(i2+1)->iProposalNum == prop_numII) + { //num mismatch begin again the local proposals loop + i1 = 0; + prop1 = At(0); //First proposal in this + aTransArray->Reset(); //Empties all the array because the current match is not valid + for (i2++; i2 < count2 ; i2++) //go for next remote proposal and + { + rem_prop = aRemoteProp->At(i2); + if (rem_prop->iProposalNum != prop_numII) + { + prop_numII = rem_prop->iProposalNum; //new proposal number to consider + i2--; //To fetch the correct proposal at the begining of the external loop + break; //next number found break the loop + } + } + continue; //Main loop continues + } + } + + break; //Loop finished. Acceptable proposal found ! + } + else //No transform matches so proposals lists don't match + { //look for the next remote proposal group (number) + i1 = 0; + prop1 = At(0); //First proposal in this + aTransArray->Reset(); //Empties all the array because the current match is not valid + i2++; //next proposal + if (i2 == count2) + return trans_num; //Error in the last transform + for (; i2 < count2 ; i2++) + { + rem_prop = aRemoteProp->At(i2); + if ( rem_prop->iProposalNum != prop_numII ) + { + prop_numII = rem_prop->iProposalNum; //new proposal number to consider + i2--; //To fetch the correct proposal at the begining of the external loop + break; //next number found break the loop + } + } + continue; //Main loop continues + } + } + else //New group of AND'd remote proposals + { + i1 = 0; + prop1 = At(0); + prop_numII = rem_prop->iProposalNum; //new proposal num + aTransArray->Reset(); //Empties all the array + i2 --; //To fetch the correct proposal at the begining of the external loop + } + + } + + if ( trans_num >= 0 ) + { + return prop_numII; //Remote proposal num that matches + } + //Otherwise fails the comparison + return trans_num; //No match. Returns last error in a transform +} diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1infonegotiation.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1infonegotiation.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,363 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: CIkev1InfoNegotiation class +* +*/ + +#include + +#include "ikev1infonegotiation.h" +#include "ikev1negotiation.h" +#include "ikev1SAdata.h" +#include "ikev1isakmpct.h" +#include "ikedebug.h" +#include "ikev1pluginsession.h" +#include "ikev1negotiation.h" +#include "ikev1crypto.h" +#include "ikev1payload.h" +#include "ikev1crack.h" +#include "ikev1trans.h" +#include "kmdapi.h" +#include "kmdeventloggerif.h" + + +CIkev1InfoNegotiation::CIkev1InfoNegotiation( CIkev1PluginSession& aPluginSession, + CIkev1Negotiation& aNegotiation, + MIkeDebug& aDebug ) + : iPluginSession( aPluginSession ), + iNegotiation( aNegotiation ), + iDebug( aDebug ) +{ +} + +#ifdef _DEBUG +void CIkev1InfoNegotiation::ExecuteL( const ThdrISAKMP& aHdr, + const TInetAddr& aSrcAddr, + TInt aLocalPort ) +#else +void CIkev1InfoNegotiation::ExecuteL( const ThdrISAKMP& aHdr, + const TInetAddr& /*aSrcAddr*/, + TInt /*aLocalPort*/ ) +#endif +{ + const ThdrISAKMP *hdr = NULL; + TUint8 *msg=NULL; + TBuf8 tmp_IV; //Temporal IV. Used to update the real one if the msg OK + + iMessageId = aHdr.GetMessageId(); //Saves the ID to compute IV and hash + if (aHdr.GetFlags() & ISAKMP_HDR_EFLAG) //if encrypted + { + DEBUG_LOG(_L("Received message (encr).")); + msg = new (ELeave) TUint8[aHdr.GetLength()]; //to place the new msg + CleanupStack::PushL(msg); + + Mem::Copy(msg,(TUint8 *)&aHdr, sizeof(aHdr)); //The header is not encrypted + + DEBUG_LOG(_L("Message ID recv:")); +#ifdef _DEBUG + TUint32 swap_id = ByteOrder::Swap32(iMessageId); + DEBUG_LOG_ARRAY((TUint8 *)&swap_id, sizeof(iMessageId)); + DEBUG_LOG(_L("Notif IV:")); +#endif // _DEBUG + //Notify and Phase II requires a recomputing of IV + + if (iNegotiation.iLastIV.Length() != 0) + tmp_IV.Copy(iNegotiation.iLastIV); + else //iLastIV not yet computed so current iIV is used + tmp_IV.Copy(iNegotiation.iIV); + iNegotiation.ComputeIVL(tmp_IV, iMessageId); + + DEBUG_LOG(_L("Decrypting...")); + + DecryptL((TUint8 *)aHdr.Next(),&msg[sizeof(aHdr)], aHdr.GetLength()-sizeof(aHdr), tmp_IV, iNegotiation.iSKEYID_e, iNegotiation.iChosenProposal_I.iAttrList->iEncrAlg); + hdr=(ThdrISAKMP *)msg; //decrypted msg + } + else + hdr = &aHdr; + + DEBUG_LOG(_L("Received message.")); +#ifdef _DEBUG + const TPtrC8 ikeMsgPtr( (TUint8*)hdr,(TUint16)hdr->GetLength() ); + TInetAddr localAddr; + iPluginSession.GetLocalAddress( localAddr ); + localAddr.SetPort( aLocalPort ); + TRACE_MSG_IKEV1( ikeMsgPtr, aSrcAddr, localAddr ); +#endif // _DEBUG + InfoExchangeL(*hdr); + if (msg) //If used erase it (when encryption) + CleanupStack::PopAndDestroy(); +} + +MKmdEventLoggerIf& CIkev1InfoNegotiation::EventLogger() +{ + return iPluginSession.EventLogger(); +} + +//No phase dependant. May inform of an error or general status info +void CIkev1InfoNegotiation::InfoExchangeL(const ThdrISAKMP &aHdr) +{ + iNegotiation.iLengthLeft = aHdr.GetLength(); //Used to check the size in the payload are OK + + CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, iNegotiation, iDebug); + if (!payload) + return; + CleanupStack::PushL(payload); + + TInt i; + TBool notif_ok = EFalse; + //If the message contains a hash + if ( payload->iHash ) + { + if ( payload->iNotifs->Count() ) + { + //Checks if the hash value is OK. Here because need the notification payload + if (!iNegotiation.VerifyInformationalHashL(payload->iHash, payload->iNotifs->At(0), iMessageId)) + { + DEBUG_LOG(_L("AUTHENTICATION_FAILED (Informational hash)")); + iNegotiation.SendNotifyL(AUTHENTICATION_FAILED); + } + else //Hash OK + { + i = 0; + while ( i < payload->iNotifs->Count() ) + { + notif_ok = ProcessNotificationL(payload->iNotifs->At(i), ETrue); + if ( !notif_ok ) + break; + i ++; + } + } + } + else if ( payload->iDeletes->Count() ) + { + if (!iNegotiation.VerifyInformationalHashL(payload->iHash, payload->iDeletes->At(0), iMessageId)) + { + DEBUG_LOG(_L("AUTHENTICATION_FAILED (Informational hash)")); + iNegotiation.SendNotifyL(AUTHENTICATION_FAILED); + } + else + { //Hash OK + if ( !iNegotiation.iAutoLogin && iNegotiation.iCRACKneg ) + iNegotiation.iCRACKneg->CrackAuthenticationFailedL(NULL); + if ( !iNegotiation.iAutoLogin && iNegotiation.iTransactionNeg ) + iNegotiation.iTransactionNeg->TransactionFailedL(NULL); + i = 0; + while ( i < payload->iDeletes->Count() ) + { + notif_ok = ProcessDeleteL(payload->iDeletes->At(0)); + if (!notif_ok) + break; + i ++; + } + } + } + else + { + DEBUG_LOG(_L("PAYLOAD_MALFORMED (no hash or delete payload)")); + iNegotiation.SendNotifyL(PAYLOAD_MALFORMED); + } + } + else //No hash sent + { + if (aHdr.GetFlags() & ISAKMP_HDR_EFLAG) //if encrypted + { + DEBUG_LOG(_L("PAYLOAD_MALFORMED (Hash required)")); + iNegotiation.SendNotifyL(PAYLOAD_MALFORMED); + } + else //Not encrypted so not hash required + { + i = 0; + while ( i < payload->iNotifs->Count() ) + { + notif_ok = ProcessNotificationL(payload->iNotifs->At(i), EFalse); + if ( !notif_ok ) + break; + i ++; + } + } + } + + if ( notif_ok ) { + const TNotificationISAKMP* notif = NULL; + if ( payload->iNotifs->Count() ) + notif = payload->iNotifs->At(0); + if ( iNegotiation.iCRACKneg ) { + if ( !iNegotiation.iAutoLogin ) + iNegotiation.iCRACKneg->CrackAuthenticationFailedL(notif); + iNegotiation.SetErrorStatus(KKmdIkeAuthFailedErr); + iNegotiation.AcquireSAErrorResponse(KKmdIkeAuthFailedErr); + } + if ( iNegotiation.iTransactionNeg ) { + if ( !iNegotiation.iAutoLogin ) + iNegotiation.iTransactionNeg->TransactionFailedL(notif); + iNegotiation.SetErrorStatus(KKmdIkeAuthFailedErr); + iNegotiation.AcquireSAErrorResponse(KKmdIkeAuthFailedErr); + } + } + + CleanupStack::PopAndDestroy(); //payload + +} + + +//Handles Notification Payload +TBool CIkev1InfoNegotiation::ProcessNotificationL(const TPayloadISAKMP *aPayload, TBool aEncrypted) +{ +#ifdef _DEBUG + TBuf<80> str; +#endif // _DEBUG + TNotificationISAKMP *notif = TNotificationISAKMP::Ptr(aPayload); + if (!iNegotiation.CheckDOI(notif->GetDOI())) + { + DEBUG_LOG(_L("DOI_NOT_SUPPORTED in NOT Payload Message.")); + return EFalse; + } + TBool Status; + TUint16 MsgType = notif->GetMsgType(); + + if ( (MsgType == DPD_R_U_THERE || MsgType == DPD_R_U_THERE_ACK) && aEncrypted ) + { + return ProcessDPDNotifyL(notif); + } + + if ( MsgType <= UNEQUAL_PAYLOAD_LENGTHS ) + { +#ifdef _DEBUG + str.Copy(_L("Error/Status Type: ")); +#endif // _DEBUG + Status = ETrue; + iNegotiation.SetNotifyStatus(MsgType); + + LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError, + R_VPN_MSG_VPN_GW_ERR_RESP_RECEIVED, + MsgType, + iPluginSession.VpnIapId(), + &(iNegotiation.iRemoteAddr) ); + } + else + { +#ifdef _DEBUG + str.Copy(_L("Unexpected info notification: ")); +#endif // _DEBUG + Status = EFalse; + } +#ifdef _DEBUG + str.Append(CIkev1Negotiation::TextNotifyType(MsgType)); + DEBUG_LOG(str); +#endif // _DEBUG + return Status; +} + +// +// Process DPD R-U_THERE / R-U-THERE-ACK +// When a R-U-THERE notify received it processes as follows: +// -- Find an ISAKMP SA with SPI in notify message +// -- Pass DPD notify message for further processing into +// CIkev1Negotiation::NotifyMessageReceived() via iNegotiation reference +// +TBool CIkev1InfoNegotiation::ProcessDPDNotifyL(TNotificationISAKMP* aNotify) +{ + + if ( aNotify->GetSPISize() == (2 * ISAKMP_COOKIE_SIZE) && (aNotify->GetNotifDataSize() == 4)) + { + TCookie cookie_I, cookie_R; + cookie_I.Copy(aNotify->GetSPI(), ISAKMP_COOKIE_SIZE); + cookie_R.Copy((aNotify->GetSPI() + ISAKMP_COOKIE_SIZE), ISAKMP_COOKIE_SIZE); + + TIkev1SAData* Sa = iPluginSession.FindIkev1SAData(cookie_I, cookie_R); + if ( !Sa ) + { + Sa = iPluginSession.FindIkev1SAData(cookie_R, cookie_I); +#ifdef _DEBUG + if (Sa) DEBUG_LOG(_L("ISAKMP SA found for DPD notify message with CKY_R+CKY_I")); +#endif // _DEBUG + } + if ( Sa && Sa->iDPDSupported ) + { + TUint32 Sequence = GET32(aNotify->GetNotifData()); + iNegotiation.DpdNotifyMessageReceivedL(Sa, aNotify->GetMsgType(), Sequence); + } +#ifdef _DEBUG + else DEBUG_LOG(_L("No ISAKMP SA found for DPD notify message")); +#endif // _DEBUG + } +#ifdef _DEBUG + else DEBUG_LOG(_L("Illegal SPI- or notify data length in DPD message")); +#endif // _DEBUG + + return EFalse; +} + +//Handles Delete Payload +TBool CIkev1InfoNegotiation::ProcessDeleteL(const TPayloadISAKMP *aPayload) +{ +TDeleteISAKMP *delete_payload = TDeleteISAKMP::Ptr(aPayload); + +#ifdef _DEBUG + TBuf<1200> msg; + DEBUG_LOG(_L("Delete Payload received!!!")); + delete_payload->String(msg); + DEBUG_LOG(msg); +#endif // _DEBUG + if (!iNegotiation.CheckDOI(delete_payload->DOI())) + { + DEBUG_LOG(_L("DOI_NOT_SUPPORTED in delete payload")); + return EFalse; + } + + TUint8 protocol = delete_payload->Protocol(); + TUint32 spi; + TInetAddr remote_addr(iNegotiation.iRemoteAddr); + remote_addr.SetPort(KInetPortAny); + + TInt err = KErrNone; + if ( protocol == PROTO_ISAKMP ) + { + iPluginSession.DeleteISAKMPSAsL( delete_payload, iNegotiation ); + } + else //IPSEC AH or ESP (others will be discarded by the kernel) + { + if (delete_payload->SPISize() != sizeof(TUint32)) + { + DEBUG_LOG(_L("Bad SPI Size for a IPsec SA. (SA Not deleted)")); + } + TIpsecSPI IpsecSpi; + for (TInt i=0; i < delete_payload->NumSPI(); i++) //Shouldn't be more than one + { + Mem::Copy((TUint8*)&spi, delete_payload->SPI(i),sizeof(TUint32)); + if (err == KErrNone) + { + //The right one is the Outbound(Local->Remote) one to avoid sending when deleted at the other side + //The opposite if sending a Delete + IpsecSpi.iSrcAddr = iNegotiation.iLocalAddr; + IpsecSpi.iDstAddr = remote_addr; + IpsecSpi.iSPI = spi; + IpsecSpi.iProtocol = protocol; + IpsecSpi.iInbound = EFalse; + if (iPluginSession.DeleteIpsecSpi(iNegotiation.SAId(), spi, EFalse)) + { + DEBUG_LOG(_L("Deleting IPsec SA")); + iPluginSession.DeleteIpsecSA(IpsecSpi.iSPI, IpsecSpi.iSrcAddr, IpsecSpi.iDstAddr, + IpsecSpi.iProtocol); + } + } + else + { + DEBUG_LOG1(_L("IPsec SA with SPI=%x not deleted"), ByteOrder::Swap32(spi)); + } + } + } + + return ETrue; +} diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1isakmpstream.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1isakmpstream.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,1373 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Stream class implementation for ISAKMP +* +*/ + + +#include "ikev1isakmpstream.h" +#include "ikemsgheader.h" +#include "ikev1negotiation.h" +#include "ikedebug.h" +#include "ikev1trans.h" +#include "ikecalist.h" +#include "ikecaelem.h" +#include "ikepolparser.h" +#include "ikev1crypto.h" +#include "ikev1pkiservice.h" +#include "ikev1private.h" +#include "ikepkiutils.h" +#include "ikev1natdiscovery.h" + +// +// TIkev1IsakmpStream +// + +TIkev1IsakmpStream::TIkev1IsakmpStream( MIkeDebug& aDebug ) + : iDebug( aDebug ) + { + } + +void TIkev1IsakmpStream::IsakmpInit(CIkev1Negotiation *aSession) +{ + ThdrISAKMP hdr; + + iError = EFalse; + iNegotiation = aSession; //stores it to avoid passing it for all the functions + DEBUG_LOG(_L("[HDR]")); + hdr.SetCookieI(iNegotiation->iCookie_I); + hdr.SetCookieR(iNegotiation->iCookie_R); + hdr.SetPayload(0); //Is set later through the pointer iNextPayload + hdr.SetVersion(0x10); //MAJOR=1 MINOR=0 + hdr.SetExchange(iNegotiation->iExchange); + hdr.SetFlags(iNegotiation->iFlags); + if ((iNegotiation->iExchange == ISAKMP_EXCHANGE_ID) || (iNegotiation->iExchange == ISAKMP_EXCHANGE_AGGR)) + hdr.SetMessageId(0); + else //QUICK mode ,INFORMATIONAL Mode or Transaction exchange + hdr.SetMessageId(iNegotiation->iMessageId); + + iBuf.SetLength(0); //Set correctly when sending SendL() + iBuf.Copy((TUint8 *)&hdr, sizeof(hdr)); //Always called the first so not Append + iNextPayload = (TUint8 *)(iBuf.Ptr() + 16); //saves the adress. + //Will be filled by the next called function +} + + +void TIkev1IsakmpStream::IsakmpSa() +{ + TSAISAKMP sa; + DEBUG_LOG(_L("[SA]")); + sa.SetPayload(0); //Not proposal or transform RFC. After reserved is already 0 + sa.SetDOI(iNegotiation->iDOI); //Always the same. Otherwise should be the one contained in CIkev1Negotiation + sa.SetSIT(IPSEC_SIT_IDENTITY_ONLY); //That means no Labeled Domain Identifier + + *iNextPayload = ISAKMP_PAYLOAD_SA; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address. + //Will be filled by the next called function + + TUint16 pos=(TUint16)iBuf.Length(); //save the position to know the total size later and insert it + iBuf.SetLength(pos + sizeof(sa)); //leave room to insert later the proposal + //including the SPI + IsakmpProposal(); + sa.SetLength((TUint16)(iBuf.Length() - pos)); + TBuf8 aux; + aux.Append((TUint8 *)&sa, sizeof(sa)); + iBuf.Replace(pos,aux.Length(),aux); + +} + +//SPI not included yet. +//Sends msg stage 2. Should be used for phase 2 as well +void TIkev1IsakmpStream::IsakmpProposal() +{ + TProposalISAKMP proposal; + TUint16 pos = 0; + TUint8 next_payload = ISAKMP_PAYLOAD_T; // default: more than one transform + + if (iNegotiation->iPhase == PHASE_I) + { + TProposal *prop; + + if (iNegotiation->iRole==INITIATOR) + { + prop=&iNegotiation->iProposal_I; + } + else + { + prop=&iNegotiation->iChosenProposal_I; + } + proposal.SetPayload(ISAKMP_PAYLOAD_NONE); //Only one proposal + proposal.SetNum(prop->iProposalNum); + proposal.SetProtocol(prop->iProtocol); + proposal.SetSPISize(0); + proposal.SetNumTrans(prop->iNumTransforms); + pos=(TUint16)iBuf.Length(); //save the position to insert later + //including the SPI + iBuf.SetLength(pos + sizeof(proposal)); //leave room to insert later the proposal + TAttrib *attr=prop->iAttrList; + for (TInt i=0; i < proposal.GetNumTrans(); i++) //Adds all the transforms + { + if ( !attr->iNext ) + next_payload = ISAKMP_PAYLOAD_NONE; // Last trasnform + IsakmpTransform((TUint8 *)attr, next_payload); + attr=attr->iNext; + } + proposal.SetLength((TUint16)(iBuf.Length() - pos)); + TBuf8 aux; + aux.Append((TUint8 *)&proposal, sizeof(proposal)); + //aux.Append(prop->iSPI); //insert the SPI + iBuf.Replace(pos,aux.Length(),aux); + return; + } + + //PHASE_II + TAttrib_II *attr_II=NULL; + CProposal_IIList *propII_List = NULL; + CProposal_II *propII = NULL; + TBuf8 SPI; + TInt i, index = 0; + TUint32 in_spi; + TUint8 num_transforms; + CArrayFixFlat *list = iNegotiation->iInboundSPIList; + + if (iNegotiation->iRole==INITIATOR) + propII_List = iNegotiation->iProposal_IIList; + else //RESPONDER + { + for (index = 0; index < list->Count(); index++) + { + if (list->At(index).iPropNum == iNegotiation->iProposalNum) + break; + } + propII_List = iNegotiation->iChosenProp_IIList; + } + + TInt count = propII_List->Count(); + + for (i = 0; i < count; i++) + { + propII = propII_List->At(i); + //Choose the correct SPI + if (iNegotiation->iRole==INITIATOR) + SPI = propII->iSPI; + else //RESPONDER + { + in_spi = list->At(index).iSPI; + SPI.Copy((TUint8 *)&in_spi, sizeof(TUint32)); + index++; + } + + if (i == count - 1) //Last proposal + proposal.SetPayload(ISAKMP_PAYLOAD_NONE); + else //There are more + proposal.SetPayload(ISAKMP_PAYLOAD_P); + + num_transforms = propII->iNumTransforms; + proposal.SetNum(propII->iProposalNum); + proposal.SetProtocol(propII->iProtocol); + proposal.SetNumTrans(num_transforms); + proposal.SetSPISize((TUint8)SPI.Length()); //The chosen contains the inbound SPI + pos=(TUint16)iBuf.Length(); //save the position to insert later + iBuf.SetLength(pos + sizeof(proposal) + proposal.GetSPISize()); //leave room to insert later the proposal + //including the SPI + for (TInt j = 0; j < num_transforms; j++) //Adds all the transforms + { + attr_II = propII->iAttrList->At(j); + if ( (num_transforms - j) == 1 ) + next_payload = ISAKMP_PAYLOAD_NONE; // Last trasnform + IsakmpTransform((TUint8 *)attr_II, next_payload); + } + proposal.SetLength((TUint16)(iBuf.Length() - pos)); + TBuf8 aux; + aux.Append((TUint8 *)&proposal, sizeof(proposal)); + aux.Append(SPI); //insert the SPI + iBuf.Replace(pos, aux.Length(), aux); + + } + +} + +//Transform data received as TUint8 to allow both TAttrib and TAttrib_II +void TIkev1IsakmpStream::IsakmpTransform(TUint8 *aTransform, TUint8 aNextPayload) +{ + TTransformISAKMP transf; + + //transf.SetNum(1);//SHOULD BE the selected transform but Linux doesn't let it use it!!! + if (iNegotiation->iPhase == PHASE_I) + { + TAttrib *attr=(TAttrib *)aTransform; + transf.SetNum(attr->iTransformNum); + transf.SetID(attr->iTransformID); + transf.SetPayload(aNextPayload); + } + else //PHASE_II + { + TAttrib_II *attr_II=(TAttrib_II *)aTransform; + transf.SetNum(attr_II->iTransformNum); + transf.SetID(attr_II->iTransformID); + transf.SetPayload(aNextPayload); + } + + TInt pos=iBuf.Length(); //save the position to insert later + iBuf.SetLength(pos + sizeof(transf)); //leave room to insert later + IsakmpAttrib(aTransform); + transf.SetLength((TUint16)(iBuf.Length() - pos)); + TBuf8 aux; + aux.Append((TUint8 *)&transf, sizeof(transf)); + iBuf.Replace(pos,aux.Length(),aux); +} + + +//Creates a data payload with the desired SA attributes. either Phase I or II +void TIkev1IsakmpStream::IsakmpAttrib(TUint8 *aTransform) +{ + if (iNegotiation->iPhase == PHASE_I) + IsakmpAttrib1((TAttrib *)aTransform); + else //PHASE_II + IsakmpAttrib2((TAttrib_II *)aTransform); +} + +//Phase_I attributes +void TIkev1IsakmpStream::IsakmpAttrib1(TAttrib *aTransform) +{ + TDataISAKMP attr; + TUint length; + TUint16 val; + TAttrib trans; + + trans=*aTransform; + + val=trans.iEncrAlg; + if (val != 0) + { + attr.SetBasic(ETrue); + attr.SetType(OAKLEY_ATTR_TYPE_ENCR_ALG); + attr.SetValue(val); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + } + + val=trans.iHashAlg; + if (val != 0) + { + attr.SetBasic(ETrue); + attr.SetType(OAKLEY_ATTR_TYPE_HASH_ALG); + attr.SetValue(val); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + } + + val=CTransNegotiation::GetAuthMethod(trans.iAuthMethod, trans.iXauthUsed, trans.iRole); + if (val != 0) + { + attr.SetBasic(ETrue); + attr.SetType(OAKLEY_ATTR_TYPE_AUTH_METH); + attr.SetValue(val); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + } + + val=trans.iGroupDesc; + if (val != 0) + { + attr.SetBasic(ETrue); + attr.SetType(OAKLEY_ATTR_TYPE_GROUP_DESC); + attr.SetValue(val); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + } + + val=trans.iGroupType; + if (val != 0) + { + attr.SetBasic(ETrue); + attr.SetType(OAKLEY_ATTR_TYPE_GROUP_TYPE); + attr.SetValue(val); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + } + + length=trans.iGroupPrime.Length(); + if (length!=0) + { + attr.SetBasic(EFalse); + attr.SetType(OAKLEY_ATTR_TYPE_GROUP_PRIME); + attr.SetLength((TUint16)(length)); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + iBuf.Append(trans.iGroupPrime); + } + + length=trans.iGroupGen1.Length(); + if (length!=0) + { + attr.SetBasic(EFalse); + attr.SetType(OAKLEY_ATTR_TYPE_GROUP_GEN1); + attr.SetLength((TUint16)(length)); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + iBuf.Append(trans.iGroupGen1); + } + + length=trans.iGroupGen2.Length(); + if (length!=0) + { + attr.SetBasic(EFalse); + attr.SetType(OAKLEY_ATTR_TYPE_GROUP_GEN2); + attr.SetLength((TUint16)(length)); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + iBuf.Append(trans.iGroupGen2); + } + + length=trans.iGroupCurveA.Length(); + if (length!=0) + { + attr.SetBasic(EFalse); + attr.SetType(OAKLEY_ATTR_TYPE_GROUP_CRVA); + attr.SetLength((TUint16)(length)); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + iBuf.Append(trans.iGroupCurveA); + } + + length=trans.iGroupCurveB.Length(); + if (length!=0) + { + attr.SetBasic(EFalse); + attr.SetType(OAKLEY_ATTR_TYPE_GROUP_CRVB); + attr.SetLength((TUint16)(length)); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + iBuf.Append(trans.iGroupCurveB); + } + + length=trans.iLifeDurationSecs.Length(); + if (length!=0) + { + attr.SetBasic(ETrue); + attr.SetType(OAKLEY_ATTR_TYPE_LIFE_TYPE); + attr.SetValue(SECONDS); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + + attr.SetBasic(EFalse); + attr.SetType(OAKLEY_ATTR_TYPE_LIFE_DUR); + attr.SetLength((TUint16)(length)); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + iBuf.Append(trans.iLifeDurationSecs); + + } + + length=trans.iLifeDurationKBytes.Length(); + if (length!=0) + { + attr.SetBasic(ETrue); + attr.SetType(OAKLEY_ATTR_TYPE_LIFE_TYPE); + attr.SetValue(KBYTES); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + + attr.SetBasic(EFalse); + attr.SetType(OAKLEY_ATTR_TYPE_LIFE_DUR); + attr.SetLength((TUint16)(length)); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + iBuf.Append(trans.iLifeDurationKBytes); + + } + + val=trans.iPRF; + if (val != 0) + { + attr.SetBasic(ETrue); + attr.SetType(OAKLEY_ATTR_TYPE_PRF); + attr.SetValue(val); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + } + + val=trans.iKeyLength; + if (val != 0) + { + attr.SetBasic(ETrue); + attr.SetType(OAKLEY_ATTR_TYPE_KEY_LEN); + attr.SetValue(val); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + } + + val=trans.iFieldSize; + if (val != 0) + { + attr.SetBasic(ETrue); + attr.SetType(OAKLEY_ATTR_TYPE_FIELD_SIZE); + attr.SetValue(val); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + } + + length=trans.iGroupOrder.Length(); + if (length!=0) + { + attr.SetBasic(EFalse); + attr.SetType(OAKLEY_ATTR_TYPE_GROUP_ORDER); + attr.SetLength((TUint16)(sizeof(attr)+length)); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + iBuf.Append(trans.iGroupOrder); + } +} + + +//Phase_II attributes +void TIkev1IsakmpStream::IsakmpAttrib2(TAttrib_II *aTransform) +{ + TDataISAKMP attr; + TUint length; + TUint16 val; + + TAttrib_II trans=*aTransform; + length=trans.iLifeDurationSecs.Length(); + if (length!=0) + { + attr.SetBasic(ETrue); + attr.SetType(DOI_ATTR_TYPE_LIFE_TYPE); + attr.SetValue(SECONDS); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + + attr.SetBasic(EFalse); + attr.SetType(DOI_ATTR_TYPE_LIFE_DUR); + attr.SetLength((TUint16)length); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + iBuf.Append(trans.iLifeDurationSecs.Ptr(),trans.iLifeDurationSecs.Length()); + + + } + + length=trans.iLifeDurationKBytes.Length(); + if (length!=0) + { + attr.SetBasic(ETrue); + attr.SetType(DOI_ATTR_TYPE_LIFE_TYPE); + attr.SetValue(KBYTES); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + + attr.SetBasic(EFalse); + attr.SetType(DOI_ATTR_TYPE_LIFE_DUR); + attr.SetLength((TUint16)length); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + iBuf.Append(trans.iLifeDurationKBytes.Ptr(),trans.iLifeDurationKBytes.Length()); + + } + + if (iNegotiation->iPFS) + { //Only sent if PFS in use. The same used in Phase I + val = trans.iGroupDesc; + if (val != 0) + { + attr.SetBasic(ETrue); + attr.SetType(DOI_ATTR_TYPE_GROUP_DESC); + attr.SetValue(val); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + } + } + + val=trans.iEncMode; + if (val != 0) + { + // + // If ESP UDP encapsulation required (because of NAT device in between) + // modify encapsulation type code values + // + if ( iNegotiation->iNAT_D_Flags ) { + if ( val == DOI_TUNNEL ) + val = UDP_ENC_TUNNEL; + else val = UDP_ENC_TRANSPORT; + } + attr.SetBasic(ETrue); + attr.SetType(DOI_ATTR_TYPE_ENC_MODE); + attr.SetValue(val); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + } + + val=trans.iAuthAlg; + if (val != 0) + { + attr.SetBasic(ETrue); + attr.SetType(DOI_ATTR_TYPE_AUTH_ALG); + attr.SetValue(val); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + } + + val=trans.iKeyLength; + if (val != 0) + { + attr.SetBasic(ETrue); + attr.SetType(DOI_ATTR_TYPE_KEY_LEN); + attr.SetValue(val); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + } + + val=trans.iKeyRounds; + if (val != 0) + { + attr.SetBasic(ETrue); + attr.SetType(DOI_ATTR_TYPE_KEY_ROUNDS); + attr.SetValue(val); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + } + + val=trans.iComprDicSize; + if (val != 0) + { + attr.SetBasic(ETrue); + attr.SetType(DOI_ATTR_TYPE_COMP_DIC_SIZE); + attr.SetValue(val); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + } + + length=trans.iComprPrivAlg.Length(); + if (length!=0) + { + attr.SetBasic(EFalse); + attr.SetType(DOI_ATTR_TYPE_COMP_PRIV_ALG); + attr.SetLength((TUint16)(length)); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + iBuf.Append(trans.iComprPrivAlg); + } + +} + + +//Adds the key payload to the buffer +void TIkev1IsakmpStream::IsakmpKeyL() +{ + TKeyISAKMP key_payload; + + if (!iNegotiation->ComputeDHPublicValueL()) //Computes the required key values. Needed to ComputeKeys + return; //No key payload generated + TPtrC8 key_ptr(iNegotiation->iOwnPublicKey_ptr); + TInt PadLth = 0; + TInt ModLth = iNegotiation->iOwnKeys->ModulusLength(); + if ( ModLth > key_ptr.Length() ) + { + PadLth = ModLth - key_ptr.Length(); + DEBUG_LOG(_L("[KE(filled)]")); + } + DEBUG_LOG(_L("[KE]")); + key_payload.SetLength((TUint16)(sizeof(key_payload) + ModLth)); + *iNextPayload = ISAKMP_PAYLOAD_KE; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address. + //Will be filled by the next called function + iBuf.Append((TUint8 *)&key_payload, sizeof(key_payload)); + if ( PadLth ) + { + TChar zero(0); + iBuf.AppendFill(zero, PadLth); //Fill prepending zero bits to DH public value + } + iBuf.Append(key_ptr); //variable size DH public value +} + +void TIkev1IsakmpStream::IsakmpOwnIdentL() +{ + IsakmpIdentL(ETrue); +} + +void TIkev1IsakmpStream::IsakmpPeerIdentL() +{ + IsakmpIdentL(EFalse); +} + +void TIkev1IsakmpStream::IsakmpIdentL(TBool aIsOwn) +{ + TIdentISAKMP id_payload; + + TBuf8<256> buf; //Max size for FQDN or DER ASN1 DN + // (buf should be allocated from heap !!) + TUint32 num; + const TUint8 *pnum; + + //DOI IPSEC + if (iNegotiation->iPhase == PHASE_I) + id_payload.SetProtocol(KProtocolInetUdp); + else + id_payload.SetProtocol(iNegotiation->iIDProtocol); //defined when receiving the acquire (INIT) or when receiveind the ID payload (RESP) + + if (aIsOwn) //Own ID! + { + if (iNegotiation->iPhase == PHASE_I) + { + DEBUG_LOG(_L("[IDi]")); + Isakmp_Phase1_IdL(buf, id_payload); + } + else //PHASE_II + { + DEBUG_LOG(_L("[IDci]")); + id_payload.SetIDType(iNegotiation->iLocalIDType_II); + + id_payload.SetPort(iNegotiation->iIDLocalPort); //defined when receiving the acquire (INIT) or when receiveind the ID payload (RESP) + + switch (iNegotiation->iLocalIDType_II) + { + case ID_IPV4_ADDR: + id_payload.SetLength((TUint16)(sizeof(id_payload) + sizeof(TUint32))); //IPV4 addr TInt32 + num = ByteOrder::Swap32(iNegotiation->iLocalAddr1_ID_II.Address());//Put in network order + pnum= (TUint8*)# + buf.Append(pnum,sizeof(TUint32)); + break; + case ID_IPV6_ADDR: + if (iNegotiation->iLocalAddr.IsV4Mapped()) + { + id_payload.SetLength((TUint16)(sizeof(id_payload) + sizeof(TUint32))); //IPV4 addr TInt32 + id_payload.SetIDType(ID_IPV4_ADDR); + num = ByteOrder::Swap32(iNegotiation->iLocalAddr.Address());//Put in network order + pnum= (TUint8*)# + buf.Append(pnum,sizeof(TUint32)); + } + else + { + id_payload.SetLength((TUint16)(sizeof(id_payload) + 16)); //IPV6 size is 16 + pnum = &iNegotiation->iLocalAddr1_ID_II.Ip6Address().u.iAddr8[0]; //Address in a bytestream + buf.Append(pnum, 16); + } + break; + case ID_IPV4_ADDR_SUBNET: + id_payload.SetLength((TUint16)(sizeof(id_payload) + 2*sizeof(TUint32))); //IPV4 addr TInt32 + num = ByteOrder::Swap32(iNegotiation->iLocalAddr1_ID_II.Address());//Put in network order + pnum= (TUint8*)# + buf.Append(pnum,sizeof(TUint32)); + num = ByteOrder::Swap32(iNegotiation->iLocalAddr2_ID_II.Address());//Put in network order + pnum= (TUint8*)# + buf.Append(pnum,sizeof(TUint32)); + break; + case ID_IPV6_ADDR_SUBNET: + id_payload.SetLength((TUint16)(sizeof(id_payload) + 32)); //one IPV6 addr size is 16 + pnum = &iNegotiation->iLocalAddr1_ID_II.Ip6Address().u.iAddr8[0]; //Address in a bytestream + buf.Append(pnum, 16); + pnum = &iNegotiation->iLocalAddr2_ID_II.Ip6Address().u.iAddr8[0]; //Address in a bytestream + buf.Append(pnum, 16); + break; + //No need for a default. Must be controlled way before when acquire or IDs received + } + } + } + else //Peer Id. + { + if (iNegotiation->iPhase == PHASE_I) + { + DEBUG_LOG(_L("[IDr]")); + Isakmp_Phase1_IdL(buf, id_payload); + } + else //PHASE_II + { + DEBUG_LOG(_L("[IDcr]")); + id_payload.SetIDType(iNegotiation->iRemoteIDType_II); + + id_payload.SetPort(iNegotiation->iIDRemotePort); //defined when receiving the acquire (INIT) or when receiving the ID payload (RESP) + + switch (iNegotiation->iRemoteIDType_II) + { + case ID_IPV4_ADDR: + id_payload.SetLength((TUint16)(sizeof(id_payload) + sizeof(TUint32))); //IPV4 addr TInt32 + num = ByteOrder::Swap32(iNegotiation->iRemoteAddr1_ID_II.Address());//Put in network order + pnum= (TUint8*)# + buf.Append(pnum,sizeof(TUint32)); + break; + case ID_IPV6_ADDR: + id_payload.SetLength((TUint16)(sizeof(id_payload) + 16)); //IPV6 size is 16 + pnum = &iNegotiation->iRemoteAddr1_ID_II.Ip6Address().u.iAddr8[0]; //Address in a bytestream + buf.Append(pnum, 16); + break; + case ID_IPV4_ADDR_SUBNET: + id_payload.SetLength((TUint16)(sizeof(id_payload) + 2*sizeof(TUint32))); //IPV4 addr TInt32 + num = ByteOrder::Swap32(iNegotiation->iRemoteAddr1_ID_II.Address());//Put in network order + pnum= (TUint8*)# + buf.Append(pnum,sizeof(TUint32)); + num = ByteOrder::Swap32(iNegotiation->iRemoteAddr2_ID_II.Address());//Put in network order + pnum= (TUint8*)# + buf.Append(pnum,sizeof(TUint32)); + break; + case ID_IPV6_ADDR_SUBNET: + id_payload.SetLength((TUint16)(sizeof(id_payload) + 32)); //one IPV6 addr size is 16 + pnum = &iNegotiation->iRemoteAddr1_ID_II.Ip6Address().u.iAddr8[0]; //Address in a bytestream + buf.Append(pnum, 16); + pnum = &iNegotiation->iRemoteAddr2_ID_II.Ip6Address().u.iAddr8[0]; //Address in a bytestream + buf.Append(pnum, 16); + break; + default: + DEBUG_LOG(_L("Bad Remote Phase_II ID type")); + iNegotiation->SetFinished(); + return; + //No need for a default. Must be controlled way before when acquire or IDs received + } + } + } + *iNextPayload = ISAKMP_PAYLOAD_ID; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the adress. + //Will be filled by the next called function + iBuf.Append((TUint8 *)&id_payload, sizeof(id_payload)); + iBuf.Append(buf); //variable size + + //stores the payload to be used in HASH_R/I computation (Only for phase I) + if ((iNegotiation->iPhase == PHASE_I) && (aIsOwn)) + { + TUint8 *p_ident=iNextPayload+sizeof(TPayloadISAKMP); //Data field + + iNegotiation->iOwnIdentPayloadSize=id_payload.GetLength()-sizeof(TPayloadISAKMP); //without the generic part! + + if (iNegotiation->iOwnIdentPayload) //in case it contains info + { + delete iNegotiation->iOwnIdentPayload; + iNegotiation->iOwnIdentPayload = NULL; + } + iNegotiation->iOwnIdentPayload = new (ELeave) TUint8[iNegotiation->iOwnIdentPayloadSize]; //Generic payload NOT included + Mem::Copy(iNegotiation->iOwnIdentPayload,p_ident,iNegotiation->iOwnIdentPayloadSize); + } + +} + +void TIkev1IsakmpStream::Isakmp_Phase1_IdL(TDes8& aIdData, TIdentISAKMP& aIdPayload) +{ + if ( iNegotiation->iNAT_D_Flags ) + aIdPayload.SetPort(0); + else aIdPayload.SetPort(IKE_PORT); + + TBool IdOk = EFalse; + TUint8 IdType = iNegotiation->iHostData->iIdType; + if (IdType == ID_USER_FQDN || IdType == ID_DER_ASN1_DN) + { + if (!iNegotiation->iOwnCert) //If not yet read + { + iNegotiation->ReadOwnCertL(); + } + } + if ( iNegotiation->iOwnCert && iNegotiation->iPkiService ) + { + // + // Priority 1 : Use IKE identity based on local certificate + // + TPtrC8 Cert(iNegotiation->iOwnCert->Des()); + HBufC8* CertIdBfr = IkePkiUtils::GetIdentityFromCertL(IdType, Cert); + if ( CertIdBfr ) + { + if ( CertIdBfr->Des().Length() <= aIdData.MaxLength() ) + { + aIdData.Copy(CertIdBfr->Des()); + if ( IdType == 0 ) + IdType = ID_DER_ASN1_DN; + IdOk = ETrue; + } + delete CertIdBfr; + } + } + + if ( !IdOk ) + { + // + // Priority 2 : Use identity defined in policy + // + TInt DataLength = iNegotiation->iHostData->iFQDN.Length(); + IdType = iNegotiation->iHostData->iIdType; + if ( ( DataLength > 0 ) && ( DataLength <= aIdData.MaxLength()) ) + { + if ( (IdType != ID_KEY_ID) && (IdType != ID_USER_FQDN) && (IdType != ID_FQDN) ) + IdType = ID_KEY_ID; + aIdData.Copy(iNegotiation->iHostData->iFQDN); + IdOk = ETrue; + } + } + + if ( !IdOk ) + { + // + // Priority 3 : Build local id from own IP address + // + TUint32 num; + const TUint8 *pnum; + if ((iNegotiation->iLocalAddr.Family() == KAfInet) || iNegotiation->iLocalAddr.IsV4Mapped() ) + { + IdType = ID_IPV4_ADDR; + num = ByteOrder::Swap32(iNegotiation->iLocalAddr.Address());//Put in network order + pnum = (TUint8*)# + aIdData.Copy(pnum, sizeof(TUint32)); + } + else + { + IdType = ID_IPV6_ADDR; + pnum = &iNegotiation->iLocalAddr.Ip6Address().u.iAddr8[0]; //Address in a bytestream + aIdData.Copy(pnum, 16); + } + } + + aIdPayload.SetLength((TUint16)(sizeof(aIdPayload) + aIdData.Length())); + aIdPayload.SetIDType(IdType); + +} + + + +void TIkev1IsakmpStream::IsakmpCertificateL() +{ + TCertificateISAKMP *cert; + + if (!iNegotiation->iSendCert) //Set by a received cert request or ourselves if initiator + return; + + if (!iNegotiation->iOwnCert) //If not yet read + { + if (!iNegotiation->ReadOwnCertL()) + { + iNegotiation->SetFinished(); + return; + } + } + DEBUG_LOG(_L("[CERT]")); + *iNextPayload = ISAKMP_PAYLOAD_CERT; //Fills the previous payload next field + cert = (TCertificateISAKMP*)(iBuf.Ptr() + iBuf.Length()); + iNextPayload = (TUint8 *)cert;//saves the adress.Will be filled by the next called function + + TPtr8 cert_ptr((TUint8 *)iBuf.Ptr() + iBuf.Length() + TCertificateISAKMP::Size(), 0, iBuf.MaxLength() - iBuf.Length()); //Pointer to the Cert. Data + + cert_ptr.Copy(iNegotiation->iOwnCert->Des()); + cert->SetReserved(0); + cert->SetLength((TUint16)(TCertificateISAKMP::Size() + cert_ptr.Size())); + cert->SetEncoding(iNegotiation->iEncoding); //If responder the same as initiator, otherwise any? (now only X509) + iBuf.SetLength(iBuf.Length() + TCertificateISAKMP::Size() + cert_ptr.Size()); //The new info just added + if ( iNegotiation->iICA2 ) + { + DEBUG_LOG(_L("[Level 2 INTERMEDIATE CERT]")); + *iNextPayload = ISAKMP_PAYLOAD_CERT; //Fills the previous payload next field + cert = (TCertificateISAKMP*)(iBuf.Ptr() + iBuf.Length()); + iNextPayload = (TUint8 *)cert;//saves the adress.Will be filled by the next called function + + TPtr8 cert_ptr((TUint8 *)iBuf.Ptr() + iBuf.Length() + TCertificateISAKMP::Size(), 0, iBuf.MaxLength() - iBuf.Length()); //Pointer to the Cert. Data + + cert_ptr.Copy(iNegotiation->iICA2->Des()); + cert->SetReserved(0); + cert->SetLength((TUint16)(TCertificateISAKMP::Size() + cert_ptr.Size())); + cert->SetEncoding(iNegotiation->iEncoding); //If responder the same as initiator, otherwise any? (now only X509) + iBuf.SetLength(iBuf.Length() + TCertificateISAKMP::Size() + cert_ptr.Size()); //The new info just added + } + if ( iNegotiation->iICA1 ) + { + DEBUG_LOG(_L("[Level 1 INTERMEDIATE CERT]")); + *iNextPayload = ISAKMP_PAYLOAD_CERT; //Fills the previous payload next field + cert = (TCertificateISAKMP*)(iBuf.Ptr() + iBuf.Length()); + iNextPayload = (TUint8 *)cert;//saves the adress.Will be filled by the next called function + + TPtr8 cert_ptr((TUint8 *)iBuf.Ptr() + iBuf.Length() + TCertificateISAKMP::Size(), 0, iBuf.MaxLength() - iBuf.Length()); //Pointer to the Cert. Data + + cert_ptr.Copy(iNegotiation->iICA1->Des()); + cert->SetReserved(0); + cert->SetLength((TUint16)(TCertificateISAKMP::Size() + cert_ptr.Size())); + cert->SetEncoding(iNegotiation->iEncoding); //If responder the same as initiator, otherwise any? (now only X509) + iBuf.SetLength(iBuf.Length() + TCertificateISAKMP::Size() + cert_ptr.Size()); //The new info just added + } +} + + +void TIkev1IsakmpStream::IsakmpCertificateReqL() +{ + if ( !iNegotiation->iPkiService || !iNegotiation->iPkiService->CaList()) + return; + CIkeCaList* CaList = iNegotiation->iPkiService->CaList(); + TCertificateReqISAKMP cert_req; + CX509Certificate *ca_cert; + TInt count = CaList->Count(); + TInt i = 0; + + while ( i < count ) { + + DEBUG_LOG(_L("[CR]")); + ca_cert = CaList->At(i)->Certificate(); + *iNextPayload = ISAKMP_PAYLOAD_CR; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address. Will be filled by the next called function + TPtr8 certreq_data_ptr((TUint8 *)iBuf.Ptr() + iBuf.Length() + TCertificateReqISAKMP::Size(), 0, iBuf.MaxLength() - iBuf.Length()); //Pointer to the CertReq. Data + IkePkiUtils::GetCertSubjectNameDERL(ca_cert, certreq_data_ptr); + cert_req.SetLength((TUint16)(TCertificateReqISAKMP::Size() + certreq_data_ptr.Size())); + cert_req.SetEncoding(iNegotiation->iEncoding); //If responder the same as initiator, otherwise any? (now only X509) + iBuf.Append((TUint8 *)&cert_req, TCertificateReqISAKMP::Size()); + iBuf.SetLength(iBuf.Length()+ certreq_data_ptr.Size()); + + i ++; + } + + iNegotiation->iCertRequested = ETrue; +} + + +void TIkev1IsakmpStream::IsakmpHashL() +{ + DEBUG_LOG(_L("[HASH]")); + THashISAKMP hash_payload; + TBuf8 hash; + TUint8 exchange = ThdrISAKMP::Ptr(iBuf)->GetExchange(); + switch (exchange) + { + case ISAKMP_EXCHANGE_ID: //Main mode + case ISAKMP_EXCHANGE_AGGR: //Main mode + *iNextPayload = ISAKMP_PAYLOAD_HASH; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the adress. + + if (iNegotiation->iRole==INITIATOR) + { + DEBUG_LOG(_L("[HASH_I]")); + iNegotiation->ComputeHash1L(hash); //Must be done after Isakmp_IDENT to have the correct Id payload + hash_payload.SetLength((TUint16)(hash.Length() + sizeof(THashISAKMP))); + iBuf.Append((TUint8 *)&hash_payload, sizeof(hash_payload)); + //iBuf.Append(iNegotiation->iHASH_I,iNegotiation->iHASH_ILen); + iBuf.Append(hash); + + } + else //RESP + { + DEBUG_LOG(_L("[HASH_R]")); + iNegotiation->ComputeHashrL(hash); //Must be done after Isakmp_IDENT to have the correct Id payload + hash_payload.SetLength((TUint16)(hash.Length() + sizeof(THashISAKMP))); + iBuf.Append((TUint8 *)&hash_payload, sizeof(hash_payload)); + //iBuf.Append(iNegotiation->iHASH_R,iNegotiation->iHASH_RLen); + iBuf.Append(hash); + } + break; + + case IKE_QUICK_MODE: + *iNextPayload = ISAKMP_PAYLOAD_HASH; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the adress. + switch (iNegotiation->iStage) + { + case 1://Require 2-stage hash payload construction + case 2: + case 4: + iHash_pos=iBuf.Length(); //Saves the pos to put the payload later in Isakmp_HASH_cont + //Leaves free space for the buffer + iBuf.SetLength(iBuf.Length() + sizeof(THashISAKMP) + iNegotiation->HashLength()); + break; + default: //stage 3 + DEBUG_LOG(_L("[HASH(3)]")); + iNegotiation->ComputeHash2L(hash, iNegotiation->iStage); + hash_payload.SetLength((TUint16)(hash.Length() + sizeof(THashISAKMP))); + iBuf.Append((TUint8 *)&hash_payload, sizeof(hash_payload)); + iBuf.Append(hash); //Puts the hash in the correct position. iHashPos fills by Isakmp_HASH() + } + break; + + case ISAKMP_EXCHANGE_INFO: + case ISAKMP_EXCHANGE_TRANSACT: + *iNextPayload = ISAKMP_PAYLOAD_HASH; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address. + iHash_pos = iBuf.Length(); //Saves the pos to put the payload later in Isakmp_HASH_cont + //Leaves free space for the buffer + iBuf.SetLength(iBuf.Length() + sizeof(THashISAKMP) + iNegotiation->HashLength()); + break; + + default: + DEBUG_LOG(_L("ISAKMP_HASH payload build error")); + iNegotiation->SetFinished(); + } +} + +//Insert the hash in the designed position. Only Phase_II stage 1 or 2 +void TIkev1IsakmpStream::IsakmpHashContL() +{ + THashISAKMP hash; + TBuf8 tmp_hash; + + //to put the correct next_payload value we check in the buffer because the next + //payload will have updated the value there + THashISAKMP *fake_hdr=(THashISAKMP *)(iBuf.Ptr() + iHash_pos); + hash.SetPayload(fake_hdr->GetPayload()); + TInt hash_len=sizeof(THashISAKMP) + iNegotiation->HashLength(); + hash.SetLength((TUint16)hash_len); + tmp_hash.Copy((TUint8 *)&hash,sizeof(hash)); + iBuf.Replace(iHash_pos, tmp_hash.Length(),tmp_hash); + iHash_pos += tmp_hash.Length(); + + TUint8 *hashMsg=((TUint8 *)iBuf.Ptr() + sizeof(ThdrISAKMP) + hash_len); //Msg to hash + TInt hashMsgLen= iBuf.Length()- sizeof(ThdrISAKMP) - hash_len; + switch (iNegotiation->iExchange) + { + case IKE_QUICK_MODE: + if (iNegotiation->iStage != 4) + iNegotiation->ComputeHash2L(tmp_hash, iNegotiation->iStage, hashMsg, hashMsgLen); + else //Send CONNECT message is informational although in Quick mode + iNegotiation->ComputeHashInfL(tmp_hash, hashMsg, hashMsgLen); + break; + case ISAKMP_EXCHANGE_INFO: + case ISAKMP_EXCHANGE_TRANSACT: + iNegotiation->ComputeHashInfL(tmp_hash, hashMsg, hashMsgLen); + break; + default: + DEBUG_LOG(_L("ISAKMP_HASH_contL")); + iNegotiation->SetFinished(); + } + iBuf.Replace(iHash_pos,tmp_hash.Length(),tmp_hash); //Puts the hash in the correct position. iHashPos fills by Isakmp_HASH() +} + +void TIkev1IsakmpStream::IsakmpSignatureL() +{ + TSignatureISAKMP sig; + TBuf8 hash; + + DEBUG_LOG(_L("[SIG]")); + if ( !iNegotiation->iPkiService ) + return; + + //DSS only allows SHA1 as hash + TUint16 tmp = iNegotiation->iChosenProposal_I.iAttrList->iHashAlg; //save the value to compute the hash with SHA1 if using DSS + + //First computes hash + if (iNegotiation->iRole==INITIATOR) + { + iNegotiation->ComputeHash1L(hash); //Must be done after Isakmp_IDENT to have the correct Id payload + } + else + { + iNegotiation->ComputeHashrL(hash); //Must be done after Isakmp_IDENT to have the correct Id payload + } + iNegotiation->iChosenProposal_I.iAttrList->iHashAlg = tmp; //Restore the value after computing the hash + + *iNextPayload = ISAKMP_PAYLOAD_SIG; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address. + //Will be filled by the next called function + TSignatureISAKMP *p_sig=(TSignatureISAKMP *)(iBuf.Ptr() + iBuf.Length()); //To update the payload size later + iBuf.Append((TUint8 *)&sig, sizeof(sig)); + + TPtr8 sig_data_ptr((TUint8 *)(iBuf.Ptr() + iBuf.Length()), iBuf.MaxLength() - iBuf.Length()); + + DEBUG_LOG1(_L("sig_data_ptr length=%d"), sig_data_ptr.Length()); + if ( iNegotiation->iPkiService->Ikev1SignatureL(iNegotiation->iPeerTrustedCA->Des(), + iNegotiation->iHostData, + hash, sig_data_ptr) == 0 ) + { + DEBUG_LOG(_L("Signature Computation failed!")); + } + + DEBUG_LOG(_L("Signature")); + iBuf.SetLength(iBuf.Length() + sig_data_ptr.Length()); //updates the buffer size + p_sig->SetLength((TUint16)(sizeof(sig) + sig_data_ptr.Length())); //Puts the correct length in the buffer +} + +//Adds the Nonce payload to the buffer +void TIkev1IsakmpStream::IsakmpNonce() +{ + TNonceISAKMP nonce_payload; + + //iNegotiation->ComputeNonce(); //Nonce to be sent + nonce_payload.SetLength((TUint16)(sizeof(nonce_payload) + OAKLEY_DEFAULT_NONCE_SIZE)); + *iNextPayload = ISAKMP_PAYLOAD_NONCE; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address. + //Will be filled by the next called function + iBuf.Append((TUint8 *)&nonce_payload, sizeof(nonce_payload)); + if (iNegotiation->iRole==INITIATOR) + { + DEBUG_LOG(_L("[NONCE_I]")); + iBuf.Append(iNegotiation->iNONCE_I); //variable size + } + else + { + DEBUG_LOG(_L("[NONCE_R]")); + iBuf.Append(iNegotiation->iNONCE_R); //variable size + } + +} + +//Adds the Notification payload to the buffer +void TIkev1IsakmpStream::IsakmpNotification(TUint16 aType, TUint8 aProtocol, TUint8* aNotifData, TInt aDataLth) +{ + TNotificationISAKMP notif; + + TBuf8<2*ISAKMP_COOKIE_SIZE> spi; + + spi.Copy(iNegotiation->iCookie_I); + spi.Append(iNegotiation->iCookie_R); + + DEBUG_LOG(_L("[NOT]")); + *iNextPayload = ISAKMP_PAYLOAD_NOTIF; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address. + TUint16 length = (TUint16)(sizeof(notif) + spi.Length() + aDataLth); + + notif.SetLength(length); + notif.SetDOI(iNegotiation->iDOI); + notif.SetProtocol(aProtocol); + notif.SetSPISize((TUint8)spi.Length()); + notif.SetMsgType(aType); + //Will be filled by the next called function + iBuf.Append((TUint8 *)¬if, sizeof(notif)); //Header + iBuf.Append(spi); //insert the SPI + + if ( aNotifData && aDataLth ) + iBuf.Append(aNotifData, aDataLth); //Add Notification data + +} + +//Adds the Notification payload to the buffer +void TIkev1IsakmpStream::IsakmpReplayStatus(TUint8 aProtocol, TUint32 aSPI, TUint8 aReplayWindowLength) +{ + TNotificationISAKMP notif; + TUint32 data; + + DEBUG_LOG(_L("[NOT]")); + *iNextPayload = ISAKMP_PAYLOAD_NOTIF; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address. + notif.SetLength((TUint16)(sizeof(notif) + sizeof(aSPI) + sizeof(data))); //No Notification Data yet!!! + notif.SetDOI(iNegotiation->iDOI); + notif.SetProtocol(aProtocol); + notif.SetSPISize(sizeof(aSPI)); //No SPI sent + notif.SetMsgType(DOI_REPLAY_STATUS); + //Will be filled by the next called function + iBuf.Append((TUint8 *)¬if, sizeof(notif)); //Header + iBuf.Append((TUint8 *)&aSPI, sizeof(aSPI)); //Insert the SPI + + // Notification Data: 0 if replay detection disabled + // 1 if replay detection enabled + + if (aReplayWindowLength > 0) + data = ByteOrder::Swap32(1); + else + data = 0; + iBuf.Append((TUint8 *)&data, sizeof(data)); + +} + +//Adds the Notification payload to the buffer +void TIkev1IsakmpStream::IsakmpResponderLifetime(TUint8 aProtocol, TUint32 aSPI, const TDesC8 &aLifetime, const TDesC8 &aLifesize) +{ + TNotificationISAKMP notif; + TDataISAKMP attr; + + DEBUG_LOG(_L("[NOT]")); + *iNextPayload = ISAKMP_PAYLOAD_NOTIF; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address. + + //Notification payload + spi + attribs lifetype and life value + TInt attrlen = 0; + if (aLifetime.Length() > 0) + attrlen = 2*sizeof(attr) + aLifetime.Length(); + if (aLifesize.Length() > 0) + attrlen += 2*sizeof(attr) + aLifesize.Length(); + if (attrlen == 0) //No lifevalues to send + return; + + notif.SetLength((TUint16)(sizeof(notif) + sizeof(aSPI) + attrlen)); + notif.SetDOI(iNegotiation->iDOI); + notif.SetProtocol(aProtocol); + notif.SetSPISize(sizeof(aSPI)); //No SPI sent + notif.SetMsgType(DOI_RESPONDER_LIFETIME); + //Will be filled by the next called function + iBuf.Append((TUint8 *)¬if, sizeof(notif)); //Header + iBuf.Append((TUint8 *)&aSPI, sizeof(aSPI)); //Insert the SPI + + //Lifetime + if (aLifetime.Length() > 0) + { + //LifeType + attr.SetBasic(ETrue); + attr.SetType(DOI_ATTR_TYPE_LIFE_TYPE); + attr.SetValue(SECONDS); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + + //Life Value + attr.SetBasic(EFalse); + attr.SetType(DOI_ATTR_TYPE_LIFE_DUR); + attr.SetLength((TUint16)(aLifetime.Length())); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + iBuf.Append(aLifetime); + } + + //Lifesize + if (aLifesize.Length() > 0) + { + //LifeType + attr.SetBasic(ETrue); + attr.SetType(OAKLEY_ATTR_TYPE_LIFE_TYPE); + attr.SetValue(KBYTES); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + + //Life Value + attr.SetBasic(EFalse); + attr.SetType(OAKLEY_ATTR_TYPE_LIFE_DUR); + attr.SetLength((TUint16)(aLifesize.Length())); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + iBuf.Append(aLifesize); + } +} + + +//Only send 1 SPI for the ISAKMP SA, AH or ESP +void TIkev1IsakmpStream::IsakmpDelete(TDesC8 &aSPI, TUint8 aProtocol) +{ + TDeleteISAKMP delete_payload; + + DEBUG_LOG(_L("[DEL]")); + + *iNextPayload = ISAKMP_PAYLOAD_D; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address. + + delete_payload.SetLength((TUint16)(sizeof(delete_payload) + aSPI.Length())); //No Notification Data yet!!! + delete_payload.SetDOI(iNegotiation->iDOI); + delete_payload.SetProtocol(aProtocol); + delete_payload.SetSPISize((TUint8)aSPI.Length()); + delete_payload.SetNumSPI(1); + + iBuf.Append((TUint8 *)&delete_payload, sizeof(delete_payload)); //Header + iBuf.Append(aSPI); //insert the SPI +} + +//Adds the Vendor ID payload to the buffer +void TIkev1IsakmpStream::IsakmpVendorId(TInt aID_Type, + TUint8 *aICOOKIE, + TUint8 *aRCOOKIE, + TInetAddr &aLocalAddr, + TUint8 *aGenericVidData, TInt aGenericVidLth ) +{ + + *iNextPayload = ISAKMP_PAYLOAD_VID; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length()); + + if ( (aID_Type == IETF_NATT_VENDOR_ID || aID_Type == IETF_RFC_NATT_VENDOR_ID) && aGenericVidData ) { + TVendorISAKMP vendor_payload; + vendor_payload.SetLength((TUint16)(sizeof(vendor_payload) + aGenericVidLth)); + iBuf.Append((TUint8 *)&vendor_payload, sizeof(vendor_payload)); //Header + iBuf.Append(aGenericVidData, aGenericVidLth); //Data + return; + } +/*-------------------------------------------------------- + * + * If an expanded Vendor Id required build it, otherwise + * use "old" style" short Vendor Id, + * + *--------------------------------------------------------*/ + TBool ExpandedVID; + + if ( aID_Type == EXPANDED_VENDOR_ID ) + ExpandedVID = ETrue; + else ExpandedVID = EFalse; + + TInt payload_lth = ConstructVendorId(ExpandedVID, + aICOOKIE, + aRCOOKIE, + aLocalAddr, + (TVendorISAKMP*)iNextPayload); + iBuf.SetLength(iBuf.Length() + payload_lth); //The new info just added + +} + + +void TIkev1IsakmpStream::IsakmpChre(TUint16 aLAMType, TUint16 aAttr1, HBufC8 *aBfr1, + TUint16 aAttr2, HBufC8 *aBfr2, TUint16 aAttr3, HBufC8 *aBfr3) +{ + TCHREISAKMP chre_payload; + + DEBUG_LOG(_L("[CHRE]")); + + *iNextPayload = ISAKMP_PAYLOAD_CHRE; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address. + /*---------------------------------------------------- + * Fill generic payload header fields (except length) + *----------------------------------------------------*/ + chre_payload.SetLAMtype(aLAMType); + chre_payload.SetCHREReserved(); + TInt pos = iBuf.Length(); //save the position to insert later + iBuf.SetLength(pos + sizeof(chre_payload)); //leave room to insert later + + /*---------------------------------------------------- + * Store CHRE payload attribute data + *----------------------------------------------------*/ + if ( aAttr1 !=0 ) + IsakmpChreAttrib(aAttr1, aBfr1); + if ( aAttr2 !=0 ) + IsakmpChreAttrib(aAttr2, aBfr2); + if ( aAttr3 !=0 ) + IsakmpChreAttrib(aAttr3, aBfr3); + /*---------------------------------------------------- + * Store correct payload length + *----------------------------------------------------*/ + chre_payload.SetLength((TUint16)(iBuf.Length() - pos)); + TBuf8 aux; + aux.Append((TUint8 *)&chre_payload, sizeof(chre_payload)); + iBuf.Replace(pos, aux.Length(), aux); +} + +void TIkev1IsakmpStream::IsakmpChreAttrib(TUint16 aType, HBufC8 *aBfr) +{ + /*---------------------------------------------------- + * Store CHRE payload attribute data (variable length) + *----------------------------------------------------*/ + TDataISAKMP attr; + TUint length; + attr.SetBasic(EFalse); + attr.SetType(aType); + if ( aBfr ) + length = aBfr->Length(); + else length = 0; + attr.SetLength((TUint16)length); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + if ( length ) + iBuf.Append(aBfr->Ptr(),length); +} + + +void TIkev1IsakmpStream::IsakmpIntnet(TUint32 aIpv4Addr) +{ + /*---------------------------------------------------------- + * Build inititor (=client) private Internal Address payload + * Payload contains only PRI_INTERNAL_ADDRESS attribute coded + * as a basic attribute with value 0. + *---------------------------------------------------------*/ + TINTNETISAKMP intnet_payload; + TDataISAKMP attr; + + DEBUG_LOG(_L("[IA]")); + + *iNextPayload = ISAKMP_INT_NETWORK; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address. + + intnet_payload.SetLength((TUint16)(sizeof(intnet_payload) + + (2 + 2))); //basic attribute + iBuf.Append((TUint8 *)&intnet_payload, + sizeof(intnet_payload)); //Payload Header + attr.SetBasic(ETrue); + attr.SetType(PRI_INTERNAL_ADDRESS); + attr.SetValue((TUint16)aIpv4Addr); + iBuf.Append((TUint8 *)&attr, sizeof(attr)); + +} + +void TIkev1IsakmpStream::IsakmpNatD(TBool aRfcNatt, TDesC8 &aHash) +{ + /*------------------------------------------------------------ + * Build NAT-D related to NAT discovery. + * Payload data is a hash data defined as follows: + * HASH = HASH(CKY-I | CKY-R | IP | Port) + * using the negotiated HASH algorithm + *---------------------------------------------------------*/ + TNATDISAKMP nat_d_payload; + + DEBUG_LOG(_L("[NAT_D]")); + + if ( aRfcNatt ) + *iNextPayload = IETF_RFC_NAT_DISCOVERY; //Fills the previous payload next field + else + *iNextPayload = IETF_NAT_DISCOVERY; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address. + + nat_d_payload.SetLength((TUint16)(sizeof(nat_d_payload) + aHash.Length())); + iBuf.Append((TUint8 *)&nat_d_payload, sizeof(nat_d_payload)); //Header + iBuf.Append(aHash); //Data + +} + +void TIkev1IsakmpStream::IsakmpAttributes(TUint8 aMsgType, TUint16 aIdentifier, TDesC8 &aAttributes) +{ + /*------------------------------------------------------------ + * Build Attributes payload. (used with config-mode and XAUTH) + *---------------------------------------------------------*/ + TAttributeISAKMP attr_payload; + attr_payload.SetCfgMsgType(aMsgType); + attr_payload.SetReservedField(); + attr_payload.SetIdentifier(aIdentifier); + + DEBUG_LOG(_L("[ATTR]")); + + *iNextPayload = ISAKMP_PAYLOAD_ATTRIBUTES; //Fills the previous payload next field + iNextPayload = (TUint8 *)(iBuf.Ptr() + iBuf.Length());//saves the address. + + attr_payload.SetLength((TUint16)(sizeof(attr_payload) + aAttributes.Length())); + iBuf.Append((TUint8 *)&attr_payload, sizeof(attr_payload)); //Header + iBuf.Append(aAttributes); //Data +} diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1keepalive.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1keepalive.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,189 @@ +/* +* Copyright (c) 2003-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv1 keep alive object +* +*/ + + +#include +#include +#include +#include "ikedebug.h" +#include "ikev1keepalive.h" +#include "ikev1pluginsession.h" + +_LIT8(KMsgContent, "\xff"); + +CIkeV1KeepAlive* CIkeV1KeepAlive::NewL( CIkev1PluginSession& aPluginSession, + TInt aPort, + TInetAddr& aDestAddr, + TInt NatKeepAlive, + TInt DpdKeepAlive, + MDpdHeartBeatEventHandler* aHandler, + TUint8 aDscp ) + { + CIkeV1KeepAlive* self = new (ELeave) CIkeV1KeepAlive( aPluginSession, + aPort, + aDestAddr, + NatKeepAlive, + DpdKeepAlive, + aHandler, + aDscp ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + + +CIkeV1KeepAlive::CIkeV1KeepAlive( CIkev1PluginSession& aPluginSession, + TInt aPort, + TInetAddr& aDestAddr, + TInt aNatKeepAlive, + TInt aDpdKeepAlive, + MDpdHeartBeatEventHandler* aHandler, + TUint8 aDscp ) + : CTimer( EPriorityStandard ), + iPluginSession( aPluginSession ), + iPort( aPort ), + iMsg( KMsgContent ) + { + iDestAddr = aDestAddr; + iNatKeepAlive = aNatKeepAlive; + iDpdKeepAlive = aDpdKeepAlive; + iCallback = aHandler; + iDscp = aDscp; + CActiveScheduler::Add( this ); + } + +//Destructor +CIkeV1KeepAlive::~CIkeV1KeepAlive() + { + Cancel(); + } + + +void CIkeV1KeepAlive::ConstructL() + { + // + // If NAT keepalive timoeut allocate (and initialize) a TIkeXmitBfr data buffer for + // NAT keepalive. Allocate a data buffer for special "Echo request" + // keepalive message, if proprietary "Nokia NAT Traversal is used". + // Start keep alive timer + // + CTimer::ConstructL(); + + if ( (iNatKeepAlive >= iDpdKeepAlive) && (iDpdKeepAlive != 0) && iCallback ) + iNatKeepAlive = 0; // Not needed + + if ( iNatKeepAlive ) + { + iDestAddr.SetPort(iPort); + + iRemainingTime = iNatKeepAlive; + if ( iCallback ) + iCurrDPDTimeLeft = iDpdKeepAlive - iNatKeepAlive; + else iDpdKeepAlive = 0; + } + else + { + iRemainingTime = iDpdKeepAlive; + } + + StartTimer(); + } + + +void CIkeV1KeepAlive::DoCancel() + { + CTimer::DoCancel(); + } + +void CIkeV1KeepAlive::RunL() + { + if ( iRemainingTime == 0 ) + { + TBool DpdEvent = EFalse; + if ( iDpdKeepAlive ) + { + if ( ( iCurrDPDTimeLeft == 0 ) && iCallback ) + { + // + // Call DPD event handler + // + DpdEvent = ETrue; + iCallback->EventHandlerL(); + iRemainingTime = iDpdKeepAlive; + } + } + + if ( iNatKeepAlive ) + { + // + // Send a NAT keepalive message(s) + // + if ( !DpdEvent ) + { + iPluginSession.SendNatKeepAliveL( iDestAddr, + iMsg, + iDscp ); + } + + iRemainingTime = iNatKeepAlive; + + if ( iDpdKeepAlive ) + { + if ( DpdEvent ) + { + iCurrDPDTimeLeft = iDpdKeepAlive - iNatKeepAlive; + } + else + { + if ( iCurrDPDTimeLeft < iNatKeepAlive ) + { + iRemainingTime = iCurrDPDTimeLeft; + iCurrDPDTimeLeft = 0; + } + else iCurrDPDTimeLeft -= iNatKeepAlive; + } + } + } + } + + StartTimer(); + } + +TInt CIkeV1KeepAlive::RunError(TInt /*aError*/) + { + return KErrNone; + } + +void CIkeV1KeepAlive::StartTimer() + { + if ( iRemainingTime > KMaxTInt/1000000 ) //To avoid overflowing the Timer + { + iRemainingTime -= KMaxTInt/1000000; + After(KMaxTInt); + } + else //No overflow + { + if ( iRemainingTime ) + { + After(iRemainingTime*1000000); + } + iRemainingTime = 0; + } + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1natdiscovery.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1natdiscovery.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,355 @@ +/* +* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Negotiation of NAT-Traversal in the IKE +* +*/ + + +#include "ikev1natdiscovery.h" +#include "ikev1crypto.h" +#include "ikev1negotiation.h" +#include "ikev1isakmpstream.h" + +// "03" version hash data +//const TUint8 IETF_NATT_VID_DATA[16] = {0x7d, 0x94, 0x19, 0xa6, 0x53, 0x10, 0xca, 0x6f, +// 0x2c, 0x17, 0x9d, 0x92, 0x15, 0x52, 0x9d, 0x56}; +_LIT8(KIetfNatTHashSeed,"draft-ietf-ipsec-nat-t-ike-03"); +_LIT8(KIetfRfcNatTHashSeed,"RFC 3947"); + +CIkev1NatDiscovery* CIkev1NatDiscovery::NewL(TUint32 aNatFlags) +{ + CIkev1NatDiscovery* NatDiscovery = new (ELeave)CIkev1NatDiscovery(); + + if ( aNatFlags ) + { + NatDiscovery->iSupport = ETrue; // Caller forces support indicator to OK + NatDiscovery->iRfcSupport= ETrue; + } + else + { + NatDiscovery->iSupport = EFalse; + NatDiscovery->iRfcSupport= EFalse; + } + + + // + // Build Vendor string for NAT discovery. This string is used later in + // a ISAKMP phase 1 Vendor Id payload to inform remote host that local + // end supprts NAT Traversal. + // The vendor string is produced as the following hash: + // Vendor Id string = MD5("draft-ietf-ipsec-nat-t-ike-03") + // + MD5HashL(KIetfNatTHashSeed, NatDiscovery->iIetfNattVidHash); // Calculate hash value + MD5HashL(KIetfRfcNatTHashSeed, NatDiscovery->iIetfRfcNattVidHash); // Calculate hash value + + return NatDiscovery; +} + +void CIkev1NatDiscovery::BuildNatVendorId(TIkev1IsakmpStream &aMsg) +{ +/**--------------------------------------------------------------------------------------- + * + * This method builds a NAT traversal related Vendor ID payload and adds it into + * the IKE message. The vendor id content is the following: + * MD5 hash of "draft-ietf-ipsec-nat-t-ike-05" (calculated earlier in NewL()) + * + *---------------------------------------------------------------------------------------*/ + TInetAddr DummyAddr; + + aMsg.IsakmpVendorId(IETF_NATT_VENDOR_ID, + NULL, NULL, DummyAddr, // These parameters has no relevance with IETF_NATT_VID_DATA + (TUint8*)iIetfNattVidHash.Ptr(), iIetfNattVidHash.Length()); + + +} + +void CIkev1NatDiscovery::BuildRfcNatVendorId(TIkev1IsakmpStream &aMsg) +{ +/**--------------------------------------------------------------------------------------- + * + * This method builds a NAT traversal related Vendor ID payload and adds it into + * the IKE message. The vendor id content is the following: + * MD5 hash of "RFC 3947" (calculated earlier in NewL()) + * + *---------------------------------------------------------------------------------------*/ + TInetAddr DummyAddr; + + aMsg.IsakmpVendorId(IETF_RFC_NATT_VENDOR_ID, + NULL, NULL, DummyAddr, // These parameters has no relevance with IETF_NATT_VID_DATA + (TUint8*)iIetfRfcNattVidHash.Ptr(), iIetfRfcNattVidHash.Length()); + + +} + +TBool CIkev1NatDiscovery::CheckNatVendorId(const TVendorISAKMP *aVendorPayload) +{ +/**--------------------------------------------------------------------------------------- + * + * This method checks does the remote end support IETF NAT traversal + * The vendor id content MUST be the following: + * + *---------------------------------------------------------------------------------------*/ + TInt vid_lth = aVendorPayload->GetLength() - sizeof(TPayloadISAKMP); + if ( vid_lth == iIetfNattVidHash.Length() ) { + if ( Mem::Compare(aVendorPayload->VIDData(), vid_lth, iIetfNattVidHash.Ptr(), vid_lth) == 0 ) { + iSupport = ETrue; // Remote end supports IETF NAT traversal + } + } + + return iSupport; + +} + +TBool CIkev1NatDiscovery::CheckRfcNatVendorId(const TVendorISAKMP *aVendorPayload) +{ +/**--------------------------------------------------------------------------------------- + * + * This method checks does the remote end support IETF NAT traversal RFC 3947 + * The vendor id content MUST be the following: + * + *---------------------------------------------------------------------------------------*/ + TInt vid_lth = aVendorPayload->GetLength() - sizeof(TPayloadISAKMP); + if ( vid_lth == iIetfRfcNattVidHash.Length() ) { + if ( Mem::Compare(aVendorPayload->VIDData(), vid_lth, iIetfRfcNattVidHash.Ptr(), vid_lth) == 0 ) { + //iSupport = ETrue; // Remote end supports IETF NAT traversal according to IETF draft 03 + iRfcSupport= ETrue; // Remote end supports IETF NAT traversal according to RFC 3947 + } + } + return iRfcSupport; +} + + +void CIkev1NatDiscovery::BuildDiscoveryPayloadsL(TIkev1IsakmpStream &aMsg, TUint16 aHashType, + TUint8 *aICOOKIE, TUint8 *aRCOOKIE, + TInetAddr &aLocalAddr, TInetAddr &aRemoteAddr) +{ +/**--------------------------------------------------------------------------------------- + * + * This builds NAT Discovery payloads for negotiation. + * from draft-ietf-ipsec-nat-t-ike-03; + * " + * The purpose of the NAT-D payload is twofold, It not only detects the + * presence of NAT between two IKE peers, it also detects where the NAT is. + * The location of the NAT device is important in that the keepalives need + * to initiate from the peer "behind" the NAT. + * + * To detect the NAT between the two hosts, we need to detect if the IP + * address or the port changes along the path. This is done by sending the + * hashes of IP address and port of both source and destination addresses + * from each end to another. When both ends calculate those hashes and get + * same result they know there is no NAT between. If the hashes do not + * match, somebody translated the address or port between, meaning we need + * to do NAT-Traversal to get IPsec packet through. + * + * If the sender of the packet does not know his own IP address (in case of + * multiple interfaces, and implementation don't know which is used to + * route the packet out), he can include multiple local hashes to the + * packet (as separate NAT-D payloads). In this case the NAT is detected if + * and only if none of the hashes match. + * + * The hashes are sent as a series of NAT-D (NAT discovery) payloads. Each + * payload contains one hash, so in case of multiple hashes, multiple NAT-D + * payloads are sent. In normal case there is only two NAT-D payloads. + * + * The format of the NAT-D packet is + * + * 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 + * +---------------+---------------+---------------+---------------+ + * | Next Payload | RESERVED | Payload length | + * +---------------+---------------+---------------+---------------+ + * ~ HASH of the address and port ~ + * +---------------+---------------+---------------+---------------+ + * + * The payload type for the NAT discovery payload is 130 (XXX CHANGE). + * + * The HASH is calculated as follows: + * + * HASH = HASH(CKY-I | CKY-R | IP | Port) + * + * using the negotiated HASH algorithm. All data inside the HASH is in the + * network byte-order. The IP is 4 octets for the IPv4 address and 16 + * octets for the IPv6 address. The port number is encoded as 2 octet + * number in network byte-order. The first NAT-D payload contains the + * remote ends IP address and port (i.e the destination address of the UDP + * packet). The rest of the NAT-D payloads contain possible local end IP + * addresses and ports (i.e all possible source addresses of the UDP packet)." + * + *---------------------------------------------------------------------------------------*/ + if ( iSupport || iRfcSupport) { + CalculateAddrPortHashL(aHashType, aICOOKIE, aRCOOKIE, aLocalAddr, aRemoteAddr); + + aMsg.IsakmpNatD(iRfcSupport, iRemoteAddrPortHash); // NAT-D payload with HASH(CKY-I | CKY-R | Remote_IP | Remote_Port) + aMsg.IsakmpNatD(iRfcSupport, iLocalAddrPortHash); // NAT-D payload with HASH(CKY-I | CKY-R | Local_IP | Local_Port) + } +} + +TUint32 CIkev1NatDiscovery::CheckDiscoveryPayloadsL(const CArrayFixFlat *aNatDPayloadArray, + TUint16 aHashType, TUint8 *aICOOKIE, TUint8 *aRCOOKIE, + TInetAddr &aLocalAddr, TInetAddr &aRemoteAddr) +{ +/**--------------------------------------------------------------------------------------- + * + * This check NAT Discovery payloads received from remote end. + * from draft-ietf-ipsec-nat-t-ike-03; + * " + * If there is no NAT between then the first NAT-D payload should match one + * of the local NAT-D packet (i.e the local NAT-D payloads this host is + * sending out), and the one of the other NAT-D payloads must match the + * remote ends IP address and port. If the first check fails (i.e first + * NAT-D payload does not match any of the local IP addresses and ports), + * then it means that there is dynamic NAT between, and this end should + * start sending keepalives as defined in the . + * + *---------------------------------------------------------------------------------------*/ + TUint32 NatFlags = 0; + + if ( iSupport || iRfcSupport ) { + + TInt count = aNatDPayloadArray->Count(); + if ( count > 1 ) { + // + // Check that the first hash corresponds current local address port pair + // + CalculateAddrPortHashL(aHashType, aICOOKIE, aRCOOKIE, aLocalAddr, aRemoteAddr); + + const TNATDISAKMP *NatDPayload = aNatDPayloadArray->At(0); + if ( !CompareHashData(NatDPayload->HashData(), NatDPayload->HashLth(), iLocalAddrPortHash) ) { + NatFlags |= LOCAL_END_NAT; //Local end is behind a NAT device + } + + // + // Check the rest of NAT discovery payloads. One of them must correspond remote hash data + // calculated in local end + // + NatFlags |= REMOTE_END_NAT; // Remote end is behind a NAT device (as default) + + for ( TInt i = 1; (i < count); i++ ) + { + NatDPayload = aNatDPayloadArray->At(i); + if ( CompareHashData(NatDPayload->HashData(), NatDPayload->HashLth(), iRemoteAddrPortHash) ) { + NatFlags &= ~REMOTE_END_NAT; //Remote end is NOT behind a NAT device + break; + } + + } + } + + } + + return NatFlags; + +} + + +void CIkev1NatDiscovery::BuildNatOaPayload(TIkev1IsakmpStream &aMsg, TInetAddr &aLocalAddr, CProposal_IIList *aProposalList) +{ +(void)aMsg; (void)aLocalAddr; (void)aProposalList; + return; +} + +TBool CIkev1NatDiscovery::GetPeerOriginalAddress(const TNATOaISAKMP *aNatOaPayload, TInetAddr& aRemoteOrigAddr, CProposal_IIList *aProposalList) +{ +(void)aNatOaPayload; (void)aRemoteOrigAddr; (void)aProposalList; + aRemoteOrigAddr.Init(KAFUnspec); // Set address value undefined + return EFalse; +} + + + +void CIkev1NatDiscovery::CalculateAddrPortHashL(TUint16 aHashType, + TUint8 *aICOOKIE, TUint8 *aRCOOKIE, + TInetAddr &aLocalAddr, TInetAddr &aRemoteAddr) +{ + if ( iHashExists ) { + return; //Hash has been already calculated + } +/**--------------------------------------------------------------------------------------- + * + * Calculate HASH = HASH(CKY-I | CKY-R | IP | Port) both for local- and remote IP address/port + * + *---------------------------------------------------------------------------------------*/ + TBuf8<64> in_data; + const TUint8 *pnum; + TUint32 ipv4addr; + TUint16 port; + + in_data.Append(aICOOKIE, ISAKMP_COOKIE_SIZE); + in_data.Append(aRCOOKIE, ISAKMP_COOKIE_SIZE); + + TInetAddr HashAddr = aLocalAddr; + HashAddr.SetPort(500); //Set local port to default IKE port value + TInt i = 0; + + while ( i < 2 ) { + + if ( HashAddr.Family() == KAfInet ) { + ipv4addr = ByteOrder::Swap32(HashAddr.Address());//Put in network order + pnum = (TUint8*)&ipv4addr; + in_data.Append(pnum, sizeof(TUint32)); + } + else { + if ( HashAddr.IsV4Mapped() ) { + HashAddr.ConvertToV4(); // IPv4 format + ipv4addr = ByteOrder::Swap32(HashAddr.Address());//Put in network order + pnum = (TUint8*)&ipv4addr; + in_data.Append(pnum, sizeof(TUint32)); + } + else { + pnum = &HashAddr.Ip6Address().u.iAddr8[0]; //Address in a bytestream + in_data.Append(pnum, 16); + } + } + + port = ByteOrder::Swap16(HashAddr.Port());//Put in network order + pnum = (TUint8*)&port; + in_data.Append(pnum, sizeof(TUint16)); + + if ( i ) { + if ( aHashType == HASH_MD5 ) + MD5HashL(in_data, iRemoteAddrPortHash); // Calculate hash value + else SHA1HashL(in_data, iRemoteAddrPortHash); + } + else { + if ( aHashType == HASH_MD5 ) + MD5HashL(in_data, iLocalAddrPortHash); // Calculate hash value + else SHA1HashL(in_data, iLocalAddrPortHash); + } + in_data.SetLength(ISAKMP_COOKIE_SIZE + ISAKMP_COOKIE_SIZE); // Reset lenght to Icookie + Rcookie + HashAddr = aRemoteAddr; // Process remote address next + + i ++; + } + + iHashExists = ETrue; + +} + +TBool CIkev1NatDiscovery::CompareHashData(TUint8 *aHashData, TUint32 aHashLth, TDesC8 &aReferenceHash) +{ +/**--------------------------------------------------------------------------------------- + * + * Compare current hash data to the reference hash data provided + * + *---------------------------------------------------------------------------------------*/ + TBool result = EFalse; + + if ( (TInt)aHashLth == aReferenceHash.Length() ) { + if ( Mem::Compare(aHashData, aHashLth, aReferenceHash.Ptr(), aHashLth) == 0 ) { + result = ETrue; + } + } + + return result; +} + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1negotiation.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1negotiation.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,8306 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv1/IPSEC SA negotiation +* +*/ + +#include +#include +#include +#include + +#include "ikev1negotiation.h" +#include "ikedebug.h" +#include "ikev1isakmpstream.h" +#include "ikev1timeout.h" +#include "ikev1payload.h" +#include "ikev1plugin.h" +#include "ikev1crack.h" +#include "ikev1trans.h" +#include "ipsecsadata.h" +#include "ipsecsalifetime.h" +#include "pfkeymsg.h" +#include "kmdapi.h" +#include "ikev1pkiservice.h" +#include "ikev1crypto.h" +#include "ikev1natdiscovery.h" +#include "ikev1private.h" +#include "vpnapidefs.h" +#include "ikepkiutils.h" +#include "vpnclientuids.h" +#include "ikecalist.h" +#include "ikecaelem.h" +#include "ikecert.h" +#include "ikev1pluginsession.h" +#include "ikesocketdefs.h" +#include "kmdeventloggerif.h" +#include "pfkeyextdatautil.h" +#include "ipsecsalist.h" + +const TInt KSubjectName = 1; + +///////////////////////////////////////////////////////////////////////////////// +// CIkev1Negotiation related stuff +///////////////////////////////////////////////////////////////////////////////// + + +// +//Proto negotiation to send a informational payload and be destroyed +// +CIkev1Negotiation* CIkev1Negotiation::NewL( CIkev1PluginSession* aPluginSession, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug, + const TInetAddr& aRemote, + const TCookie& aInitiator, + const TCookie& aResponder ) + { + CIkev1Negotiation* self = new ( ELeave ) CIkev1Negotiation( aPluginSession, + aPFKeySocketIf, + aDebug ); + CleanupStack::PushL( self ); + self->iRemoteAddr = aRemote; + self->iCookie_I = aInitiator; + self->iCookie_R = aResponder; + self->iExchange = ISAKMP_EXCHANGE_INFO; + self->iDOI = IPSEC_DOI; + self->iTimer = CIkev1Timeout::NewL( *self ); + CleanupStack::Pop( self ); + return self; + } + +CIkev1Negotiation* CIkev1Negotiation::NewL( CIkev1PluginSession* aPluginSession, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug, + const TInetAddr& aRemote, + const TCookie& aInitiator, + TBool aAutoLogin ) + { + CIkev1Negotiation* self = new ( ELeave ) CIkev1Negotiation( aPluginSession, + aPFKeySocketIf, + aDebug, + aRemote, + aInitiator ); + CleanupStack::PushL( self ); + self->ConstructL( aAutoLogin ); + CleanupStack::Pop( self ); + return self; + } + +CIkev1Negotiation* CIkev1Negotiation::NewL( CIkev1PluginSession* aPluginSession, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug, + TIkev1SAData* aIkev1SAdata, + TUint aRole, + const TPfkeyMessage *aReq ) + { + CIkev1Negotiation* self = new ( ELeave ) CIkev1Negotiation( aPluginSession, + aPFKeySocketIf, + aDebug ); + CleanupStack::PushL( self ); + self->ConstructL( aIkev1SAdata, aRole, aReq ); + CleanupStack::Pop( self ); + return self; + } + + +CIkev1Negotiation* CIkev1Negotiation::NewL( CIkev1PluginSession* aPluginSession, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug, + const TInetAddr& aRemote, + TBool aAutoLogin ) + { + CIkev1Negotiation* self = new ( ELeave ) CIkev1Negotiation( aPluginSession, + aPFKeySocketIf, + aDebug, + aRemote ); + CleanupStack::PushL( self ); + self->iCookie_I = self->CreateCookieL(); + self->ConstructL( aAutoLogin ); + CleanupStack::Pop( self ); + return self; + } + +CIkev1Negotiation* CIkev1Negotiation::NewL( CIkev1PluginSession* aPluginSession, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug, + const TInetAddr& aRemote, + const TPfkeyMessage& aReq ) + { + CIkev1Negotiation* self = new ( ELeave ) CIkev1Negotiation( aPluginSession, + aPFKeySocketIf, + aDebug, + aRemote ); + CleanupStack::PushL( self ); + self->iCookie_I = self->CreateCookieL(); + self->ConstructL( aReq ); + CleanupStack::Pop( self ); + return self; + } + +// +// Destructor +// +CIkev1Negotiation::~CIkev1Negotiation() + { + DEBUG_LOG1( _L("CIkev1Negotiation::~CIkev1Negotiation this=0x%x"), this ); + + + if ( iRole == INITIATOR && + iAcquirePending ) + { + // Response with error to pending Acquire. + AcquireSAErrorResponse( KKmdIkeNegotFailed ); + } + + delete iIpsecSaSpiRetriever; + delete iSavedIkeMsgBfr; + + if( iPluginSession ) + { + iPluginSession->RemoveNegotiation( this ); + } + + iCookie_I.FillZ(ISAKMP_COOKIE_SIZE); + + if(iTimer) + { + iTimer->Cancel(); + delete iTimer; + } + + delete iOwnCert; + delete iPeerX509Cert; + delete iPeerTrustedCA; // Peer trusted CA name + delete iICA1; + delete iICA2; + + delete iPkiService; // Trusted CA certificate list + + delete iSAPayload; + delete iPeerIdentPayload; + delete iOwnIdentPayload; + + //Keys + delete iOwnKeys; //structure containing the public and private keys + delete iOwnPublicKey; //Public Key + + //Phase_I Proposal + TAttrib *attr; + while ((attr = iProposal_I.iAttrList) != NULL) + { + iProposal_I.iAttrList = attr->iNext; + delete attr; + } + + delete iChosenProposal_I.iAttrList; //Only one transformation chosen + + //Phase_II proposals (include transformations) + delete iProposal_IIList; + + //Phase_II chosen Proposal + delete iChosenProp_IIList; + delete iInboundSPIList; + delete iCRACKneg; + delete iTransactionNeg; // Transaction exchange + delete iInternalAddr; + delete iNatDiscovery; + delete iSARekeyInfo; + delete iLastMsg; +} + + +// +// CIkev1Negotiation +// Constructor for remote initiated negotiation +// +CIkev1Negotiation::CIkev1Negotiation( CIkev1PluginSession* aPluginSession, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug, + const TInetAddr& aRemote, + const TCookie& aInitiator ) + : iCookie_I( aInitiator ), + iRemoteAddr( aRemote ), + iPluginSession( aPluginSession ), + iPFKeySocketIf( aPFKeySocketIf ), + iDebug( aDebug ) +{ + + DEBUG_LOG1( _L("CIkev1Negotiation::CIkev1Negotiation, RESPONDER this=0x%x"), this ); + iCookie_R.FillZ(ISAKMP_COOKIE_SIZE); + iSAId = iPluginSession->GetSAId(); + iPluginSession->LinkNegotiation(this); + iRole = RESPONDER; + iStage = 1; //next phase for the responder is 2 +} + +// +// Constructor for local initiated negotiation +// + +CIkev1Negotiation::CIkev1Negotiation( CIkev1PluginSession* aPluginSession, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug, + const TInetAddr& aRemote ) + : iRemoteAddr( aRemote ), + iPluginSession( aPluginSession ), + iPFKeySocketIf( aPFKeySocketIf ), + iDebug( aDebug ) +{ + DEBUG_LOG1( _L("CIkev1Negotiation::CIkev1Negotiation, INITIATOR this=0x%x"), this ); + iCookie_I.FillZ(ISAKMP_COOKIE_SIZE); + iCookie_R.FillZ(ISAKMP_COOKIE_SIZE); + iSAId = iPluginSession->GetSAId(); + iPluginSession->LinkNegotiation(this); + iRole = INITIATOR; + iStage = 0; +} + +// +// Constructor for Phase II initiated negotiations +// + +CIkev1Negotiation::CIkev1Negotiation( CIkev1PluginSession* aPluginSession, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug ) + : iPluginSession( aPluginSession ), + iPFKeySocketIf( aPFKeySocketIf ), + iDebug( aDebug ) +{ + DEBUG_LOG1( _L("CIkev1Negotiation::CIkev1Negotiation, this=0x%x"), this ); + iCookie_I.FillZ(ISAKMP_COOKIE_SIZE); + iCookie_R.FillZ(ISAKMP_COOKIE_SIZE); + iSAId = iPluginSession->GetSAId(); + iPluginSession->LinkNegotiation(this); +} + +//Used when creating a negotiation as a RESPONDER! +//Used also when Initiator (= Phase 1 negotiation stated by the policy activation) +//Leaves if error detected +void CIkev1Negotiation::ConstructL(TBool aAutoLogin) +{ + iIpsecSaSpiRetriever = CIpsecSaSpiRetriever::NewL( *this, + iPFKeySocketIf ); + + iAutoLogin = aAutoLogin; + CommonConstructL(); +} + + +//Used when an Acquire is received +//Leaves if error detected +void CIkev1Negotiation::ConstructL(const TPfkeyMessage &aReq) +{ + iIpsecSaSpiRetriever = CIpsecSaSpiRetriever::NewL( *this, + iPFKeySocketIf ); + + CommonConstructL(); + GetAcquireDataL(aReq); +} + +//Used when initiating a new Phase II negotiation from a negotiated ISAKMP SA. +void CIkev1Negotiation::ConstructL( TIkev1SAData* aSA, + TUint aRole, + const TPfkeyMessage *aReq ) +{ + + iIpsecSaSpiRetriever = CIpsecSaSpiRetriever::NewL( *this, + iPFKeySocketIf ); + + iPhase = PHASE_II; + + //Almost like common construct + iTimer = CIkev1Timeout::NewL(*this); + + //Phase II proposal lists + iProposal_IIList = new (ELeave) CProposal_IIList(1); + + iRemoteAddr.SetPort(IKE_PORT); + + iSeq = aSA->iSeq; + iLocalAddr = aSA->iLocalAddr; + iRemoteAddr = aSA->iRemoteAddr; // Remote Address from peer + iLastRemoteAddr = aSA->iDestinAddr; // Remote Address last transmitted + + iLastIKEMsgInfo = aSA->iLastIKEMsgInfo; + iLastMsg = HBufC8::NewL(4096); + if ( aSA->iLastMsg != NULL ) + { + *iLastMsg = *aSA->iLastMsg; + } + + iRole = aRole; // If we are initiator or responder + + //Header Data + iCookie_I = aSA->iCookie_I; // Initiator Cookie (Used with responder to create KEYID) + iCookie_R = aSA->iCookie_R; // Responder Cookie + iPrevExchange = aSA->iPrevExchange; + iExchange = IKE_QUICK_MODE; + + iMessageId = RandomMessageId(); + + iFlags = aSA->iFlags; // Flags in the msg header + +// iNotifyMessageId = aSA->iHdr.iNotifyMessageId; // Message Id. for Informational Exchanges + + //SA Data + iDOI = IPSEC_DOI; + + iChosenProposal_I.iProtocol = PROTO_ISAKMP; + iChosenProposal_I.iProposalNum = 0; +// iChosenProposal_I.iSPI.Copy(aSA->iChosenProposal_I.iSPI); + iChosenProposal_I.iNumTransforms = 1; + iChosenProposal_I.iAttrList = new (ELeave) TAttrib; //allocated now and deleted when destroying the obj +// *iChosenProposal_I.iAttrList = *aSA->iChosenProposal_I.iAttrList; + iChosenProposal_I.iAttrList->iEncrAlg = aSA->iEncrAlg; + iChosenProposal_I.iAttrList->iHashAlg = aSA->iHashAlg; + iChosenProposal_I.iAttrList->iGroupDesc = aSA->iGroupDesc; + iChosenProposal_I.iAttrList->iGroupType = aSA->iGroupType; + iChosenProposal_I.iAttrList->iKeyLength = aSA->iKeyLength; + if ( aSA->iLifeTimeSecs ) + iChosenProposal_I.iAttrList->iLifeDurationSecs.Copy((TUint8 *)&aSA->iLifeTimeSecs, sizeof(TUint32)); + if ( aSA->iLifeTimeKB ) + iChosenProposal_I.iAttrList->iLifeDurationKBytes.Copy((TUint8 *)&aSA->iLifeTimeKB, sizeof(TUint32)); + + + iHostData = aSA->iIkeData; + if ( iHostData->iCAList && iHostData->iCAList->Count() ) + { + iPkiService = CIkeV1PkiService::NewL(iHostData, iDebug); + } + + if (aRole == INITIATOR) + { + GetAcquireDataL(*aReq); //Data needed from the acquire + } + else //RESPONDER + { + iAcquireSeq = 1; //msg Seq. number + } + + // + //NAT Traversal data + // + iFamiliarPeer = aSA->iFamiliarPeer; + iNAT_T_Required = aSA->iNAT_T_Required; + + // + //Copy an Internal address object (if exists) to the new negotiation + // + if ( aSA->iVirtualIp ) + { + iInternalAddr = CInternalAddress::NewL(*(aSA->iVirtualIp)); + } + + iNAT_D_Flags = aSA->iNAT_D_Flags; + if ( iNAT_D_Flags ) { + // + // Use IETF specified NAT traversal + // + iNatDiscovery = CIkev1NatDiscovery::NewL(aSA->iNAT_D_Flags); + } + + //Keys (DH Generated public value when own) + iSKEYID.Copy(aSA->iSKEYID); + iSKEYID_d.Copy(aSA->iSKEYID_d); + iSKEYID_a.Copy(aSA->iSKEYID_a); + iSKEYID_e.Copy(aSA->iSKEYID_e); + + //IV used by des_cbc and des3_cbc is 8 but digest returns 16 bytes for MDx and 20 for SHS (first 8 used) + iIV = aSA->iIV; //normal IV + iIVSize = iIV.Length(); + + iLastIV = aSA->iLastIV; //Saves the last IV of PHASE_I to compute iNotifIV everytime + + //Nonces +// iNONCE_I = aSA->iNONCE_I; +// iNONCE_R = aSA->iNONCE_R; + // + // If the ISAKMP SA (=aSA) has been originally negotiated due the policy activation (iAutoLogin = ETrue) + // The iLocalAddr maybe then undefined in aSA. + // If local end is acting as an initiator, method GetAcquireDataL updates iLocalAddr in CIkev1Negotiation object. + // In that case take iLocalAddr value from there and store it to CIsakmpSa (aSA) object. + // If local end is acting as a responder, resolve iLocalAddr value. + // + if ( aSA->iAutoLogin ) + { + if ( aRole == INITIATOR) + iLocalAddr = aSA->iLocalAddr; + else User::LeaveIfError( iPluginSession->GetLocalAddress( iLocalAddr ) ); + } + iDPDSupported = aSA->iDPDSupported; + + iSAId = aSA->iSAId; // Reference to existin ISAKMP SA + iStage = 1; //if initiator the stage will be set in a subsequent call to InitPhase_IIL() +} + +//Leaves if error detected +void CIkev1Negotiation::CommonConstructL() +{ + iPhase = PHASE_I; + iTimer = CIkev1Timeout::NewL(*this); + + //Phase II proposal lists + iProposal_IIList = new (ELeave) CProposal_IIList(1); + + iRemoteAddr.SetPort(IKE_PORT); + + iHostData = &iPluginSession->IkeData(); + if (!iHostData) + { + DEBUG_LOG(_L("The host has no data. Negotiation aborted")); + User::Leave(KKmdIkeNoPolicyErr); + } + + if ( iHostData->iCAList && iHostData->iCAList->Count() ) + { + iPkiService = CIkeV1PkiService::NewL(iHostData, iDebug); + TInt stat ( EFalse ); + stat=ReadCAsL(iHostData->iCAList); // Build trusted CA list + if ( !stat ) + { + SetErrorStatus( KVpnErrInvalidCaCertFile ); + User::Leave(KVpnErrInvalidCaCertFile); + } + } + iSendCert = iHostData->iAlwaysSendCert; //If true will always be sent, otherwise only with a CR + + //Proposals + if (!BuildProposals1L()) + { + SetFinished(); + User::Leave(KKmdIkePolicyFileErr); //if any error returns + } + + iEncoding = X509_CERT_SIG; //Only type in use + + iChosenProposal_I.iAttrList = new (ELeave) TAttrib; //allocated now and deleted when destroying the obj + User::LeaveIfError( iPluginSession->GetLocalAddress( iLocalAddr ) ); + + //PFKEY data (is overwritten if initiator because we use the data given in the acquire + + iAcquireSeq = 1;//msg Seq. number of acquire needed for the UPDATE + iSeq = 1; //Sequence number for pfkey messages + + iLastRemoteAddr = iRemoteAddr; // Used as destination address when sending data +#ifdef _DEBUG + TBuf<40> txt_addr; + iRemoteAddr.OutputWithScope(txt_addr); +#endif + + iLastMsg = HBufC8::NewL(4096); + + DEBUG_LOG1( _L("New negotiation with Host %S"), + &txt_addr ); + + if ( !iHostData->iUseNatProbing && iHostData->iEspUdpPort == 0 ) + { + // + // Use IETF specified NAT traversal + // + iNatDiscovery = CIkev1NatDiscovery::NewL(0); + } + + if ( iRole == RESPONDER ) + { + // + // Get base value internal address (=VPN virtual IP) + // + iInternalAddr = iPluginSession->InternalAddressL(); + } +} + + +TBool CIkev1Negotiation::ReadCAsL(CArrayFixFlat *aCAList) +{ + + TBool Status = iPkiService->ImportCACertsL(aCAList); + +#ifdef _DEBUG + if ( !Status ) + { + DEBUG_LOG( _L("Trusted CA list creation failed!") ); + } +#endif // _DEBUG + + return Status; + +} + +TBool CIkev1Negotiation::ReadOwnCertL() +{ + // + // Read own certificate from PKI store using own trusted CA as + // specified issuer + // + TBool Status = EFalse; + _LIT(KVpnApplUid, "101F7993"); + if ( iPkiService && iHostData->iCAList ) + { + TCertInfo* CertInfo; + HBufC8* CAName = HBufC8::NewLC(256); + TInt i = 0; + if ( iHostData->iCAList->At(0)->iData!=KVpnApplUid ) + { + while ( i < iHostData->iCAList->Count() ) + { + + CertInfo = iHostData->iCAList->At(i); + CAName->Des().Copy(CertInfo->iData); // Assure that CA name is in ASCII format + if ( iPkiService->ReadUserCertWithNameL(CAName->Des(), iHostData, EFalse) == KErrNone ) + { + Status = ETrue; + delete iOwnCert; // delete old if exists + iOwnCert = iPkiService->GetCertificate(); + delete iPeerTrustedCA; // for sure + iPeerTrustedCA = iPkiService->GetTrustedCA(); + CleanupStack::PopAndDestroy(CAName); //CAName + CAName=NULL; + break; + } + i ++; + } + if (!Status) + { + CleanupStack::PopAndDestroy(CAName); + CAName=NULL; + } + } + else + { + CIkeCaList* trustedCaList = iPkiService->CaList(); + CleanupStack::PopAndDestroy(CAName); + CAName=NULL; + while ( i < trustedCaList->Count() ) + { + + CIkeCaElem* CaElem = (*trustedCaList)[i]; + CAName = IkeCert::GetCertificateFieldDERL(CaElem->Certificate(), KSubjectName); + if (CAName == NULL) + { + User::Leave(KErrArgument); + } + CleanupStack::PushL(CAName); + if ( iPkiService->ReadUserCertWithNameL(*CAName, iHostData, ETrue) == KErrNone) + { + Status = ETrue; + delete iOwnCert; // delete old if exists + iOwnCert = iPkiService->GetCertificate(); + delete iPeerTrustedCA; + iPeerTrustedCA = iPkiService->GetTrustedCA(); + CleanupStack::PopAndDestroy(CAName); + CAName=NULL; + + + break; + } + i ++; + + CleanupStack::PopAndDestroy(CAName); + CAName=NULL; + } + } + if ( !Status ) + { + DEBUG_LOG( _L("Error loading Own Certificate!") ); + } + } + return Status; +} + + + +void CIkev1Negotiation::GetAcquireDataL(const TPfkeyMessage &aReq) +{ + // ACQUIRE Contains: + + iLocalAddr = *aReq.iSrcAddr.iAddr; //Copies our own address because it's the only way to know it + + //Phase II proposals + //Only one combination received so only one transform + CProposal_II *prop_II = new (ELeave) CProposal_II(); + CleanupStack::PushL(prop_II); + prop_II->ConstructL(); + iProposal_IIList->AppendL(prop_II); + CleanupStack::Pop(); //prop_II safe in case of leave + + prop_II->iProposalNum = FIRST_IPSEC_PROPOSAL; + prop_II->iNumTransforms = 1; + prop_II->iReplayWindowLength = aReq.iProposal.iExt->sadb_prop_replay; + TAttrib_II *attr_II = new (ELeave) TAttrib_II(); + CleanupStack::PushL(attr_II); + prop_II->iAttrList->AppendL(attr_II); //added into the proposal so it's safe if function leaves + CleanupStack::Pop(); //attr_II safe in case of leave + + attr_II->iTransformNum = FIRST_IPSEC_TRANSFORM; + + if (aReq.iBase.iMsg->sadb_msg_satype==SADB_SATYPE_AH) + { + prop_II->iProtocol = PROTO_IPSEC_AH; + if (aReq.iProposal.iComb->sadb_comb_auth == SADB_AALG_MD5HMAC) + { + attr_II->iTransformID = AH_MD5; + attr_II->iAuthAlg = DOI_HMAC_MD5; + } + else if (aReq.iProposal.iComb->sadb_comb_auth == SADB_AALG_SHA1HMAC) + { + attr_II->iTransformID=AH_SHA; + attr_II->iAuthAlg = DOI_HMAC_SHA; + } + else + { + DEBUG_LOG(_L("Unsupported Authentication Algorithm in Acquire")); + SetFinished(); + return; + } + // No auth with variable encryption + } + else if (aReq.iBase.iMsg->sadb_msg_satype == SADB_SATYPE_ESP) + { + prop_II->iProtocol=PROTO_IPSEC_ESP; + /* Request ESP from peer host */ + + attr_II->iTransformID = aReq.iProposal.iComb->sadb_comb_encrypt; + switch ( attr_II->iTransformID ) + { + case ESP_DES_CBC: + case ESP_3DES_CBC: + case ESP_NULL: + break; + + case ESP_AES_CBC: + attr_II->iKeyLength = aReq.iProposal.iComb->sadb_comb_encrypt_maxbits; + break; + + default: + DEBUG_LOG(_L("IPsec Encryption algorithm is not implemented. Wrong algorithms file")); + SetFinished(); + return; + + } + if (aReq.iProposal.iComb->sadb_comb_auth != SADB_AALG_NONE) + { + if (aReq.iProposal.iComb->sadb_comb_auth == SADB_AALG_MD5HMAC) + attr_II->iAuthAlg = DOI_HMAC_MD5; + else if (aReq.iProposal.iComb->sadb_comb_auth == SADB_AALG_SHA1HMAC) + attr_II->iAuthAlg = DOI_HMAC_SHA; + else + { + DEBUG_LOG(_L("Unsupported Authentication Algorithm in Acquire")); + SetFinished(); + return; + } + } + } + + //Check if PFS in use... + if (aReq.iProposal.iComb->sadb_comb_flags & SADB_SAFLAGS_PFS) + { + iPFS=ETrue; + switch (iHostData->iGroupDesc_II) + { + case IKE_PARSER_MODP_768: + attr_II->iGroupDesc = MODP_768; + break; + case IKE_PARSER_MODP_1024: + attr_II->iGroupDesc = MODP_1024; + break; + case IKE_PARSER_MODP_1536: + attr_II->iGroupDesc = MODP_1536; + break; + case IKE_PARSER_MODP_2048: + attr_II->iGroupDesc = MODP_2048; + break; + default: + DEBUG_LOG(_L("ISAKMP Proposals error (Bad Group description)")); + SetFinished(); + return; + } + } + else + { + iPFS=EFalse; + attr_II->iGroupDesc = 0; //No group assigned because no PFS + } + + if (aReq.iProposal.iComb->sadb_comb_flags & SADB_SAFLAGS_TUNNEL) + { + attr_II->iEncMode = DOI_TUNNEL; + } + else + { + attr_II->iEncMode = DOI_TRANSPORT; + } + + iIDLocalPort = (TUint16)aReq.iSrcAddr.iAddr->Port(); + iIDRemotePort = (TUint16)aReq.iDstAddr.iAddr->Port(); + iIDProtocol = aReq.iDstAddr.iExt->sadb_address_proto; //May be needed for phase II ID + + //Source Identity + if (aReq.iSrcIdent.iExt) + { + if (aReq.iSrcIdent.iExt->sadb_ident_type == SADB_IDENTTYPE_PREFIX) + { + if ( !ProcessIdentityData(aReq.iSrcIdent.iData, &iLocalIDType_II, + &iLocalAddr1_ID_II, &iLocalAddr2_ID_II) ) + { + SetFinished(); + return; + } + } + else //Invalid identity type + { + DEBUG_LOG1(_L("Invalid Local identity type (%d)"), aReq.iSrcIdent.iExt->sadb_ident_type); + SetFinished(); + return; + } + } + else + { + //We need to assign a default address if other info is to be sent in the same payload + if (attr_II->iEncMode == DOI_TUNNEL || iIDLocalPort != 0 || iIDRemotePort != 0 || + iIDProtocol != 0 || aReq.iDstIdent.iExt) + { + DEBUG_LOG(_L("Local Identity not defined and needed. Using Own address as local identity.")); + iLocalAddr1_ID_II = iLocalAddr; + if ((iLocalAddr.Family() == KAfInet) || iLocalAddr.IsV4Mapped() ) + iLocalIDType_II = ID_IPV4_ADDR; + else + iLocalIDType_II = ID_IPV6_ADDR; + iDefaultLocalID = ETrue; //Must be sent but won't be used when updating the SAD + } + } + + //Destination Identity + if (aReq.iDstIdent.iExt) + { + if (aReq.iDstIdent.iExt->sadb_ident_type == SADB_IDENTTYPE_PREFIX) + { + if ( !ProcessIdentityData(aReq.iDstIdent.iData, &iRemoteIDType_II, + &iRemoteAddr1_ID_II, &iRemoteAddr2_ID_II) ) + { + SetFinished(); + return; + } + } + else //Invalid identity type + { + + DEBUG_LOG1( _L("Invalid Destination identity type (%d)"), aReq.iDstIdent.iExt->sadb_ident_type ); + SetFinished(); + return; + } + } + else + { + // + // RemoteID_II is required only if LocalID_II already exists + // If transports mode + // Build RemoteID_II for Quick mode negotiation from specified remote IP address + // else Use subnet 0/0 as remote id + // + if ( iLocalIDType_II != 0 ) + { + if ( attr_II->iEncMode == DOI_TUNNEL ) { + if ( iLocalIDType_II == ID_IPV4_ADDR || iLocalIDType_II == ID_IPV4_ADDR_SUBNET ) { + iRemoteAddr1_ID_II.Init(KAfInet); + iRemoteAddr2_ID_II.Init(KAfInet); + iRemoteIDType_II = ID_IPV4_ADDR_SUBNET; + } + else { + iRemoteAddr1_ID_II.Init(KAfInet6); + iRemoteAddr2_ID_II.Init(KAfInet6); + iRemoteIDType_II = ID_IPV6_ADDR_SUBNET; + } + } + else { + iRemoteAddr1_ID_II = *aReq.iDstAddr.iAddr; + if ( iRemoteAddr1_ID_II.Family() == KAfInet6 ) + iRemoteIDType_II = ID_IPV6_ADDR; + else iRemoteIDType_II = ID_IPV4_ADDR; + } + iDefaultRemoteID = ETrue; //Must be sent but won't be used when updating the SAD + } + } + + //Only Hard Lifetimes taken into account + TInt64 lifetime64 = aReq.iProposal.iComb->sadb_comb_soft_addtime; + iHardLifetime = aReq.iProposal.iComb->sadb_comb_hard_addtime; + + if ( lifetime64 == 0 ) + { + lifetime64 = iHardLifetime; + } + + TUint high = 0; + TUint low = 0; + if (lifetime64!=0) + { + high = ByteOrder::Swap32(I64HIGH(lifetime64)); + if (high > 0) + attr_II->iLifeDurationSecs.Copy((TUint8 *)&high, sizeof(high)); + low = ByteOrder::Swap32(I64LOW(lifetime64)); + attr_II->iLifeDurationSecs.Append((TUint8 *)&low, sizeof(low)); + } + + //Bytes lifetime + lifetime64 = aReq.iProposal.iComb->sadb_comb_soft_bytes; + lifetime64 = (lifetime64/1024); //Bytes to KB + if (lifetime64 != 0) + { + high = ByteOrder::Swap32(I64HIGH(lifetime64)); + if (high > 0) + attr_II->iLifeDurationKBytes.Copy((TUint8 *)&high, sizeof(high)); + low = ByteOrder::Swap32(I64LOW(lifetime64)); + attr_II->iLifeDurationKBytes.Append((TUint8 *)&low, sizeof(low)); + } + + //Save some pf_key data to use later in PFKEY_UPDATE msg + iAcquireSeq = aReq.iBase.iMsg->sadb_msg_seq; //msg Seq. number + iPfkeyAcquirePID = aReq.iBase.iMsg->sadb_msg_pid; //msg PID. + iAcquirePending = ETrue; + DEBUG_LOG2( _L("Acq seq= %d , PID= %d"), iAcquireSeq, iPfkeyAcquirePID ); + +} + +// +// CIkev1Negotiation::ExecuteL() +// An ISAKMP message has been received belonging to this negotiation. +// Process the message and advance the negotiation session to appropriate +// next state/stage. +// +TBool CIkev1Negotiation::ExecuteL( const ThdrISAKMP& aHdr, + const TInetAddr& aRemote, + TInt aLocalPort ) +{ + aLocalPort = aLocalPort; + + TBool ret=EFalse; + const ThdrISAKMP *hdr; + TUint8 *msg = NULL; //to place the new msg + TBuf8 tmp_IV(iIV); //Temporal IV. Used to update the real one if the msg OK + + TLastIKEMsg msg_info(aHdr); //For retransmitted IKE msg detection + if ( IsRetransmit(msg_info) ) { + DEBUG_LOG(_L("Retransmitted IKE message received.")); + TBool FloatedPort = EFalse; + if ( iNAT_D_Flags & (REMOTE_END_NAT + LOCAL_END_NAT) ) + FloatedPort = ETrue; + TPtr8 lastMsg(iLastMsg->Des()); + iPluginSession->SendIkeMsgL(lastMsg, iLastRemoteAddr, FloatedPort); + return EFalse; + } + + if ( iPhase == PHASE_II && + aHdr.GetExchange() != IKE_QUICK_MODE ) + { + DEBUG_LOG(_L("Bad packet (retransmission?)")); +#ifdef _DEBUG + const TPtrC8 ikeMsgPtr( (TUint8 *)&aHdr, (TUint16)aHdr.GetLength() ); + TInetAddr dstAddr; + iPluginSession->GetLocalAddress( dstAddr ); + dstAddr.SetPort( aLocalPort ); + TRACE_MSG_IKEV1( ikeMsgPtr, iRemoteAddr, dstAddr ); +#endif // _DEBUG + + SetFinished(); + return EFalse; //Bad packet, is a retransmission + } + + iLastRemoteAddr = aRemote; //Save last remote address (used in NAT cases) + + iLengthLeft = aHdr.GetLength(); //Used to check the size in the payload are OK + + DEBUG_LOG2( _L("---------- Phase %d - Stage %d ----------"), iPhase, iStage ); + + if ((iStage==1) && (iPhase==PHASE_I)) //Only saved for the first message + iExchange = aHdr.GetExchange(); + + DEBUG_LOG1( _L("Exchange %d"), aHdr.GetExchange() ); + + if (aHdr.GetFlags() & ISAKMP_HDR_EFLAG) //if encrypted + { + //before anything, prints the packet + DEBUG_LOG(_L("Received message (encr).")); + DEBUG_LOG(_L("Decrypting...")); + msg = new (ELeave)(TUint8[aHdr.GetLength()]); //to place the new msg + CleanupStack::PushL(msg); + + Mem::Copy(msg,(TUint8 *)&aHdr,sizeof(aHdr)); //The header is not encrypted + + if ((iPhase==PHASE_II) && (iStage == 1)) + { + iMessageId = aHdr.GetMessageId(); //Saves the ID to compute IV + DEBUG_LOG(_L("Quick IV:")); + ComputeIVL(iIV, iMessageId); + } + + DecryptL((TUint8 *)aHdr.Next(),&msg[sizeof(aHdr)], aHdr.GetLength()-sizeof(aHdr),iIV, iSKEYID_e, iChosenProposal_I.iAttrList->iEncrAlg); + if ((iStage == 6 && iExchange == ISAKMP_EXCHANGE_ID) || + (iStage == 3 && iExchange == ISAKMP_EXCHANGE_AGGR)) + { + iLastIV.Copy(iIV); //Saves last IV in Phase 1 + DEBUG_LOG(_L("Last IV Saved!")); + } + hdr=(ThdrISAKMP *)msg; //decrypted msg + + } + else if (iFlags & ISAKMP_HDR_EFLAG) // IKE message SHOULD be encrypted + { + hdr=&aHdr; //no encryption + DEBUG_LOG(_L("Received message.")); +#ifdef _DEBUG + const TPtrC8 ikeMsgPtr( (TUint8 *)hdr, (TUint16)hdr->GetLength() ); + TInetAddr dstAddr; + iPluginSession->GetLocalAddress( dstAddr ); + dstAddr.SetPort( aLocalPort ); + TRACE_MSG_IKEV1( ikeMsgPtr, iRemoteAddr, dstAddr ); +#endif // _DEBUG + DEBUG_LOG(_L("The message is NOT encrypted (ignored)")); + return EFalse; + } + else + hdr=&aHdr; //no encryption + + DEBUG_LOG(_L("Received message.")); +#ifdef _DEBUG + const TPtrC8 ikeMsgPtr( (TUint8 *)hdr, (TUint16)hdr->GetLength() ); + TInetAddr dstAddr; + iPluginSession->GetLocalAddress( dstAddr ); + dstAddr.SetPort( aLocalPort ); + TRACE_MSG_IKEV1( ikeMsgPtr, iRemoteAddr, dstAddr ); +#endif // _DEBUG + + if (iPhase==PHASE_I) + ret = Phase_IExchangeL(*hdr);//MAIN MODE && AGGRESSIVE MODE + else + { + ret = Phase_IIExchangeL(*hdr);//QUICK MODE + } + if (!ret) //Incorrect packet. Restore the IV + { + DEBUG_LOG(_L("Restoring previous IV")); + iIV.Copy(tmp_IV); + } + else //correct packet + { + SaveRetransmitInfo(msg_info); // store new last received IKE message info + } + + if ( msg ) //If used erase it (when encryption) + CleanupStack::PopAndDestroy(); + + return ret; +} + +TBool CIkev1Negotiation::ExecutePhase2L( const ThdrISAKMP &aHdr, + const TInetAddr &aRemote, + TInt aLocalPort ) +{ + return ExecuteL( aHdr, aRemote, aLocalPort ); +} + +// +// CIkev1Negotiation::ExecuteTransactionL +// An ISAKMP Transaction exchange message received. +// Call CTransNegotiation::ExecuteL method and process returned status +// +TBool CIkev1Negotiation::ExecuteTransactionL( const ThdrISAKMP& aHdr, + const TInetAddr& aRemote, + TInt aLocalPort ) +{ + TInt status; + TBool ret = ETrue; + if ( iTransactionNeg ) { + status = iTransactionNeg->ExecuteL( aHdr, aRemote, aLocalPort ); + if ( status == TRANSACTION_SUCCESS ) { + // + // XAUTH / CONFIG-MODE completed succesfully + // + IsakmpPhase1CompletedL(); + } + else { + if ( status == TRANSACTION_FAILED ) { + // + // XAUTH / CONFIG-MODE completed succesfully + // + LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError, + R_VPN_MSG_VPN_GW_AUTH_FAIL, + KKmdIkeAuthFailedErr, + iPluginSession->VpnIapId(), + &iRemoteAddr ); + SendDeleteL(PROTO_ISAKMP); + SetFinished(); + } + } + } + else ret = EFalse; + + return ret; +} + + +// +// CIkev1Negotiation::AuthDialogCompletedL +// Authentication dialog is completed. Check CAuthDialogInfo object ID +// and call eithet CIKECRACKNegotiation::ProcessUserResponseL or +// CTransNegotiation::ProcessUserResponseL to handle dialog data +// +void CIkev1Negotiation::AuthDialogCompletedL(CAuthDialogInfo *aUserInfo) +{ + if ( !aUserInfo || (!aUserInfo->iUsername && !aUserInfo->iSecret) ) + { + DEBUG_LOG(_L("Legacy authentication cancelled by user!")); + SendDeleteL(PROTO_ISAKMP); + LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError, + R_VPN_MSG_VPN_GW_AUTH_FAIL, + KErrCancel, + iPluginSession->VpnIapId(), + &iRemoteAddr ); + SetErrorStatus(KErrCancel); + return; + } + + TInt status; + + if ( aUserInfo->GetObjId() == XAUTH_DIALOG_ID ) + { + if ( iTransactionNeg ) + status = iTransactionNeg->ProcessUserResponseL(aUserInfo); + else status = TRANSACTION_FAILED; + + if ( status == TRANSACTION_FAILED ) + { + /*-------------------------------------------------------- + * + * XAUTH negotiation failed. Negotiation shall be deleted + * + *--------------------------------------------------------*/ + LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError, + R_VPN_MSG_VPN_GW_AUTH_FAIL, + status, + iPluginSession->VpnIapId(), + &iRemoteAddr ); + SetErrorStatus(KKmdIkeAuthFailedErr); + AcquireSAErrorResponse(KKmdIkeAuthFailedErr); + } + } + else + { + if ( iCRACKneg ) + status = iCRACKneg->ProcessUserResponseL(aUserInfo); + else status = CRACK_FAILED; + + if ( status == CRACK_FAILED ) + { + /*-------------------------------------------------------- + * + * Crack negotiation failed. Negotiation shall be deleted + * + *--------------------------------------------------------*/ + LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError, + R_VPN_MSG_VPN_GW_AUTH_FAIL, + status, + iPluginSession->VpnIapId(), + &iRemoteAddr ); + SetErrorStatus(KKmdIkeAuthFailedErr); + AcquireSAErrorResponse(KKmdIkeAuthFailedErr); + } + } +} + + +// +// CIkev1Negotiation::StartCRACKAuthL +// Start CRACK authentication phase of IKE phase I negotiation +// - Create CIKECRACKNegotiation object and call it`s ConstructL +// - Set iStage variable to 7 to indicate that CRACK authentication +// is going +// +TBool CIkev1Negotiation::StartCRACKAuthL() +{ +TInt status; + + iStage = 7; + + if ( !iCRACKneg ) { + iCRACKneg = new(ELeave) CIKECRACKNegotiation( iDebug ); + TBuf<2> DummyDomain; + // + // If the IKE Id-type value is configured to value "Opaque + // String" and iFQDN length is larger than zero in the current + // policy ==> iFQDN value contains "Group name" value + // which shall be conveyed to the peer in CRACK "Domain name" + // attribute + // + iFlags |= ISAKMP_HDR_EFLAG; //From now on encryption is used + + if ( (iHostData->iIdType == ID_KEY_ID) && (iHostData->iFQDN.Length() > 0 ) ) + status = iCRACKneg->ConstructL(iHostData->iCRACKLAMType, this, iHostData->iFQDN); + else status = iCRACKneg->ConstructL(iHostData->iCRACKLAMType, this, DummyDomain); + if ( status == CRACK_FAILED ) { + return EFalse; + } + } + + return ETrue; +} + +// +// CIkev1Negotiation::IsakmpPhase1CompletedL +// This method is called when an ISAKMP phase 1 negotiation is succesfully +// completed. The following actions are taken: +// -- If either Extended authentication or/and Config mode required +// If iTransactionNeg data member exists it means that XAUTH/CONFIG mode +// has been succesfully completed. +// If iTransactionNeg data member is NULL, XAUTH/CONFIG mode shall be initiated +// -- If No XAUTH/CONFIG mode (or if XAUTH/CONFIG mode already completed). +// If iAutoLogin is TRUE save ISAKMP SA and deconstruct negotiation. +// If iAutoLogin is False, save ISAKMP SA and; +// if negotiation role is initiator continue with Quick mode exchange. +// if negotiation role is responder deconstruct negotiation. +// +TBool CIkev1Negotiation::IsakmpPhase1CompletedL() +{ + TBool Status; + + if ( iTransactionNeg ) { + // + // Try to get Internal address information and delete iTransactionNeg + // + delete iInternalAddr; + iInternalAddr = iTransactionNeg->GetInternalAddr(); + delete iTransactionNeg; + iTransactionNeg = NULL; + } + else { + if ( (iRole == INITIATOR) && (iHostData->iUseXauth || iHostData->iUseCfgMode) ) + { + TBool useModeCfg; + if ( iSARekeyInfo ) + useModeCfg = EFalse; // Use existing virtual Ip, if any + else + useModeCfg = iHostData->iUseCfgMode; + + iTransactionNeg = CTransNegotiation::NewL( iHostData->iUseXauth, + useModeCfg, + iPluginSession, + this, + iDebug ); + + // If only MODE_CFG is needed a request is sent + if(useModeCfg && !iHostData->iUseXauth) + iTransactionNeg->BuildConfigRequestL(); + + iStage = 8; + return ETrue; + } + } + + SaveISAKMPSAL(); + + if ( iAutoLogin ) { + // + // ISAKMP Phase 1 completed. Quick mode is NOT started because there is no acquire pending + // but phase 1 negotiation is started by the policy activation. + // + CInternalAddress* internalAddr = NULL; + if ( iInternalAddr != NULL ) + { + internalAddr = CInternalAddress::NewL(*iInternalAddr); + } + iPluginSession->IkeSaCompleted(KErrNone, internalAddr); + SetFinished(); // Causes negotiation object destruction + iAutoLogin = EFalse; + Status = EFalse; + } + else { + if ( iRole == INITIATOR ) { + TBool internalAddressChanged = EFalse; + if ( iInternalAddr ) { + // + // Report internal IP address changed event + // + internalAddressChanged = iPluginSession->InternalAddressChangedL(*iInternalAddr); + } + if ( (!iSARekeyInfo || + iPhaseIIAfterIkeSaRekey) && + !internalAddressChanged ) + { + iPhaseIIAfterIkeSaRekey = EFalse; + iPrevExchange = iExchange; //Needed to know how to begin Phase II (Sending or receiving) + iExchange = IKE_QUICK_MODE; + iPhase = PHASE_II; + iStage = 1; + Status = ETrue; + iMessageId = RandomMessageId(); + InitPhase2L(); //Immediately inits PHASE_II. No reply expected. + } + else { + // + // Rekeyed IKE SA or internal address changed. No IKE quick mode started + // Pending acquire will be failed, if internal address has changed. + // + SetFinished(); + Status = EFalse; + } + } + else { + SetFinished(); // Causes negotiation object destruction + Status = EFalse; + } + } + + LOG_KMD_EVENT( MKmdEventLoggerIf::KLogInfo, + R_VPN_MSG_VPN_GW_AUTH_OK, + KErrNone, + iPluginSession->VpnIapId(), + &iRemoteAddr ); + + TInt NatStatus = iNAT_D_Flags; // Record "IETF" NAT status + if ( NatStatus == 0 ) + { + if ( iNAT_T_Required ) + NatStatus = 4; // Local end is NAT:ted (discovered via "Nokia" NAT-T) + else if ( !iHostData->iUseNatProbing ) + NatStatus = iHostData->iEspUdpPort; // "Forced" ESP UDP encapsulation ? + } + + TInetAddr localAddr; + iPluginSession->GetLocalAddress( localAddr ); + LOG_KMD_EVENT2( MKmdEventLoggerIf::KLogInfo, + R_VPN_MSG_ADDR_INFO_FOR_VPN_AP, + NatStatus, iPluginSession->VpnIapId(), + (iInternalAddr ? &iInternalAddr->iClientIntAddr : NULL), + &localAddr ); + + return Status; +} + + +//Sends the initial IKE packets to start the negotiation. PHASE I +void CIkev1Negotiation::InitNegotiationL() //Equiv. to stage 1 +{ + TIkev1IsakmpStream* msg = SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) ); + + TInt vendor_id_type; + + //Main mode stage 1 + + switch (iHostData->iMode) + { + case IKE_PARSER_MAIN: + iExchange = ISAKMP_EXCHANGE_ID; // Identity Protection (Main mode in IKE) + DEBUG_LOG(_L("IKE: Initiating negotiation (Main Mode)")); + break; + case IKE_PARSER_AGGRESSIVE: + iExchange = ISAKMP_EXCHANGE_AGGR; // Agressive + DEBUG_LOG(_L("IKE: Initiating negotiation (Aggressive Mode)")); + break; + default: + DEBUG_LOG1(_L("Bad Mode used (%d)"), iHostData->iMode); + return; + } + iStage = 1; + DEBUG_LOG2(_L("---------- Phase %d - Stage %d ----------"),iPhase, iStage); + + iCookie_R.FillZ(ISAKMP_COOKIE_SIZE); //Set responder Cookie to 0 + + iDOI = IPSEC_DOI; + iEncoding = X509_CERT_SIG; //Only cert Allowed + msg->IsakmpInit(this); + msg->IsakmpSa(); + + const TUint8 *ptr = msg->iBuf.Ptr() + sizeof(ThdrISAKMP); + const TSAISAKMP *sa = (TSAISAKMP*)ptr; + //Generic payload NOT included + iSAPayloadSize = sa->GetLength() - sizeof(TPayloadISAKMP); + delete iSAPayload; + iSAPayload = NULL; + iSAPayload = new (ELeave) TUint8[iSAPayloadSize]; + ptr += sizeof(TPayloadISAKMP); + Mem::Copy(iSAPayload, ptr,iSAPayloadSize); + + TBool cert_required = EFalse; //If any proposal requires a cert to send a CR if needed + TBool preshared_key = EFalse; //Preshared key authentication + TBool crack_used = EFalse; + + TAttrib *transf = iProposal_I.iAttrList; + for (TInt i=0; (i < iProposal_I.iNumTransforms) && (!cert_required); i++) + { + switch (transf->iAuthMethod) + { + case RSA_SIG: //Proposals involving certificates + case DSS_SIG: + cert_required = ETrue; + break; + case IKE_A_CRACK: + cert_required = ETrue; + crack_used = ETrue; + break; + default: // No cert involved + preshared_key = ETrue; + transf = transf->iNext; + } + } + + if (crack_used && + !iHostData->iCRACKLAMUserName && + !iHostData->iCRACKLAMPassword) + { + TBuf<256> UserName; + TBuf<64> Password; + CIkev1Dialog* Dialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); + if (KErrNone != Dialog->GetSyncUNPWCacheDialog(UserName, Password)) + { + DEBUG_LOG(_L("Failed to get credentials for crack auth!")); + SetFinished(); + delete Dialog; + return; + } + iHostData->iCRACKLAMUserName = TStringData::NewL(UserName); + iHostData->iCRACKLAMPassword = TStringData::NewL(Password); + delete Dialog; + } + + if (iExchange == ISAKMP_EXCHANGE_AGGR) //Aggressive contains more payloads + { + if ( preshared_key && !cert_required ) { + // + // Only pre-shared key authentication proposal(s) exists + // Check if is necessary to ask user name/password (= IKE ID/preshared key) + // from user + // + if ( CheckCredentials(iHostData) != KErrNone ) { + DEBUG_LOG(_L("Failed to get credentials for Aggressive pre-shared auth!")); + SetFinished(); + return; + } + } + ComputeNonceL(); //Nonce to be sent + if ( cert_required && !iOwnCert ) + ReadOwnCertL(); // For possible DER ASN1 distuingish name Ident + msg->IsakmpKeyL(); + msg->IsakmpNonce(); + msg->IsakmpOwnIdentL(); + + //For aggressive mode we send a CR if a cert is going to be needed + if ((!iPeerX509Cert) && (cert_required)) + { + msg->IsakmpCertificateReqL(); + } + if ( iHostData->iUseNatProbing ) + vendor_id_type = EXPANDED_VENDOR_ID; + else vendor_id_type = HASH_VENDOR_ID; + msg->IsakmpVendorId(vendor_id_type, + (TUint8*)iCookie_I.Ptr(), + (TUint8*)iCookie_R.Ptr(), iLocalAddr); + + } + + if ( iHostData->iDPDHeartBeat != 0 ) + BuildDPDVendorId(*msg); + + if ( iNatDiscovery ) { + iNatDiscovery->BuildNatVendorId(*msg); + iNatDiscovery->BuildRfcNatVendorId(*msg); + } + + if ( iHostData->iUseXauth || iHostData->iUseCfgMode ) { + CTransNegotiation::BuildXauthVendorId(*msg); + } + + SendL(*msg); + iStage = 2; +} + +//Builds the proposal list from the structure in the engine +TBool CIkev1Negotiation::BuildProposals1L() +{ + TProposalData *p_list = iHostData->iPropList; + + if (!p_list) + { + DEBUG_LOG(_L("ERROR: No proposals in the configuration file. Negotiation Cancelled")); + return EFalse; + } + iProposal_I.iSPI.FillZ(4); //filled with 0 (not send anyway) + iProposal_I.iProposalNum = FIRST_ISAKMP_PROPOSAL; + iProposal_I.iProtocol = PROTO_ISAKMP; + iProposal_I.iNumTransforms = 0; + + TUint8 trans_num = FIRST_ISAKMP_TRANSFORM; + + TAttrib *prev=NULL,*attrlist=NULL; + + while ( p_list ) + { + iProposal_I.iNumTransforms ++; + attrlist = new (ELeave) TAttrib; + if (!iProposal_I.iAttrList) //First transform + iProposal_I.iAttrList=attrlist; //attrlist safe + if (prev) + prev->iNext = attrlist; + prev = attrlist; + + attrlist->iTransformID = KEY_IKE; //only one allowed by Protocol ISAKMP (KEY_IKE) + attrlist->iTransformNum = trans_num; + trans_num++; + switch (p_list->iEncrAlg) + { + case IKE_PARSER_DES_CBC: + attrlist->iEncrAlg=DES_CBC; //DES_CBC + break; + case IKE_PARSER_DES3_CBC: + attrlist->iEncrAlg=DES3_CBC; //DES3_CBC + break; + case IKE_PARSER_AES_CBC: + attrlist->iEncrAlg = AES_CBC; //AES_CBC + attrlist->iKeyLength = (TUint16)p_list->iEncrKeyLth; + if (!attrlist->iKeyLength) + attrlist->iKeyLength = 128; //default AES key size + break; + default: + DEBUG_LOG(_L("ISAKMP Proposals error (Bad Encryption algorithm)")); + return EFalse; + } + switch (p_list->iHashAlg) + { + case IKE_PARSER_MD5: + attrlist->iHashAlg=HASH_MD5; //HASH_MD5 + break; + case IKE_PARSER_SHA1: + attrlist->iHashAlg=HASH_SHA1; //HASH_SHA1 + break; + default: + DEBUG_LOG(_L("ISAKMP Proposals error (Bad Hash algorithm)")); + return EFalse; + } + switch (p_list->iAuthMeth) + { + case IKE_PARSER_RSA_SIG: + attrlist->iAuthMethod=RSA_SIG; + break; + case IKE_PARSER_DSS_SIG: + attrlist->iAuthMethod=DSS_SIG; + break; + case IKE_PARSER_PRE_SHARED: + attrlist->iAuthMethod=PRE_SHARED; + break; + case IKE_PARSER_CRACK: + attrlist->iAuthMethod=IKE_A_CRACK; //CRACK authentication + break; + + default: + DEBUG_LOG(_L("ISAKMP Proposals error (Bad Authentication Method)")); + return EFalse; + } + + switch (p_list->iGroupDesc) + { + case IKE_PARSER_MODP_768: + attrlist->iGroupDesc = MODP_768; + break; + case IKE_PARSER_MODP_1024: + attrlist->iGroupDesc = MODP_1024; + break; + case IKE_PARSER_MODP_1536: + attrlist->iGroupDesc = MODP_1536; + break; + case IKE_PARSER_MODP_2048: + attrlist->iGroupDesc = MODP_2048; + break; + default: + DEBUG_LOG(_L("ISAKMP Proposals error (Bad Group description)")); + return EFalse; + } + + switch (p_list->iGroupType) + { + case IKE_PARSER_MODP: + attrlist->iGroupType = MODP; + break; + case IKE_PARSER_DEFAULT: + break; + default: + DEBUG_LOG(_L("ISAKMP Proposals error (Bad Group Type)")); + return EFalse; + } + + switch (p_list->iPRF) + { + case IKE_PARSER_DES3_CBC_MAC: + attrlist->iPRF=OAKLEY_PRF_3DES_CBC_MAC; + break; + case IKE_PARSER_NONE: + break; + default: + DEBUG_LOG(_L("ISAKMP Proposals error (Bad PRF specified)")); + return EFalse; + } + + TUint32 lifetime = ByteOrder::Swap32(p_list->iLifetimeSec); + if (lifetime) + attrlist->iLifeDurationSecs.Copy((TUint8 *)&lifetime, sizeof(lifetime)); + + lifetime = ByteOrder::Swap32(p_list->iLifetimeKb); + if (lifetime) + attrlist->iLifeDurationKBytes.Copy((TUint8 *)&lifetime, sizeof(lifetime)); + + // + // Store parameters for extended authentication + // + attrlist->iXauthUsed = iHostData->iUseXauth; + attrlist->iRole = iRole; + + p_list = p_list->iNext; + + } + attrlist->iNext=NULL; //Last transform + + + return ETrue; +} + +//Builds Phase_II proposals from the config. file to when acting as RESPONDER to see if +//proposals received are acceptable. +TInt CIkev1Negotiation::BuildProposals2L() +{ + CIpsecSaSpecList* SaList = NULL; + TInetAddr empty_addr; //empty address + TInt err = KErrNone; + + TRAP(err, + if ( iLocalIDType_II == 0 ) //Local ID not received (so remote neither) so it's the same as gateway + { + TInetAddr localSelector(iLocalAddr); + localSelector.SetPort(iIDLocalPort); + TInetAddr remoteSelector(iRemoteAddr); + remoteSelector.SetPort(iIDRemotePort); + + SaList = iPluginSession->GetIpseSaSpecListLC(localSelector, empty_addr, + remoteSelector, empty_addr, + iIDProtocol ); + } + else // either none or both (RFC 2409 5.5 so we must have both) + { + TInetAddr localSelector(iLocalAddr1_ID_II); + localSelector.SetPort(iIDLocalPort); + TInetAddr remoteSelector(iRemoteAddr1_ID_II); + remoteSelector.SetPort(iIDRemotePort); + + + SaList = iPluginSession->GetIpseSaSpecListLC(localSelector, + iLocalAddr2_ID_II, + remoteSelector, + iRemoteAddr2_ID_II, + iIDProtocol ); + } + + CleanupStack::Pop(SaList); + ); + + if (err != KErrNone) + return err; + + CleanupStack::PushL(SaList); + + //Phase II proposals + + CProposal_II *prop = NULL; + TAttrib_II *attr_II = NULL; + const TIpsecSaSpec *spec = NULL; + TInt count = SaList->Count(); + TInt i = 0; + + while ( i < count ) + { + prop = new (ELeave) CProposal_II(); + CleanupStack::PushL(prop); + prop->ConstructL(1); + iProposal_IIList->AppendL(prop); + CleanupStack::Pop(); //prop safe + // + // Only 1 proposal which may be AND'd (many prop with same num) if many bundles + // Only 1 transform because no OR'ing implemented in IPSEC + // + prop->iProposalNum = FIRST_IPSEC_PROPOSAL; + prop->iNumTransforms = 1; + + attr_II = new (ELeave) TAttrib_II(); + CleanupStack::PushL(attr_II); + prop->iAttrList->AppendL(attr_II); + CleanupStack::Pop(); //attr_II safe + + attr_II->iTransformNum = FIRST_IPSEC_TRANSFORM; + + spec = &(SaList->At(i)); + + if (spec->iType == SADB_SATYPE_AH) + { + prop->iProtocol=PROTO_IPSEC_AH; + if (spec->iAalg == SADB_AALG_MD5HMAC) + { + attr_II->iTransformID = AH_MD5; + attr_II->iAuthAlg = DOI_HMAC_MD5; + } + else if (spec->iAalg == SADB_AALG_SHA1HMAC) + { + attr_II->iTransformID=AH_SHA; + attr_II->iAuthAlg = DOI_HMAC_SHA; + } + else + { + DEBUG_LOG(_L("Unsupported Authentication Algorithm in IPsec Policy")); + err = KKmdIkeNoProposalErr; + break; + } + // No auth with variable encryption + } + else if (spec->iType == SADB_SATYPE_ESP) + { + prop->iProtocol = PROTO_IPSEC_ESP; + // Request ESP from peer host + + attr_II->iTransformID = spec->iEalg; + switch ( attr_II->iTransformID ) + { + case ESP_DES_CBC: + case ESP_3DES_CBC: + case ESP_NULL: + break; + + case ESP_AES_CBC: + attr_II->iKeyLength = spec->iEalgLen; //If 0 it won't be sent + break; + + default: + DEBUG_LOG(_L("IPsec Encryption algorithm is not implemented. Wrong algorithms file")); + err = KKmdIkeNoProposalErr; + break; + } + + if (err != KErrNone) + { + break; + } + + if (spec->iAalg != SADB_AALG_NONE) + { + if (spec->iAalg == SADB_AALG_MD5HMAC) + attr_II->iAuthAlg = DOI_HMAC_MD5; + else if (spec->iAalg == SADB_AALG_SHA1HMAC) + attr_II->iAuthAlg = DOI_HMAC_SHA; + else + { + DEBUG_LOG(_L("Unsupported Authentication Algorithm in IPsec Policy")); + err = KKmdIkeNoProposalErr; + break; + } + } + } + + //Check if PFS in use... + iPFS = spec->iPfs; + + if (spec->iTransportMode) + attr_II->iEncMode = DOI_TRANSPORT; + else attr_II->iEncMode = DOI_TUNNEL; + + ////////////////////////////////////////////////////////// + // + // Check if remote identity defined in Security Policy + // If it is not set iDefaultLocalID = ETrue. + // This prevents destination identity information to IPSEC + // in PFKEY Update- and Add primitives + // (see UpdateSADatabaseL() method) + // + ////////////////////////////////////////////////////////// + if ( spec->iRemoteIdentity.Length() == 0 ) + iDefaultLocalID = ETrue; + if ( !ExamineRemoteIdentity(spec->iRemoteIdentity) ) + { + DEBUG_LOG(_L("Remote Identity mismatch with IPsec Policy")); + err = KKmdIkeNoProposalErr; + break; + } + + //Only Hard Lifetimes taken into account + TInt64 lifetime64 = spec->iHard.iAddTime; + TUint high = 0; + TUint low = 0; + if (lifetime64!=0) + { + high = ByteOrder::Swap32(I64HIGH(lifetime64)); + if (high > 0) + attr_II->iLifeDurationSecs.Copy((TUint8 *)&high, sizeof(high)); + low = ByteOrder::Swap32(I64LOW(lifetime64)); + attr_II->iLifeDurationSecs.Append((TUint8 *)&low, sizeof(low)); + } + + //Bytes lifetime + lifetime64 = spec->iHard.iBytes; + lifetime64 = (lifetime64/1024); //Bytes to KB + if (lifetime64 != 0) + { + high = ByteOrder::Swap32(I64HIGH(lifetime64)); + if (high > 0) + attr_II->iLifeDurationKBytes.Copy((TUint8 *)&high, sizeof(high)); + low = ByteOrder::Swap32(I64LOW(lifetime64)); + attr_II->iLifeDurationKBytes.Append((TUint8 *)&low, sizeof(low)); + } + if (iPFS) + { + switch (iHostData->iGroupDesc_II) + { + case IKE_PARSER_MODP_768: + attr_II->iGroupDesc = MODP_768; + break; + case IKE_PARSER_MODP_1024: + attr_II->iGroupDesc = MODP_1024; + break; + case IKE_PARSER_MODP_1536: + attr_II->iGroupDesc = MODP_1536; + break; + case IKE_PARSER_MODP_2048: + attr_II->iGroupDesc = MODP_2048; + break; + default: //Shouldn't happen but the error will be detected later + err = KKmdIkeNoProposalErr; + break; + } + + if (err != KErrNone) + { + break; + } + } + + prop->iReplayWindowLength = spec->iReplayWindowLength; + + i ++; + } //while + + if (err != KErrNone) + { + delete iProposal_IIList; + iProposal_IIList = NULL; + } + + CleanupStack::PopAndDestroy(SaList); //SAList + + return err; +} + +TBool CIkev1Negotiation::ExamineRemoteIdentity(const TDesC8& aRemoteIdInPolicy) +{ + ////////////////////////////////////////////////////////////////// + // + // This method is called when we are acting as a Quick mode responder. + // The purpose of this method is compare remote Identity information + // received in Quick Mode IKE message (=IDi) to the remote Identity + // information in the local Ipsec Policy. + // If Identitiea are NOT matching the FALSE response is returned. + // There is the following special "kludge" is done in these test: + // Identity IPv4 address and IPv4 subnet with prefix 32 are + // interpreted to be same as well as IPv6 address and IPv6 subnet + // with prefix 128. When this situation occurs a special flag + // (iSwapRemoteIdType = ETrue) is set in CIkev1Negotiation object + // + ////////////////////////////////////////////////////////////////// + TBool AddrMatch; + TInetAddr IpAddr; + TInetAddr IpMask; + TUint8 IdType; + TInt PrefixLength = 0; + TInetAddr* PrefixPtr = NULL; + + if ( !ProcessIdentityData(aRemoteIdInPolicy, &IdType, &IpAddr, &IpMask) ) + return EFalse; + + AddrMatch = IpAddr.Match(iRemoteAddr1_ID_II); + + if ( AddrMatch ) + { + if ( (IdType == ID_IPV4_ADDR_SUBNET ) || (IdType == ID_IPV6_ADDR_SUBNET) ) + { + // + // Identity in policy is IP subnet + // + if ( iRemoteIDType_II == IdType ) + { + // + // Both identity in policy and identity in IKE IDi payload are + // IP subnets. The subnet masks MUST match, too + // + AddrMatch = IpMask.Match(iRemoteAddr2_ID_II); + } + else + { + if ( ( (IdType == ID_IPV4_ADDR_SUBNET ) && (iRemoteIDType_II == ID_IPV4_ADDR)) || + ( (IdType == ID_IPV6_ADDR_SUBNET ) && (iRemoteIDType_II == ID_IPV6_ADDR))) + { + // + // Identity in IKE IDi payload is an IP address + // Do the special check: There must be full mask in the + // subnet identity configured in policy + // + if ( IdType == ID_IPV6_ADDR_SUBNET ) + PrefixLength = 128; + else PrefixLength = 32; + PrefixPtr = &IpMask; + DEBUG_LOG(_L("Peer is using IP address IDi, full mask subnet required in local end!")); + } + else AddrMatch = EFalse; + } + } + else + { + // + // Identity in policy is IP address. + // + if ( ( (IdType == ID_IPV4_ADDR ) && (iRemoteIDType_II == ID_IPV4_ADDR_SUBNET)) || + ( (IdType == ID_IPV6_ADDR ) && (iRemoteIDType_II == ID_IPV6_ADDR_SUBNET))) + { + // + // Identity in IKE IDi payload is an IP subnet + // Do the special check: There must be full mask in the + // subnet identity in IKE IDi payload + // + if ( IdType == ID_IPV6_ADDR ) + PrefixLength = 128; + else PrefixLength = 32; + PrefixPtr = &iRemoteAddr2_ID_II; + DEBUG_LOG(_L("An IP address ID used in local end, full mask subnet required in peer IDi!")); + } + else if ( iRemoteIDType_II != IdType ) + AddrMatch = EFalse; + + } + } + + if ( PrefixPtr ) + { + if ( PrefixLength == PrefixLen(*PrefixPtr) ) + { + iSwapRemoteIdType = ETrue; + DEBUG_LOG(_L("Required ID OK, modified remote IDi informed to IPsec!")); + } + else AddrMatch = EFalse; + } + + return AddrMatch; +} + +TBool CIkev1Negotiation::ProcessIdentityData(const TDesC8& aIdentity, TUint8* aToIdType, + TInetAddr* aToIpAddr1, TInetAddr* aToIpAddr2) +{ + if ( !aToIdType || !aToIpAddr1 || !aToIpAddr2 ) + return EFalse; + + aToIpAddr1->Init(KAFUnspec); + aToIpAddr2->Init(KAFUnspec); + *aToIdType = 0; + + if ( aIdentity.Length() ) + { + TInt offset = aIdentity.Find(_L8("/")); + + switch (offset) + { + case KErrNotFound: //Simple address + { +#ifdef _UNICODE + HBufC *unibuf = HBufC::New(aIdentity.Length()); + if ( !unibuf ) + return EFalse; + unibuf->Des().Copy(aIdentity); + if ( aToIpAddr1->Input(unibuf->Des()) != KErrNone ) + { + delete unibuf; + DEBUG_LOG(_L("Bad IP address identity!")); + return EFalse; + } + delete unibuf; +#else + if (aToIpAddr1->Input(aIdentity) != KErrNone) + { + DEBUG_LOG(_L("Bad IP address identity!")); + return EFalse; + } +#endif + if ( aToIpAddr1->Family() == KAfInet ) + *aToIdType = ID_IPV4_ADDR; + else *aToIdType = ID_IPV6_ADDR; + break; + } + + default: //Subnet + { + //addr1 - subnet + TInt prefix_len; +#ifdef _UNICODE + HBufC *unibuf = HBufC::New(aIdentity.Length()); + if ( !unibuf ) + return EFalse; + unibuf->Des().Copy(aIdentity); + TPtrC addr_buf(unibuf->Ptr(), offset); + if (aToIpAddr1->Input(addr_buf) != KErrNone) + { + delete unibuf; + DEBUG_LOG(_L("Bad Subnet Identity address!")); + return EFalse; + } + TPtrC prefix_ptr(unibuf->Ptr() + offset + 1, unibuf->Length() - offset - 1); +#else + TPtrC addr_buf(aIdentity.Ptr(), offset); + if (aToIpAddr1->.Input(addr_buf) != KErrNone) + { + DEB(LogError(_L("Bad Subnet Identity address!"));) + return EFalse; + } + TPtrC prefix_ptr(aIdentity.Ptr() + offset + 1, aIdentity.Length() - offset - 1); +#endif + //addr2 - mask + TLex lex(prefix_ptr); + if (lex.Val(prefix_len) != KErrNone) + { + DEBUG_LOG(_L("Bad Subnet Identity PREFIX Length!")); + return EFalse; + } +#ifdef _UNICODE + delete unibuf; +#endif + if ( aToIpAddr1->Family() == KAfInet ) + { + if ( prefix_len > 32 ) + { + DEBUG_LOG(_L("Bad Subnet Identity: Prefix too long!")); + return EFalse; + } + *aToIdType = ID_IPV4_ADDR_SUBNET; + PrefixMask(*aToIpAddr2, prefix_len, KAfInet); + } + else //KAfInet6 + { + if ( prefix_len > 128 ) + { + DEBUG_LOG(_L("Bad Subnet Identity: Prefix too long!")); + return EFalse; + } + *aToIdType = ID_IPV6_ADDR_SUBNET; + PrefixMask(*aToIpAddr2, prefix_len, KAfInet); + } + + } + + } //end switch + } + + return ETrue; +} + +//First msg of PHASE_II as initiator +void CIkev1Negotiation::InitPhase2L() +{ + //Quick mode stage 1 + DEBUG_LOG(_L("-------- IKE: Initiating PHASE II --------")); + iPhase = PHASE_II; + iDOI=IPSEC_DOI; + iStage = 1; + + GetSPIL(); + //the rest will be done in ReceiveSPI +} + +//Requests an SPI from the kernel + +void CIkev1Negotiation::GetSPIL() +{ + CProposal_IIList *propII_List; + CProposal_II *prop=NULL; + TUint8 sa_type = 0; + + DEBUG_LOG1(_L("GetSPI in stage: %d"), iStage); + + iInboundSPIList = new (ELeave) CArrayFixFlat(1); + + if (iRole == RESPONDER) //If Phase II proposal Chosen + propII_List = iChosenProp_IIList; //If RESPONDER + else + propII_List = iProposal_IIList; //If INITIATOR + + TInt i, count = propII_List->Count(); + for (i = 0; i < count; i++) //May have many Phase_II proposals + { + prop = propII_List->At(i); + if (prop->iProtocol == PROTO_IPSEC_AH) + sa_type = SADB_SATYPE_AH; + else if (prop->iProtocol == PROTO_IPSEC_ESP) + sa_type = SADB_SATYPE_ESP; + else + sa_type = 0; //Unknown Protocol + + TInetAddr myAddr(iLocalAddr); + if ( myAddr.IsUnspecified() ) + User::LeaveIfError( iPluginSession->GetLocalAddress( myAddr ) ); + TInetAddr peerAddr(iRemoteAddr); + peerAddr.SetPort(0); + TSPINode node; + node.iPropNum = prop->iProposalNum; + node.iSeq = iSeq; + iInboundSPIList->AppendL(node); + + + __ASSERT_DEBUG( iIpsecSaSpiRetriever != NULL, + User::Invariant() ); + iIpsecSaSpiRetriever->Cancel(); + iIpsecSaSpiRetriever->GetIpsecSaSpi( iSeq++, sa_type, peerAddr, myAddr ); + iPendingSPI++; //To know when all received in ReceiveSPIL() + } + + DEBUG_LOG1(_L("GetSPI seq= %d"), iSeq); +} + +//aSPI received in Network order. +void CIkev1Negotiation::ReceiveSPIL(TUint32 aSPI, TUint32 aSeq) +{ + TIkev1IsakmpStream* msg = SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) ); + + DEBUG_LOG2(_L("ReceiveSPIL: SPI=%x, Seq=%u"), ByteOrder::Swap32(aSPI), aSeq); + + CProposal_IIList *propII_List = iProposal_IIList; + TInt i; + for (i = 0; i < iInboundSPIList->Count(); i++) + { + if (iInboundSPIList->At(i).iSeq == aSeq) + { + iInboundSPIList->At(i).iSPI = aSPI; + break; + } + //prop = prop->iNext; //To assign the SPI to the correct proposal + } + if (iRole==INITIATOR) + propII_List->At(i)->iSPI.Copy((TUint8*)&aSPI,sizeof(TUint32)); //needed to send it to the other Peer + + if (--iPendingSPI) // Check if still waiting for some SPI + return; + + iExchange = IKE_QUICK_MODE; //Current mode being used. + //Builds and send the packet + + if ((iHostData->iCommit) && (iRole==RESPONDER)) //Responder && if commit bit used we set the flag + iFlags |= ISAKMP_HDR_CFLAG; //Sets the Commit bit if this side set it else + + msg->IsakmpInit(this); + msg->IsakmpHashL(); + msg->IsakmpSa(); + ComputeNonceL(); //Computes a new Nonce for PHASE_II + msg->IsakmpNonce(); + if (iPFS) //Only sent if PFS in use... + msg->IsakmpKeyL(); + + if (iStage==1) //Initiator + { + // + // If Internal address private extension used change iLocalAddr1_ID_II to + // correspond that address + // + if ( iInternalAddr ) { + iLocalAddr1_ID_II = iInternalAddr->iClientIntAddr; + iLocalIDType_II = ID_IPV4_ADDR; + iDefaultLocalID = ETrue; + } + DEBUG_LOG(_L("PhaseII IV:")); //New IV for phase II + ComputeIVL(iIV, iMessageId); + //IDs must be sent if TUNNEL mode or is explicitly specified in the acquire + if ((!iLocalAddr1_ID_II.IsUnspecified()) || (!iRemoteAddr1_ID_II.IsUnspecified()) || + (iIDProtocol != 0) || (iIDLocalPort != 0) || (iIDRemotePort != 0)) + { + msg->IsakmpOwnIdentL(); //Own proxy + msg->IsakmpPeerIdentL(); //Peer Proxy + } + } + else if (iStage==2) //Responder + { + if (iIDReceived) //If received we send it back, otherwise no + { + msg->IsakmpPeerIdentL(); + msg->IsakmpOwnIdentL(); + } + if (iHostData->iResponderLifetime) + CheckSendResponderLifetime(*msg); //Adds to the message the RESPONDER_LIFETIME payload if needed + } + else return; + + if (iHostData->iReplayStatus) + { + DEBUG_LOG(_L("Constructing REPLAY-STATUS")); + + TInt i; + CProposal_II *prop; + for (i = 0 ; i < iProposal_IIList->Count(); i++) + { + prop = iProposal_IIList->At(i); + msg->IsakmpReplayStatus(prop->iProtocol, iInboundSPIList->At(i).iSPI, prop->iReplayWindowLength); + } + } + msg->IsakmpHashContL(); //inserts the hash in the correct position of the buffer + SendL(*msg); + + iStage++; //Next stage +} + +void CIkev1Negotiation::AcquireSAErrorResponse(TInt aError) + { + DEBUG_LOG(_L("CIkev1Negotiation::AcquireSAErrorResponse")); + + if ( iProposal_IIList ) + { + for ( TInt j=0; jCount(); j++ ) + { + TIpsecSAData sa_data; + sa_data.iSeq = iAcquireSeq; + sa_data.iPid = iPfkeyAcquirePID; + sa_data.iSPI = 0; + sa_data.iDst = iRemoteAddr; + + CProposal_II* prop_II = iProposal_IIList->At( j ); + + if ( prop_II->iProtocol == PROTO_IPSEC_AH ) + { + sa_data.iSAType = SADB_SATYPE_AH; + } + else if ( prop_II->iProtocol == PROTO_IPSEC_ESP ) + { + sa_data.iSAType = SADB_SATYPE_ESP; + } + iPluginSession->AcquireSAError( sa_data, aError ); + } + } + iAcquirePending = EFalse; + } + +//Will update the outbound +void CIkev1Negotiation::UpdateSADatabaseL() +{ +#ifdef _DEBUG + TBuf<40> addr_buf; +#endif + TUint8 sa_type=0; + TUint8 auth_alg=0; + TUint8 encr_alg=0; + TUint32 updateSPI,addSPI; + TIpsecSAData sa_data; + TBool TunnelMode; + // + // Received Phase II key (Might be Auth + Encr keys) + // (Buffers are allocated for max 1024 bits key material + HBufC8* outboundKey_II = HBufC8::NewLC(128); + HBufC8* inboundKey_II = HBufC8::NewLC(128); + TPtrC8 in_authKey(0,0), out_authKey(0,0); + TPtrC8 in_encrKey(0,0), out_encrKey(0,0); + //Identities +#ifdef _UNICODE + TBuf<80> id_work; +#endif + HBufC8* local_id = HBufC8::NewLC(128); + HBufC8* remote_id = HBufC8::NewLC(128); + // ESP UDP Encapsulation extension data + HBufC8* gen_ext_data = HBufC8::NewLC(128); + TPtr8 GenExtData((TUint8*)gen_ext_data->Ptr(), 0, gen_ext_data->Des().MaxLength()); + + DEBUG_LOG(_L("---UPDATING SAD---")); + + if ((!iDefaultLocalID) && (iLocalIDType_II != 0)) + { + switch (iLocalIDType_II) + { + case ID_IPV4_ADDR: + case ID_IPV6_ADDR: +#ifdef _UNICODE + iLocalAddr1_ID_II.OutputWithScope(id_work); + local_id->Des().Copy(id_work); +#else + iLocalAddr1_ID_II.OutputWithScope(local_id->Des()); +#endif + break; + + case ID_IPV4_ADDR_SUBNET: + case ID_IPV6_ADDR_SUBNET: +#ifdef _UNICODE + iLocalAddr1_ID_II.OutputWithScope(id_work); + local_id->Des().Copy(id_work); +#else + iLocalAddr1_ID_II.OutputWithScope(local_id->Des()); +#endif + local_id->Des().AppendFormat(_L8("/%d"),PrefixLen(iLocalAddr2_ID_II)); //PrefixLen can't fail because checked before + break; + default: //Should never come here + DEBUG_LOG1(_L("Local ID type %d not supported"), iLocalIDType_II); + CleanupStack::PopAndDestroy(5); //key buffer, identities and ESP UDP encaps data + return; + } + } + + if ((!iDefaultRemoteID) && (iRemoteIDType_II != 0) ) + { + switch (iRemoteIDType_II) + { + case ID_IPV4_ADDR: + case ID_IPV6_ADDR: +#ifdef _UNICODE + iRemoteAddr1_ID_II.OutputWithScope(id_work); + remote_id->Des().Copy(id_work); +#else + iRemoteAddr1_ID_II.OutputWithScope(remote_id->Des()); +#endif + if ( iSwapRemoteIdType ) + { + if ( iRemoteIDType_II == ID_IPV4_ADDR ) + remote_id->Des().AppendFormat(_L8("/%d"), 32); + else remote_id->Des().AppendFormat(_L8("/%d"), 128); + } + break; + + case ID_IPV4_ADDR_SUBNET: + case ID_IPV6_ADDR_SUBNET: +#ifdef _UNICODE + iRemoteAddr1_ID_II.OutputWithScope(id_work); + remote_id->Des().Copy(id_work); +#else + iRemoteAddr1_ID_II.OutputWithScope(remote_id->Des()); +#endif + if ( !iSwapRemoteIdType ) + remote_id->Des().AppendFormat(_L8("/%d"),PrefixLen(iRemoteAddr2_ID_II)); //PrefixLen can't fail because checked before + break; + + default: //Should never come here + DEBUG_LOG1(_L("Remote ID type %d not supported"), iRemoteIDType_II); + CleanupStack::PopAndDestroy(5); //key buffer, identities and ESP UDP encaps data + return; + } + } + + TUint32 flags = 0; + if (iPFS) + { + flags = SADB_SAFLAGS_PFS; + DEBUG_LOG(_L("PFS enabled")); + } + + TUint32 addPID; + if (iRole==INITIATOR) + addPID = iPfkeyAcquirePID; //Require to remove the Larval SA + else + addPID = iPluginSession->Uid(); + + DEBUG_LOG2(_L("SAD seq= %d , PID= %d"), iAcquireSeq, addPID); + + TInt i, j; + for (i = 0; i < iInboundSPIList->Count(); i++) + { + if (iInboundSPIList->At(i).iPropNum == iProposalNum) + break; + } + + CProposal_II *prop; + TSPINode inboundspi_node; + TInt key_len, encr_len, auth_len; + TChosenAttrib_II *attr_II; + TInt count = iChosenProp_IIList->Count(); + + for (j = 0 ; j < count; j++) + { + prop = iChosenProp_IIList->At(j); + inboundspi_node = iInboundSPIList->At(i); + attr_II = (TChosenAttrib_II *)prop->iAttrList->At(0); //only 1 transform is chosen no matter how many there are + if (prop->iProtocol == PROTO_IPSEC_AH) + { + + sa_type = SADB_SATYPE_AH; + encr_alg = 0; + auth_alg = attr_II->iTransformID; + auth_len = (TInt)HMAC_KeyLength((TUint8)auth_alg); + + TPtr8 AHOutKey((TUint8*)outboundKey_II->Ptr(), 0, outboundKey_II->Des().MaxLength()); + TPtr8 AHInKey((TUint8*)inboundKey_II->Ptr(), 0, inboundKey_II->Des().MaxLength()); + + ComputeKeys2L(prop, auth_len, inboundspi_node, AHOutKey, AHInKey); + in_encrKey.Set(NULL, 0); + out_encrKey.Set(NULL, 0); + in_authKey.Set(inboundKey_II->Ptr(), auth_len/8); + out_authKey.Set(outboundKey_II->Ptr(),auth_len/8); + } + else if (prop->iProtocol == PROTO_IPSEC_ESP) + { + sa_type = SADB_SATYPE_ESP; + encr_alg = attr_II->iTransformID; + if (attr_II->iKeyLength!=0) + encr_len = attr_II->iKeyLength; + else //not sent means constant size or variable and use default + { + switch ( encr_alg ) + { + case ESP_DES_CBC: + encr_len = 64; + break; + case ESP_3DES_CBC: + encr_len = 3*64; + break; + case ESP_NULL: + encr_len = 0; + break; + case ESP_AES_CBC: + encr_len = 128; + break; + default: + encr_len = 0; + break; + + } + } + + if (attr_II->iAuthAlg==DOI_HMAC_MD5) + auth_alg = SADB_AALG_MD5HMAC; + else if (attr_II->iAuthAlg==DOI_HMAC_SHA) + auth_alg = SADB_AALG_SHA1HMAC; + else + auth_alg = 0; + + auth_len = (TInt)HMAC_KeyLength((TUint8)auth_alg); + key_len = encr_len + auth_len; + + TPtr8 ESPOutKey((TUint8*)outboundKey_II->Ptr(), 0, outboundKey_II->Des().MaxLength()); + TPtr8 ESPInKey((TUint8*)inboundKey_II->Ptr(), 0, inboundKey_II->Des().MaxLength()); + ComputeKeys2L(prop, key_len, inboundspi_node, ESPOutKey, ESPInKey); + + in_encrKey.Set(inboundKey_II->Ptr(), encr_len/8); + out_encrKey.Set(outboundKey_II->Ptr(), encr_len/8); + + //If no HMAC selected the next instr does nothing because size will be 0 + in_authKey.Set(inboundKey_II->Ptr() + in_encrKey.Length(),auth_len/8); + out_authKey.Set(outboundKey_II->Ptr() + out_encrKey.Length(),auth_len/8); + // + // Nokia specific NAT traversal info (=ESP UDP tunneling) + // If iNAT_T_Required is true connection is over NAT:ted + // newtork (=local end behind NAT). + // + if ( iNAT_T_Required ) { + flags |= SADB_SAFLAGS_NAT_T; + } + } + else + { + DEBUG_LOG1(_L("Unknown IPsec protocol %d"), prop->iProtocol); + CleanupStack::PopAndDestroy(5); //key buffer, identities and ESP UDP encaps data + return; + } + + updateSPI = inboundspi_node.iSPI; + Mem::Copy((TUint8*)&addSPI, prop->iSPI.Ptr(), sizeof(TUint32)); + + TInetAddr local_addr(iLocalAddr); + local_addr.SetPort(iIDLocalPort); + TInetAddr remote_addr(iRemoteAddr); + remote_addr.SetPort(iIDRemotePort); + + //This will be always outbound + + TInt64 time(0), bytes(0); + TPtrC8 time_ptr(attr_II->iLifeDurationSecs); + TPtrC8 bytes_ptr(attr_II->iLifeDurationKBytes); + if (attr_II->iReducedLifeSecs.Length() != 0) + time_ptr.Set(attr_II->iReducedLifeSecs); + + if (attr_II->iReducedLifeKBytes.Length() != 0) + bytes_ptr.Set(attr_II->iReducedLifeKBytes); + + ComputeLifetimes_II(time_ptr, bytes_ptr, time, bytes); + if (time == 0) //default lifetime applied + time = DEFAULT_IPSEC_SA_LIFETIME; + + if (iHardLifetime > time) + { + DEBUG_LOG2(_L("Time %u, hard lifetime %d"), + I64LOW(time), I64LOW(iHardLifetime)); + time = iHardLifetime; + } + + if (attr_II->iEncMode==DOI_TUNNEL) + { + TunnelMode = ETrue; + DEBUG_LOG(_L("TUNNEL MODE")); +#ifdef _DEBUG + iLocalAddr1_ID_II.OutputWithScope(addr_buf); + DEBUG_LOG1(_L("Local ID: net %S"), &addr_buf); + + if ((iLocalIDType_II == ID_IPV4_ADDR_SUBNET) || (iLocalIDType_II == ID_IPV6_ADDR_SUBNET)) + { + iLocalAddr2_ID_II.OutputWithScope(addr_buf); + DEBUG_LOG1(_L(", mask %S"), &addr_buf); + } + DEBUG_LOG1(_L(" (port %d)"), iIDLocalPort); + iRemoteAddr1_ID_II.OutputWithScope(addr_buf); + DEBUG_LOG1(_L("Remote ID: addr %S"), &addr_buf); + if ((iRemoteIDType_II == ID_IPV4_ADDR_SUBNET) || (iRemoteIDType_II == ID_IPV6_ADDR_SUBNET)) + { + iRemoteAddr2_ID_II.OutputWithScope(addr_buf); + DEBUG_LOG1(_L(", mask %S"), &addr_buf); + } + DEBUG_LOG1(_L(" (port %d)"), iIDRemotePort); +#endif // _DEBUG + + } + else { + TunnelMode = EFalse; + DEBUG_LOG(_L("TRANSPORT MODE")); + } + DEBUG_LOG1(_L("Sec Lifetime set to %u"),I64LOW(time)); + DEBUG_LOG1(_L("KB Lifetime set to %u"),I64LOW(bytes)); + + //Inbound SA. + sa_data.iSAType = sa_type; + sa_data.iSeq = iAcquireSeq; + sa_data.iSrc = remote_addr; + sa_data.iDst = local_addr; + sa_data.iProtocol = iIDProtocol; + sa_data.iSrcIdType = iRemoteIDType_II; + sa_data.iDstIdType = iLocalIDType_II; + sa_data.iSrcIdent.Set((TUint8 *)remote_id->Ptr(), remote_id->Length(), remote_id->Length()); + sa_data.iDstIdent.Set((TUint8 *)local_id->Ptr(), local_id->Length(), local_id->Length()); + sa_data.iPid = iPluginSession->Uid(); + sa_data.iSPI = updateSPI; + sa_data.iAuthAlg = auth_alg; + sa_data.iEncrAlg = encr_alg; + sa_data.iAuthKey.Set(in_authKey); + sa_data.iEncrKey.Set(in_encrKey); + TIpsecSALifetime lifetime(0, bytes, time, 0); + sa_data.iHard = &lifetime; + sa_data.iReplayWindowLength = prop->iReplayWindowLength; + + if ( (sa_type == SADB_SATYPE_ESP) && (GenExtData.Length() == 0) ) { + // + // Store possible NAT traversal info for IPSEC to do ESP UDP encapsulation correctly + // + PFKeyExtDataUtil::BuildUdpEncExtensionData( GenExtData, + iNAT_D_Flags, + (flags & SADB_SAFLAGS_NAT_T), + iHostData->iUseNatProbing, + (TUint16)iHostData->iEspUdpPort, + UDP_KEEPALIVE_TIME, + iLastRemoteAddr, + iRemoteOriginalAddr ); + } + + if ( GenExtData.Length() ) { + sa_data.iGenericExtension.Set(GenExtData); + } + + if ( TunnelMode ) { + // + // Get VPN interface index + // + TUint32 vpnInterfaceIndex = iPluginSession->VpnInterfaceIndex(); + if ( vpnInterfaceIndex != 0 ) + { + sa_data.iInternalAddress.Init( KAfInet6 ); + sa_data.iInternalAddress.SetScope( vpnInterfaceIndex ); + flags |= SADB_SAFLAGS_INT_ADDR; + } + } + sa_data.iFlags = flags; + iPluginSession->UpdateSAL(sa_data); + TIpsecSPI SpiData; + SpiData.iProtocol = sa_type; + SpiData.iSrcAddr = remote_addr; + SpiData.iDstAddr = local_addr; + SpiData.iSPI = updateSPI; + SpiData.iInbound = ETrue; + iPluginSession->AddIpsecSPIToSAL(iSAId, SpiData); + + sa_data.iFlags &= ~SADB_SAFLAGS_INT_ADDR; //No VPN interface index to outbound SA + //Outbound SA. + //First check there's no other SA with the same parameters and + //erase it if happens (very unlikely, but still possible) + SpiData.iDstAddr = remote_addr; + SpiData.iSrcAddr = local_addr; + SpiData.iSPI = addSPI; + SpiData.iInbound = EFalse; + if ( iPluginSession->DeleteIpsecSpi(iSAId, addSPI, EFalse) ) + { + DEBUG_LOG(_L("Deleting previously negotiated IPsec SA")); + iPluginSession->DeleteIpsecSA(SpiData.iSPI, SpiData.iSrcAddr, SpiData.iDstAddr, + SpiData.iProtocol); + } + //Some changes in the SA, the rest is the same + sa_data.iSrc = local_addr; + sa_data.iDst = remote_addr; + sa_data.iSrcIdType = iLocalIDType_II; + sa_data.iDstIdType = iRemoteIDType_II; + sa_data.iSrcIdent.Set((TUint8 *)local_id->Ptr(), local_id->Length(), local_id->Length()); + sa_data.iDstIdent.Set((TUint8 *)remote_id->Ptr(), remote_id->Length(), remote_id->Length()); + sa_data.iPid = addPID; + sa_data.iSPI = addSPI; + sa_data.iAuthKey.Set(out_authKey); + sa_data.iEncrKey.Set(out_encrKey); + + iPluginSession->AddSAL(sa_data); + iPluginSession->AddIpsecSPIToSAL(iSAId, SpiData); + + i++; //To get the correct SPIs from iInboundSPIList + } //end for + + CleanupStack::PopAndDestroy(5); //key buffer, identities and ESP UDP encaps data + + iAcquirePending = EFalse; + +} + +void CIkev1Negotiation::ComputeLifetimes_II(const TDesC8 &aLifetime, const TDesC8 &aLifesize, TInt64 &aTime, TInt64 &aBytes) +{ + TInt64 maxnum = MAKE_TINT64(0x7fffffffu, 0xffffffffu); + + if (Desc8ToTInt64(aLifetime, aTime) != KErrNone) + { + DEBUG_LOG(_L("Phase_II Lifetime(sec) Overflowed Setting to maximum value")); + } + if (Desc8ToTInt64(aLifesize, aBytes) != KErrNone) { + DEBUG_LOG(_L("Phase_II Lifetime(kbytes) Overflowed Setting to maximum value")); + } + else + { if (aBytes < maxnum / 1024) //Make sure no overflow + aBytes = aBytes * 1024; //KB to Bytes + else + { + aBytes = MAKE_TINT64(KMaxTInt, KMaxTUint); + DEBUG_LOG(_L("Phase_II Lifetime(kbytes) Overflowed Setting to maximum value")); + } + } + +} + + +TBool CIkev1Negotiation::Phase_IExchangeL(const ThdrISAKMP &aHdr) +{ + if (!ProcessHeaderL(aHdr)) + return EFalse; + + DEBUG_LOG2(_L("---------- Phase %d - Stage %d ----------"),iPhase, iStage); + if (iPhase == PHASE_I) + { + if (aHdr.GetExchange() == ISAKMP_EXCHANGE_ID) + MainModeReplyL(); //Main Mode + else + AggressiveReplyL(); //Aggressive Mode + } + else + { + QuickModeReplyL(); + } + return ETrue; +} + +TBool CIkev1Negotiation::Phase_IIExchangeL(const ThdrISAKMP &aHdr) +{ + if (!ProcessHeaderL(aHdr)) + return EFalse; + + DEBUG_LOG2(_L("---------- Phase %d - Stage %d ----------"),iPhase, iStage); + + QuickModeReplyL(); + + return ETrue; +} + +void CIkev1Negotiation::QuickModeReplyL() +{ + + TIkev1IsakmpStream* msg = SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) ); + switch(iStage) + { + //INITIATOR cases + case 3: //Send last message (if no COMMIT) + msg->IsakmpInit(this); + msg->IsakmpHashL(); + SendL(*msg); + iStage = 4; + + if (iRecvFlags & ISAKMP_HDR_CFLAG) //Commit Bit set + return; //Not finished yet. We wait for CONNECTED + + //No Commot bit, Update SA database + UpdateSADatabaseL(); + SetFinished(); //No more stages. + break; + case 1: + DEBUG_LOG(_L("QuickModeReplyL in Stage 1 ?")); + break; + case 5: //Send last message (extra message waiting for commit( + //No more processing required + SetFinished(); //No more stages. + break; + //RESPONDER cases + case 2: + GetSPIL(); + //rest done in receiveSPI + break; + case 4: + if (iRecvFlags & ISAKMP_HDR_CFLAG) //Commit Bit set + { + DEBUG_LOG(_L("Sending CONNECTED Status message")); + msg->IsakmpInit(this); + + //HASH Payload only if payload protected with encryption + if (iFlags & ISAKMP_HDR_EFLAG) + msg->IsakmpHashL(); + + msg->IsakmpNotification(CONNECTED, iChosenProp_IIList->At(0)->iProtocol); + + if (iFlags & ISAKMP_HDR_EFLAG) + msg->IsakmpHashContL(); + + SendL(*msg); + } + SetFinished(); + break; + } +} + +//Builds and sends a Phase I reply for Main Mode +void CIkev1Negotiation::MainModeReplyL() +{ + TIkev1IsakmpStream* msg = SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) ); + TInt vendor_type; + + switch(iStage) + { + // + //RESPONDER replies + // + case 2: + msg->IsakmpInit(this); + msg->IsakmpSa(); + if ( iHostData->iDPDHeartBeat != 0 ) + BuildDPDVendorId(*msg); + if ( iNatDiscovery ) { + iNatDiscovery->BuildNatVendorId(*msg); + iNatDiscovery->BuildRfcNatVendorId(*msg); + } + SendL(*msg); + iStage = 3; + break; + case 4: + ComputeNonceL(); //Nonce to be sent + msg->IsakmpInit(this); + msg->IsakmpKeyL(); + msg->IsakmpNonce(); + if (((iChosenProposal_I.iAttrList->iAuthMethod == RSA_SIG) || + (iChosenProposal_I.iAttrList->iAuthMethod == DSS_SIG)) && !iPeerX509Cert) + msg->IsakmpCertificateReqL(); + if ( iNatDiscovery ) { + iNatDiscovery->BuildDiscoveryPayloadsL(*msg, iChosenProposal_I.iAttrList->iHashAlg, + (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(), + iLocalAddr, iLastRemoteAddr); + } + SendL(*msg); + iStage = 5; //next stage + iFlags |= ISAKMP_HDR_EFLAG; //From now on encryption is used + if (!ComputeKeysL()) //Generates keying material for encryption stages + return; //error don't send reply packet + break; + case 6: + msg->IsakmpInit(this); + + switch(iChosenProposal_I.iAttrList->iAuthMethod) + { + case RSA_SIG: + case DSS_SIG: + msg->IsakmpOwnIdentL(); + msg->IsakmpCertificateL(); + msg->IsakmpSignatureL(); + break; + case PRE_SHARED: + msg->IsakmpOwnIdentL(); + msg->IsakmpHashL(); + break; + } + + if ( iHostData->iInitialContact && + iRole == INITIATOR && + iSARekeyInfo == NULL ) + { + DEBUG_LOG(_L("Constructing INITIAL-CONTACT")); + msg->IsakmpNotification(DOI_INITIAL_CONTACT, PROTO_ISAKMP); //Not protected by the hash! + } + + SendL(*msg); + + IsakmpPhase1CompletedL(); + break; + // + //INITIATOR replies + // + case 3: + ComputeNonceL(); //Nonce to be sent + msg->IsakmpInit(this); + msg->IsakmpKeyL(); + msg->IsakmpNonce(); + if ( iChosenProposal_I.iAttrList->iAuthMethod == IKE_A_CRACK && !iPeerX509Cert ) + { + msg->IsakmpCertificateReqL(); + } + if ( iHostData->iUseNatProbing ) + vendor_type = EXPANDED_VENDOR_ID; + else vendor_type = HASH_VENDOR_ID; + msg->IsakmpVendorId(vendor_type, + (TUint8*)iCookie_I.Ptr(), + (TUint8*)iCookie_R.Ptr(), iLocalAddr); + if ( iNatDiscovery ) + { + iNatDiscovery->BuildDiscoveryPayloadsL(*msg, iChosenProposal_I.iAttrList->iHashAlg, + (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(), + iLocalAddr, iLastRemoteAddr); + } + SendL(*msg); + iStage = 4; //next stage + break; + + case 5: + iFlags |= ISAKMP_HDR_EFLAG; //From now on encryption is used + if (!ComputeKeysL()) //Generates keying material for encryption stages + return; //error don't send reply packet + + msg->IsakmpInit(this); + + switch(iChosenProposal_I.iAttrList->iAuthMethod) + { + case RSA_SIG: + case DSS_SIG: + msg->IsakmpOwnIdentL(); //Also fills iOwnIdentPayload! + msg->IsakmpCertificateL(); + msg->IsakmpSignatureL(); + if (!iPeerX509Cert) + msg->IsakmpCertificateReqL(); + break; + case PRE_SHARED: + msg->IsakmpOwnIdentL(); + msg->IsakmpHashL(); + break; + } + + + if ( iFamiliarPeer && iHostData->iUseInternalAddr ) + msg->IsakmpIntnet(0); /* null IPV4 address as parameter */ + + if ( iHostData->iInitialContact && + !iPluginSession->FindIkev1SADataWithAddr(iRemoteAddr) && + iRole == INITIATOR && + iSARekeyInfo == NULL ) + { + DEBUG_LOG(_L("Constructing INITIAL-CONTACT")); + msg->IsakmpNotification(DOI_INITIAL_CONTACT, PROTO_ISAKMP); //Not protected by the hash! + } + + SendL(*msg); + iStage = 6; //next stage + + break; + case 7: + // CRACK authentication going. No actions required here ! + break; + default: + DEBUG_LOG1(_L("Main mode Wrong Phase number requested (%d) !!"),iStage); + } + +} + + +//Builds and sends a Phase I reply for Aggressive Mode +void CIkev1Negotiation::AggressiveReplyL() +{ + TIkev1IsakmpStream* msg = SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) ); + + switch(iStage) + { + case 2://RESPONDER Sends the 2nd msg. of the exchange + ComputeNonceL(); //Nonce to be sent + msg->IsakmpInit(this); + msg->IsakmpSa(); + msg->IsakmpKeyL(); + msg->IsakmpNonce(); + msg->IsakmpOwnIdentL(); + + if (!ComputeKeysL()) //Needed to compute hash before computing signature + { + return; + } + + if ( iHostData->iDPDHeartBeat != 0 ) + BuildDPDVendorId(*msg); + if ( iNatDiscovery ) { + iNatDiscovery->BuildNatVendorId(*msg); + iNatDiscovery->BuildRfcNatVendorId(*msg); + iNatDiscovery->BuildDiscoveryPayloadsL(*msg, iChosenProposal_I.iAttrList->iHashAlg, + (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(), + iLocalAddr, iLastRemoteAddr); + } + + switch (iChosenProposal_I.iAttrList->iAuthMethod) + { + case RSA_SIG: + case DSS_SIG: + msg->IsakmpCertificateL(); + msg->IsakmpSignatureL(); + if (!iPeerX509Cert) //No stored cert so send a CR + { + msg->IsakmpCertificateReqL(); + } + break; + case PRE_SHARED: + msg->IsakmpHashL(); + break; + } + SendL(*msg); + + iStage = 3; //next stage + + break; + case 3://INITIATOR + iFlags |= ISAKMP_HDR_EFLAG; //From now on encryption is used + msg->IsakmpInit(this); + if ( iNatDiscovery ) { + iNatDiscovery->BuildDiscoveryPayloadsL(*msg, iChosenProposal_I.iAttrList->iHashAlg, + (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(), + iLocalAddr, iLastRemoteAddr); + } + + switch (iChosenProposal_I.iAttrList->iAuthMethod) + { + case RSA_SIG: + case DSS_SIG: + msg->IsakmpCertificateL(); + msg->IsakmpSignatureL(); + break; + case PRE_SHARED: + msg->IsakmpHashL(); + break; + } + if ( iHostData->iInitialContact && + !iPluginSession->FindIkev1SADataWithAddr(iRemoteAddr) && + iRole == INITIATOR && + iSARekeyInfo == NULL ) //Only sent if no ISAKMP SA established + { + DEBUG_LOG(_L("Constructing INITIAL-CONTACT")); + msg->IsakmpNotification(DOI_INITIAL_CONTACT, PROTO_ISAKMP); //Not protected by the hash! + } + + SendL(*msg); + IsakmpPhase1CompletedL(); + break; + case 4: + // Aggressive mode as responder completed + DEBUG_LOG(_L("Aggressive mode as responder completed")); + break; + + case 7: + // CRACK authentication going. No actions required here ! + break; + default: + DEBUG_LOG1(_L("Main mode Wrong Phase number requested (%d) !! "),iStage); + } + +} + +void CIkev1Negotiation::SaveISAKMPSAL() +{ + // + // Create a new IKEv1 SA object + // + TIkev1SAData SaData; + SaData.iCookie_I = iCookie_I; + SaData.iCookie_R = iCookie_R; + SaData.iSAId = iSAId; + SaData.iSAState = 0; + SaData.iInitiator = (iRole == INITIATOR); + SaData.iAutoLogin = iAutoLogin; + SaData.iDPDSupported = iDPDSupported; + SaData.iFamiliarPeer = iFamiliarPeer; + SaData.iNAT_T_Required = iNAT_T_Required; + SaData.iNAT_D_Flags = iNAT_D_Flags; + SaData.iIkeData = iHostData; + SaData.iLocalAddr = iLocalAddr; + SaData.iRemoteAddr = iRemoteAddr; + SaData.iDestinAddr = iLastRemoteAddr; + SaData.iVirtualIp = iInternalAddr; + SaData.iSeq = iSeq; + SaData.iPrevExchange = iPrevExchange; + SaData.iFlags = iFlags; + + SaData.iEncrAlg = iChosenProposal_I.iAttrList->iEncrAlg; + SaData.iHashAlg = iChosenProposal_I.iAttrList->iHashAlg; + SaData.iGroupDesc = iChosenProposal_I.iAttrList->iGroupDesc; + SaData.iGroupType = iChosenProposal_I.iAttrList->iGroupType; + SaData.iKeyLength = iChosenProposal_I.iAttrList->iKeyLength; + + TUint32 Lifetime = 0; + TUint Len = iChosenProposal_I.iAttrList->iLifeDurationSecs.Length(); + if (Len > 0) + { + if (Len > sizeof(TUint32)) + { + Lifetime = KMaxTUint32; + } + else // (len <= sizeof(TUint32)) + { + Mem::Copy(&Lifetime, iChosenProposal_I.iAttrList->iLifeDurationSecs.Ptr(), Len); + Lifetime = ByteOrder::Swap32(Lifetime); + Lifetime = Lifetime >> (sizeof(TUint32)*8 - Len*8); //To set the correct value (shift in bits) + } + } + SaData.iLifeTimeSecs = Lifetime; + + Lifetime = 0; + Len = iChosenProposal_I.iAttrList->iLifeDurationKBytes.Length(); + if (Len > 0) + { + if (Len > sizeof(TUint32)) + { + Lifetime = KMaxTUint32; + } + else // (len <= sizeof(TUint32)) + { + Mem::Copy(&Lifetime, iChosenProposal_I.iAttrList->iLifeDurationKBytes.Ptr(), Len); + Lifetime = ByteOrder::Swap32(Lifetime); + Lifetime = Lifetime >> (sizeof(TUint32)*8 - Len*8); //To set the correct value (shift in bits) + } + } + SaData.iLifeTimeKB = Lifetime; + + SaData.iSKEYID = iSKEYID; + SaData.iSKEYID_d = iSKEYID_d; + SaData.iSKEYID_a = iSKEYID_a; + SaData.iSKEYID_e = iSKEYID_e; + SaData.iLastIV = iLastIV; + SaData.iIV = iIV; + + if ( iDPDSupported && iHostData->iDPDHeartBeat ) + { + // + // Initialize DPD protocol parameters in TIkev1SAData + // + TPtr8 ptr((TUint8*)&SaData.iDPDSequence, sizeof(TUint32)); + ptr.SetLength(sizeof(TUint32)); + TRandom::RandomL(ptr); + SaData.iDPDSequence &= 0x7fffffff; + SaData.iDPDRetry = 0; + SaData.iPendingDPDSequence = 0; + SaData.iExpectedDPDSequence = 0; + } + + iLastIKEMsgInfo.Store(SaData.iLastIKEMsgInfo); + SaData.iLastMsg = iLastMsg; + iPluginSession->CreateIkev1SAL(SaData, iSARekeyInfo); // Add rekey info later +} + +TBool CIkev1Negotiation::ProcessHeaderL(const ThdrISAKMP &aHdr) +{ + //checks on the header + if (!CheckCookies(aHdr.GetCookieI(), aHdr.GetCookieR())) + return EFalse; + + if (iStage == 1) + { + if (iPhase == PHASE_I) + { + iCookie_I = aHdr.GetCookieI(); //save initiator cookie + iCookie_R = CreateCookieL(); //create responder cookie + } + iMessageId = aHdr.GetMessageId(); + } + + //checks on the header + if (!CheckPayloadCode(aHdr.GetPayload())) + return EFalse; + + if (!CheckVersionL(aHdr.GetVersion())) + return EFalse; + + if (!CheckExchangeTypeL(aHdr.GetExchange())) + return EFalse; + + if (!CheckFlagsL(aHdr.GetFlags())) + return EFalse; + iRecvFlags = aHdr.GetFlags(); //Save the flags for later use + + if (!CheckMessageIdL(aHdr.GetMessageId())) + return EFalse; + + iLengthLeft -= ISAKMP_HEADER_SIZE; //Updates the length left in the buffer + + //EVEN stages RESPONDER, ODD ones INITIATOR + DEBUG_LOG(_L("Processing packet...")); + if (iPhase == PHASE_I) + { + switch (iStage) + { + case 1: + if (!ProcessStage1L(aHdr)) + return EFalse; + break; + case 2: + if (!ProcessStage2L(aHdr)) + return EFalse; + break; + case 3: + if (iExchange == ISAKMP_EXCHANGE_ID) + { + if (!ProcessStage3MainL(aHdr)) + return EFalse; + } + else //ISAKMP_EXCHANGE_AGGR + { + if (!ProcessStage3AggrL(aHdr)) + return EFalse; + } + break; + case 4: + if (!ProcessStage4L(aHdr)) + return EFalse; + break; + case 5: + if (!ProcessStage5L(aHdr)) + return EFalse; + break; + case 6: + if (!ProcessStage6L(aHdr)) + return EFalse; + break; + case 7: + if (!ProcessStage7L(aHdr)) /* For CRACK negotiation */ + return EFalse; + break; + default: + return EFalse; + } + } + else //PHASE_II + { + switch (iStage) + { + case 1: + if (!ProcessStage1Phase2L(aHdr)) + return EFalse; + break; + case 2: + if (!ProcessStage2Phase2L(aHdr)) + return EFalse; + break; + case 3: + if (!ProcessStage3Phase2L(aHdr)) + return EFalse; + break; + case 4: + if (!ProcessCONNECTEDL(aHdr)) + return EFalse; + break; + default: + DEBUG_LOG(_L("Quick Bad Stage")); + } + } + return ETrue; +} + +//Process payloads appearing in Stage 1. Responder Role +TBool CIkev1Negotiation::ProcessStage1L(const ThdrISAKMP &aHdr) +{ + CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug); + if (!payload) + return EFalse; + + CleanupStack::PushL(payload); + + //SA Payload processing (all modes) + if (!ProcessSAL(payload->iSa, NULL)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + //Process vendor ID:s + ProcessVendorL(payload->iVids); + + TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod; + + switch (auth_method) + { + case RSA_SIG: + case DSS_SIG: + //Process the possible CR payloads + if ( !ProcessCertificateReqArrayL(payload->iCertReqs) ) { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + //Process the possible CERT payloads + if ( !ProcessCertificateArrayL(payload->iCerts) ) { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + break; + + default: + break; + } + + + if (iExchange == ISAKMP_EXCHANGE_ID) + { + if ( payload->iKe || payload->iNonce || payload->iHash || payload->iSign || + payload->iIds->Count() ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + } + else //ISAKMP_EXCHANGE_AGGR + { + if ( !payload->iKe || !payload->iNonce || (payload->iIds->Count() != 1) ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + //Key Payload processing (all modes) + if (!ProcessKeyL(payload->iKe)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + TIdentISAKMP* id_payload = (TIdentISAKMP*)payload->iIds->At(0); // The first ID + TNonceISAKMP* nonce_payload = (TNonceISAKMP*)payload->iNonce; + + //Nonce Payload processing + if (!ProcessNonceL(nonce_payload)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + //ID Payload processing + if (!CheckIdentL(id_payload)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + //Save the ident payload for HASH_I/R computing + delete iPeerIdentPayload; + iPeerIdentPayload = NULL; + iPeerIdentPayloadSize = id_payload->GetLength() - sizeof(TPayloadISAKMP); + iPeerIdentPayload = new (ELeave) TUint8[iPeerIdentPayloadSize]; + Mem::Copy(iPeerIdentPayload,((TUint8 *)id_payload)+sizeof(TPayloadISAKMP),iPeerIdentPayloadSize); + + if ( iNatDiscovery ) + { + if ( payload->iNatDs->Count() ) + { + iNAT_D_Flags = iNatDiscovery->CheckDiscoveryPayloadsL(payload->iNatDs, iChosenProposal_I.iAttrList->iHashAlg, + (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(), + iLocalAddr, iLastRemoteAddr); + if ( iNAT_D_Flags ) + iLastRemoteAddr.SetPort(FLOATED_IKE_PORT); + } + else + { + if ( iLastRemoteAddr.Port() == FLOATED_IKE_PORT ) + iNAT_D_Flags |= LOCAL_END_NAT; + } + } + + }//end aggressive + + + CleanupStack::PopAndDestroy(); //payload + iStage = 2; + return ETrue; + +} + +//Process payloads appearing in Stage 3. Initiator Role +TBool CIkev1Negotiation::ProcessStage2L(const ThdrISAKMP &aHdr) +{ + CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug); + if (!payload) + return EFalse; + + CleanupStack::PushL(payload); + + iCookie_R = aHdr.GetCookieR(); //Save the responder Cookie + + //SA Payload processing (all modes) + if (!ProcessSAL(payload->iSa, NULL)) { + CleanupStack::PopAndDestroy(); // payload + return EFalse; + } + + ProcessVendorL(payload->iVids); + + if ( iAutoLogin && (iLocalAddr.Family() == KAFUnspec ) ) { + User::LeaveIfError( iPluginSession->GetLocalAddress( iLocalAddr ) ); //No local address, get it now (used later with NAT traversal) + } + + //NOW we know the auth method chosen! + TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod; + + switch (auth_method) + { + case RSA_SIG: + case DSS_SIG: + //Process the possible CR payloads + if ( !ProcessCertificateReqArrayL(payload->iCertReqs) ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + if (!ProcessCertificateArrayL(payload->iCerts)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + break; + + default: + break; + } + + if (iExchange == ISAKMP_EXCHANGE_ID) + { + if ( payload->iKe || payload->iNonce || payload->iHash || payload->iSign || + payload->iIds->Count() ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + } + else //ISAKMP_EXCHANGE_AGGR + { + if ( !payload->iKe || + !payload->iNonce || + (!payload->iHash && auth_method == PRE_SHARED) // hash is a must only with PSK + || (payload->iIds->Count() != 1) ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + //Key Payload processing (all modes) + if (!ProcessKeyL(payload->iKe)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + TIdentISAKMP* id_payload = (TIdentISAKMP*)payload->iIds->At(0); // The first ID + TNonceISAKMP* nonce_payload = (TNonceISAKMP*)payload->iNonce; + + //Nonce Payload processing + if (!ProcessNonceL(nonce_payload)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + //ID Payload processing + if (!CheckIdentL(id_payload)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + //Save the ident payload for HASH_I/R computing + delete iPeerIdentPayload; + iPeerIdentPayload = NULL; + iPeerIdentPayloadSize = id_payload->GetLength()-sizeof(TPayloadISAKMP); + iPeerIdentPayload = new (ELeave) TUint8[iPeerIdentPayloadSize]; + Mem::Copy(iPeerIdentPayload,((TUint8 *)id_payload)+sizeof(TPayloadISAKMP),iPeerIdentPayloadSize); + + if (!ComputeKeysL()) //Computes the keys to be used. Needed to compute HASH_R + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + switch (auth_method) + { + case PRE_SHARED: + if (!ProcessHashL(payload->iHash)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + DEBUG_LOG(_L("HASH OK!")); + break; + case RSA_SIG: + case DSS_SIG: + case IKE_A_CRACK: + //Signature payload processing and checking + if (!ProcessSignatureL(payload->iSign)) { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + if ( auth_method == IKE_A_CRACK ) { + CleanupStack::PopAndDestroy(); //payload + return StartCRACKAuthL(); + } + else { + if (!CertifyRemoteIdentityL(id_payload)) + { + DEBUG_LOG(_L("ProcessStage2L RSA_SIG CertifyRemoteIdentityL failed")); + DEBUG_LOG(_L("AUTHENTICATION_FAILED")); + SetErrorStatus( KKmdIkeAuthFailedErr ); + SendNotifyL(AUTHENTICATION_FAILED); + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + } + break; + + default: + break; + + } + + if ( iNatDiscovery && payload->iNatDs->Count()) { + iNAT_D_Flags = iNatDiscovery->CheckDiscoveryPayloadsL(payload->iNatDs, iChosenProposal_I.iAttrList->iHashAlg, + (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(), + iLocalAddr, iLastRemoteAddr); + if ( iNAT_D_Flags ) + iLastRemoteAddr.SetPort(FLOATED_IKE_PORT); + } + } + + CleanupStack::PopAndDestroy(); //payload + + iStage = 3; + return ETrue; +} + +// Process payloads appearing in Stage 4. Order NOT relevant. Only Main Mode +// Handles message: HDR, KE, [HASH(1),] PubKey_r, PubKey_r for RSAENCR +// Handles message: HDR, KE, Ni for the rest [CERTREQ] in certificates +TBool CIkev1Negotiation::ProcessStage3MainL(const ThdrISAKMP &aHdr) +{ + CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug); + if (!payload) + return EFalse; + + CleanupStack::PushL(payload); + + if ( payload->iSa || !payload->iNonce || payload->iHash || payload->iSign ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod; + + //Process payloads + //Main mode (ONLY) + //Key Payload processing (all methods) + if (!ProcessKeyL(payload->iKe)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + if ((auth_method == RSA_SIG) || (auth_method == DSS_SIG)) + { + //Process the possible CR payloads + if ( !ProcessCertificateReqArrayL(payload->iCertReqs) ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + } + + TNonceISAKMP* nonce_payload = (TNonceISAKMP*)payload->iNonce; + + ProcessVendorL(payload->iVids); + + if ( iNatDiscovery && payload->iNatDs->Count() ) + { + iNAT_D_Flags = iNatDiscovery->CheckDiscoveryPayloadsL(payload->iNatDs, iChosenProposal_I.iAttrList->iHashAlg, + (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(), + iLocalAddr, iLastRemoteAddr); + if ( iNAT_D_Flags ) + iLastRemoteAddr.SetPort(FLOATED_IKE_PORT); + } + + //Nonce Payload processing (all methods) + TBool Status = ProcessNonceL(nonce_payload); + if ( Status ) + { + iStage = 4; + } + CleanupStack::PopAndDestroy(); //payload + + return Status; +} + + +//Process payloads appearing in 3(Aggressive). Order NOT relevant +TBool CIkev1Negotiation::ProcessStage3AggrL(const ThdrISAKMP &aHdr) +{ + CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug); + if (!payload) + return EFalse; + + CleanupStack::PushL(payload); + + TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod; + + //Mode-dependent processing + switch (auth_method) + { + case PRE_SHARED: + //Hash payload processing + if (!ProcessHashL(payload->iHash)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + DEBUG_LOG(_L("HASH OK!")); + break; + case RSA_SIG: + case DSS_SIG: + //Certificate payload processing + if (!ProcessCertificateArrayL(payload->iCerts)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + //Signature payload processing + if (!ProcessSignatureL(payload->iSign)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + break; + + default: + break; + } + + ProcessVendorL(payload->iVids); + + if ( iNatDiscovery && payload->iNatDs->Count() ) { + iNAT_D_Flags = iNatDiscovery->CheckDiscoveryPayloadsL(payload->iNatDs, iChosenProposal_I.iAttrList->iHashAlg, + (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(), + iLocalAddr, iLastRemoteAddr); + if ( iNAT_D_Flags ) + iLastRemoteAddr.SetPort(FLOATED_IKE_PORT); + } + + CleanupStack::PopAndDestroy(); //payload + + iFlags |= ISAKMP_HDR_EFLAG; //From now on encryption is used + IsakmpPhase1CompletedL(); + iStage = 4; + return ETrue; + +} + + +//Process payloads appearing in Stage 5. Order NOT relevant. ONLY for MAIN Mode +// Preshared and signatures: HDR, KE, Nr +// RSA Encr. : HDR, PubKey_i, PubKey_i +// RSA Revised Encr. : HDR, PubKey_i , Ke_r, Ke_r +TBool CIkev1Negotiation::ProcessStage4L(const ThdrISAKMP &aHdr) +{ + CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug); + if (!payload) + return EFalse; + + CleanupStack::PushL(payload); + + if ( payload->iSa || !payload->iNonce || !payload->iKe ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod; + + if ((auth_method == RSA_SIG) || (auth_method == DSS_SIG)) + { + //Process the possible CR payloads + if ( !ProcessCertificateReqArrayL(payload->iCertReqs) ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + } + + //Key Payload processing (all methods) + if (!ProcessKeyL(payload->iKe)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + if ( auth_method != PRE_SHARED ) { + if (!ProcessCertificateArrayL(payload->iCerts)) { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + } + TNonceISAKMP* nonce_payload = (TNonceISAKMP*)payload->iNonce; + + //Nonce Payload processing (all modes) + TBool Status = ProcessNonceL(nonce_payload); + if (!Status) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + ProcessVendorL(payload->iVids); + + if ( iNatDiscovery && payload->iNatDs->Count() ) + { + iNAT_D_Flags = iNatDiscovery->CheckDiscoveryPayloadsL(payload->iNatDs, iChosenProposal_I.iAttrList->iHashAlg, + (TUint8*)iCookie_I.Ptr(), (TUint8*)iCookie_R.Ptr(), + iLocalAddr, iLastRemoteAddr); + if ( iNAT_D_Flags ) + iLastRemoteAddr.SetPort(FLOATED_IKE_PORT); + } + + if ( auth_method == IKE_A_CRACK ) + { + /*--------------------------------------------------- + * Process message: HDR, [CERT], KEr, Nr, SIG + * - Verify CRACK signature and if OK + * - Initialize CRACK authentication + *---------------------------------------------------*/ + Status = ComputeKeysL(); + if ( Status ) //Generates keying material for encryption stages + { + Status = ProcessSignatureL(payload->iSign); + if ( Status ) //Signature payload processing and checking + { + Status = StartCRACKAuthL(); + } + } + } + else + { + iStage = 5; + } + + CleanupStack::PopAndDestroy(); //payload + return Status; +} + + +//Process payloads appearing in Stage 6. Order NOT relevant +TBool CIkev1Negotiation::ProcessStage5L(const ThdrISAKMP &aHdr) +{ + CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug); + if (!payload) + return EFalse; + + CleanupStack::PushL(payload); + if ( payload->iSa || payload->iNonce || payload->iKe ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod; + TIdentISAKMP* id_payload = NULL; + // ID Payload processing (all modes) + if ( payload->iIds->Count() != 1 ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + id_payload = (TIdentISAKMP*)payload->iIds->At(0); // The first ID + if (!CheckIdentL(id_payload)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + //Save the ident payload for HASH_I/R computing + delete iPeerIdentPayload; + iPeerIdentPayload = NULL; + iPeerIdentPayloadSize=id_payload->GetLength()-sizeof(TPayloadISAKMP); + iPeerIdentPayload = new (ELeave) TUint8[iPeerIdentPayloadSize]; + Mem::Copy(iPeerIdentPayload,((TUint8 *)id_payload)+sizeof(TPayloadISAKMP),iPeerIdentPayloadSize); + + //Mode-dependent processing + switch (auth_method) + { + case PRE_SHARED: + //Hash payload processing + if (!ProcessHashL(payload->iHash)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + DEBUG_LOG(_L("HASH OK!")); + break; + case RSA_SIG: + case DSS_SIG: + //Certificate payload processing + if (!ProcessCertificateArrayL(payload->iCerts)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + if (!CertifyRemoteIdentityL(id_payload)) + { + DEBUG_LOG(_L("ProcessStage5L RSA_SIG CertifyRemoteIdentityL failed")); + DEBUG_LOG(_L("AUTHENTICATION_FAILED")); + SetErrorStatus( KKmdIkeAuthFailedErr ); + SendNotifyL(AUTHENTICATION_FAILED); + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + //Signature payload processing and checking + if (!ProcessSignatureL(payload->iSign)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + //Process the possible CR payloads (needed if we are responder) + if ( iRole == RESPONDER ) + { + if ( !ProcessCertificateReqArrayL(payload->iCertReqs) ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + if ( !iOwnCert ) + ReadOwnCertL(); // Peer does not required a specific cert. Get any + } + break; + + default: + break; + }//end switch + + // Process notification payloads + TInt i = 0; + while ( i < payload->iNotifs->Count() ) { + if (!ProcessNotificationL(payload->iNotifs->At(i))) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + i ++; + } + + ProcessVendorL(payload->iVids); + + CleanupStack::PopAndDestroy(); //payload + + if (iExchange == ISAKMP_EXCHANGE_ID) + iStage = 6; + else iStage = 3; + + return ETrue; +} + + +//Process payloads appearing in Stage 6(Main) Order NOT relevant +TBool CIkev1Negotiation::ProcessStage6L(const ThdrISAKMP &aHdr) +{ + CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug); + if (!payload) + return EFalse; + + CleanupStack::PushL(payload); + if ( payload->iSa || payload->iNonce || payload->iKe ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + + TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod; + TIdentISAKMP* id_payload = NULL; + //ID Payload processing (all modes) + if ( payload->iIds->Count() != 1 ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + id_payload = (TIdentISAKMP*)payload->iIds->At(0); // The first ID + if (!CheckIdentL(id_payload)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + //Save the ident payload for HASH_I/R computing + delete iPeerIdentPayload; + iPeerIdentPayload = NULL; + iPeerIdentPayloadSize=id_payload->GetLength()-sizeof(TPayloadISAKMP); + iPeerIdentPayload = new (ELeave) TUint8[iPeerIdentPayloadSize]; + Mem::Copy(iPeerIdentPayload,((TUint8 *)id_payload)+sizeof(TPayloadISAKMP),iPeerIdentPayloadSize); + + //Mode-dependent processing + switch (auth_method) + { + case PRE_SHARED: + //Hash payload processing + if (!ProcessHashL(payload->iHash)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + DEBUG_LOG(_L("HASH OK!")); + break; + case RSA_SIG: + case DSS_SIG: + //Certificate payload processing + if (!ProcessCertificateArrayL(payload->iCerts)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + if (!CertifyRemoteIdentityL(id_payload)) + { + DEBUG_LOG(_L("ProcessStage6L RSA_SIG CertifyRemoteIdentityL failed")); + DEBUG_LOG(_L("AUTHENTICATION_FAILED")); + SetErrorStatus( KKmdIkeAuthFailedErr ); + SendNotifyL(AUTHENTICATION_FAILED); + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + //Signature payload processing and checking + if (!ProcessSignatureL(payload->iSign)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + break; + default: + break; + } + + // Process notification payloads + TInt i = 0; + while ( i < payload->iNotifs->Count() ) { + if (!ProcessNotificationL(payload->iNotifs->At(i))) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + i ++; + } + + ProcessVendorL(payload->iVids); + // Internal address payload processing + ProcessIntAddrL(payload->iIaddr); + + CleanupStack::PopAndDestroy(); //payload + + return IsakmpPhase1CompletedL(); + +} + +//Process payloads appearing in Stage 7 = CRACK authentication going +TBool CIkev1Negotiation::ProcessStage7L(const ThdrISAKMP &aHdr) +{ +TBool status = ETrue; +TInt crack_status; + + if ( iCRACKneg ) { + crack_status = iCRACKneg->ExecuteCRACKMsgL(aHdr); + + switch ( crack_status ) { + + case CRACK_SUCCESS: + /*------------------------------------------------------- + * CRACK authentication has been succesfully completed + * Take actions to start Quick mode negotiation + *------------------------------------------------------*/ + delete iCRACKneg; + iCRACKneg = NULL; + iLastIV.Copy(iIV); //Saves last IV in Phase 1 + DEBUG_LOG(_L("Last IV Saved!")); + IsakmpPhase1CompletedL(); + break; + + case CRACK_CONTINUE: + /*---------------------------------------------------------- + * CRACK authentication continues, no further actions needed + *----------------------------------------------------------*/ + break; + + case CRACK_IGNORE_MSG: + /*---------------------------------------------------------- + * CRACK authentication continues, received message ignored + *----------------------------------------------------------*/ + status = EFalse; + break; + + default: + /*---------------------------------------------------------- + * CRACK authentication failed, negotiation failed + *----------------------------------------------------------*/ + LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError, + R_VPN_MSG_VPN_GW_AUTH_FAIL, + KKmdIkeAuthFailedErr, + iPluginSession->VpnIapId(), + &iRemoteAddr ); + status = EFalse; + SetErrorStatus(KKmdIkeAuthFailedErr); + AcquireSAErrorResponse(KKmdIkeAuthFailedErr); + break; + + } + } + + return status; +} + +//Called as a RESPONDER for PHASE_II +//Checks HASH(1),SA,KE,NONCE,[ID,ID] from INITIATOR +TBool CIkev1Negotiation::ProcessStage1Phase2L(const ThdrISAKMP &aHdr) +{ + CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug); + if (!payload) + return EFalse; + + CleanupStack::PushL(payload); + + if ( !payload->iSa || !payload->iNonce ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + //Payload Processing + + CProposal_IIList *recv_proposals = new (ELeave) CProposal_IIList(1); //, *prop + CleanupStack::PushL(recv_proposals); + + //SA + if (!ProcessSAL(payload->iSa, (TUint8 *)recv_proposals)) + { + CleanupStack::PopAndDestroy(2); //recv_proposals + payload + return EFalse; + } + + //ID payloads (if existing) + if ( payload->iIds->Count() == 2 ) + { + if (!ProcessStage1_II_IDsL(payload->iIds->At(0), payload->iIds->At(1), recv_proposals)) + { + CleanupStack::PopAndDestroy(2); //recv_proposals + payload + return EFalse; + } + } + else if ( payload->iIds->Count() != 0 ) + { + DEBUG_LOG(_L("Unsupported Phase II ID payload count")); + CleanupStack::PopAndDestroy(2); //recv_proposals + payload + return EFalse; + } + //After ID to know what address to search in the "SAD" + TInt err = BuildProposals2L(); + if (err != KErrNone) + { + DEBUG_LOG(_L("NO_PROPOSAL_CHOSEN: No policy matching")); + SendNotifyL(NO_PROPOSAL_CHOSEN); + CleanupStack::PopAndDestroy(2); //recv_proposals + payload + return EFalse; + } + + //Contains the transform nums matching if multiple proposals + CTransModifierList *trans_array = new (ELeave) CTransModifierList(1); + CleanupStack::PushL(trans_array); + + TInt num = iProposal_IIList->MultiMatchL(recv_proposals, iRole == RESPONDER, trans_array);//If RESPONDER relaxed comparison (no lifetimes checked) + iProposalNum = num; // Set to num not 1 +#ifdef _DEBUG + TBuf<128> err_buf; +#endif + if (num < 0) + { +#ifdef _DEBUG + err_buf.Copy(_L("NO_PROPOSAL_CHOSEN: Phase II proposal not accepted - ")); + AppendAttributeError(num, err_buf); + DEBUG_LOG(err_buf); +#endif + SetErrorStatus( KKmdIkeNoProposalErr ); + SendNotifyL(NO_PROPOSAL_CHOSEN); + CleanupStack::PopAndDestroy(3); //transarray + recv_proposals + payload + return EFalse; + } + + //Copy the chosen transform + //Actually is the same one as recv_proposals because we should always receive a single proposal with a single transform. + CreateChosenProposalL(recv_proposals, num, trans_array); + + CleanupStack::PopAndDestroy(2); //transarray + recv_proposals + + //Process the possible NOTIFICATION payloads + for (TInt i = 0; i < payload->iNotifs->Count(); i++) + { + if (!ProcessNotificationL(payload->iNotifs->At(i))) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + } + + if (!ProcessNonceL(payload->iNonce)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + //HASH + if (!ProcessHash2L(aHdr, payload->iHash, payload->iPadding)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + if (!ProcessKeyL(payload->iKe)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + ProcessVendorL(payload->iVids); + + if ( iNatDiscovery ) { + iNAT_D_Flags |= iNatDiscovery->GetPeerOriginalAddress(payload->iNatOa, iRemoteOriginalAddr, iChosenProp_IIList); + } + + CleanupStack::PopAndDestroy(); //notif_payload_array + iStage = 2; + return ETrue; +} + +//Creates a new proposal list from a selected part of another list (Certain proposal and transforms) +void CIkev1Negotiation::CreateChosenProposalL(CProposal_IIList* aPropList, TInt aPropNum, CTransModifierList *aTransArray) +{ + + CProposal_II *prop, *new_propII; + TAttrib_II *attr_II; + TChosenAttrib_II *new_attr_II; + TInt count = aPropList->Count(); + TInt i = 0; + TInt j = 0; + + // + // Find selected proroposal from list + // + while ( i < count) + { + if (aPropList->At(i)->iProposalNum == aPropNum) + break; + i ++; + } + + TTransModifier *tmodif; + TInt64 own_time, own_bytes, peer_time, peer_bytes; + delete iChosenProp_IIList; //Must be erased because can contain data from previous retransmissions + iChosenProp_IIList = NULL; + iChosenProp_IIList = new (ELeave) CProposal_IIList(1); + while ( i < count ) + { + prop = aPropList->At(i); + if ( prop->iProposalNum != aPropNum) + break; // Stop, another Proposal + + new_propII = new (ELeave) CProposal_II(); + CleanupStack::PushL(new_propII); + new_propII->ConstructL(1); + iChosenProp_IIList->AppendL(new_propII); + CleanupStack::Pop(); //new_propII safe + + new_propII->iProtocol = prop->iProtocol; + new_propII->iNumTransforms = 1; //We only choose 1 transform for each proposal + new_propII->iProposalNum = (TUint8)aPropNum; + new_propII->iSPI.Copy(prop->iSPI); + tmodif = aTransArray->At(j); + new_propII->iReplayWindowLength = tmodif->iReplayWindowLength; + + attr_II = prop->iAttrList->At(tmodif->iTransNum); //look for the chosen transform in the prop + ComputeLifetimes_II(tmodif->iReducedLifeSecs, tmodif->iReducedLifeKBytes, own_time, own_bytes); + ComputeLifetimes_II(attr_II->iLifeDurationSecs, attr_II->iLifeDurationKBytes, peer_time, peer_bytes); + + //Only copy the chosen transform + new_attr_II = new (ELeave) TChosenAttrib_II(); + CleanupStack::PushL(new_attr_II); + new_attr_II->Copy(*attr_II); + if ((peer_time > own_time) && (own_time != 0)) + { + new_attr_II->iReducedLifeSecs.Set(tmodif->iReducedLifeSecs); + DEBUG_LOG1(_L("Lifetime bigger than the one set. Reducing to %d"), own_time); + } + else + new_attr_II->iReducedLifeSecs.Set(NULL, 0); + + if ((peer_bytes > own_bytes) && (own_bytes != 0)) + { + new_attr_II->iReducedLifeKBytes.Set(tmodif->iReducedLifeKBytes); + DEBUG_LOG1(_L("Lifesize bigger than the one set. Reducing to %d"), own_bytes); + } + else + new_attr_II->iReducedLifeKBytes.Set(NULL, 0); + + new_propII->iAttrList->AppendL(new_attr_II); + CleanupStack::Pop(); //new_attrII safe + + j++; // Next transform modifer + i++; // Next proposal + + } +} + + +//Called as a INITIATOR for PHASE_II +//Checks HASH(1),SA, ,NONCE,[KE] [ID,ID] from RESPONDER +TBool CIkev1Negotiation::ProcessStage2Phase2L(const ThdrISAKMP &aHdr) +{ + CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug); + if (!payload) + return EFalse; + + CleanupStack::PushL(payload); + + if ( !payload->iSa || !payload->iNonce ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + CProposal_IIList *recv_proposals = new (ELeave) CProposal_IIList(1); + CleanupStack::PushL(recv_proposals); + + //SA + if (!ProcessSAL(payload->iSa, (TUint8 *)recv_proposals)) + { + CleanupStack::PopAndDestroy(2); //recv_proposals + payload + return EFalse; + } + + //ID payloads (if existing) + if ( payload->iIds->Count() == 2 ) + { + if (!ProcessStage2_II_IDsL(payload->iIds->At(0), payload->iIds->At(1))) + { + CleanupStack::PopAndDestroy(2); //recv_proposals + payload + return EFalse; + } + } + else if ( payload->iIds->Count() != 0 ) + { + DEBUG_LOG(_L("Unsupported Phase II ID payload count")); + CleanupStack::PopAndDestroy(2); //recv_proposals + payload + return EFalse; + } + + //Contains the transform nums matching if multiple proposals + CTransModifierList *trans_array = new (ELeave) CTransModifierList(1); + CleanupStack::PushL(trans_array); + + //Check the received proposals match the proposed one (Got from + //acquire msg.) + TInt num = iProposal_IIList->MultiMatchL(recv_proposals, iRole == RESPONDER, trans_array);//If RESPONDER relaxed comparison (no lifetimes checked) +#ifdef _DEBUG + TBuf<128> err_buf; +#endif + if (num < 0) + { +#ifdef _DEBUG + err_buf.Copy(_L("BAD_PROPOSAL_SYNTAX: Phase II reply doesn't match proposal - ")); + AppendAttributeError(num, err_buf); + DEBUG_LOG(err_buf); +#endif + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(BAD_PROPOSAL_SYNTAX); + CleanupStack::PopAndDestroy(3); //transarray + recv_proposals + payload + return EFalse; + } + // iProposalNum set to correspond local proposal numbering + iProposalNum = trans_array->At(0)->iPropNum; + //Copy the chosen transform + CreateChosenProposalL(recv_proposals, num, trans_array); + + CleanupStack::PopAndDestroy(2); //transarray + recv_proposals + + //Process the possible NOTIFICATION payloads + for (TInt i = 0; i < payload->iNotifs->Count(); i++) + { + if (!ProcessNotificationL(payload->iNotifs->At(i))) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + } + //NONCE + if (!ProcessNonceL(payload->iNonce)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + //HASH + if (!ProcessHash2L(aHdr, payload->iHash, payload->iPadding)) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + //KEY (if present (PFS)) + if (!ProcessKeyL(payload->iKe)) + { + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(PAYLOAD_MALFORMED); + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + ProcessVendorL(payload->iVids); + + if ( iNatDiscovery ) { + iNAT_D_Flags |= iNatDiscovery->GetPeerOriginalAddress(payload->iNatOa, iRemoteOriginalAddr, iChosenProp_IIList); + } + + if ( iRecvFlags & ISAKMP_HDR_CFLAG ) //Commit Bit set + { + iFlags |= ISAKMP_HDR_CFLAG; //Sets the Commit bit if this side set it else + DEBUG_LOG(_L("SAD update delayed until CONNECTED received")); + } + + CleanupStack::PopAndDestroy(); //payload + iStage = 3; + return ETrue; + +} + +TBool CIkev1Negotiation::ProcessStage3Phase2L(const ThdrISAKMP &aHdr) +{ + CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug); + if (!payload) + return EFalse; + + CleanupStack::PushL(payload); + + if ( payload->iSa || payload->iNonce || payload->iKe || payload->iIds->Count() != 0 ) + { + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + //Hash Payload + TBool Status = ProcessHash2L(aHdr, payload->iHash, payload->iPadding); + if ( Status ) + { + //END OF THE PHASE II (Quick mode) negotiation. + //Now we need to update the PFKEY SA database + ProcessVendorL(payload->iVids); + UpdateSADatabaseL(); + iStage = 4; + } + CleanupStack::PopAndDestroy(); //payload + return Status; +} + +TBool CIkev1Negotiation::ProcessCONNECTEDL(const ThdrISAKMP &aHdr) +{ + CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *this, iDebug); + if (!payload) + return EFalse; + + CleanupStack::PushL(payload); + + if ( !payload->iHash || (payload->iNotifs->Count() != 1) || payload->iSa || + payload->iNonce || payload->iKe || (payload->iIds->Count() != 0) ) + { + DEBUG_LOG(_L("PAYLOAD_MALFORMED (no hash or notfic payload)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(PAYLOAD_MALFORMED); + CleanupStack::PopAndDestroy(); //payload + return EFalse; + } + + //Checks if the hash value is OK. Here because need the + //notification payload + const TNotificationISAKMP* notif_payload = payload->iNotifs->At(0); + TBool Status = VerifyInformationalHashL(payload->iHash, notif_payload, iMessageId); + if ( Status ) + { //Hash OK + if ((notif_payload->GetDOI() == IPSEC_DOI) && (notif_payload->GetMsgType() == CONNECTED)) + { + //END OF THE PHASE II (Quick mode) negotiation. + //Now we need to update the PFKEY SA database + DEBUG_LOG(_L("CONNECTED message received. Updating SAD")); + UpdateSADatabaseL(); + iStage = 5; + } + } + else + { + DEBUG_LOG(_L("AUTHENTICATION_FAILED (Informational hash)")); + SetErrorStatus( KKmdIkeAuthFailedErr ); + SendNotifyL(AUTHENTICATION_FAILED); + } + CleanupStack::PopAndDestroy(); //payload + return Status; +} + +//returns KErrNone if OK, otherwise error already treated. +TBool CIkev1Negotiation::ProcessSAL(const TSAISAKMP *aSA, TUint8 *aRecvProposals) +{ + //payload not present + if (!aSA) + { + DEBUG_LOG(_L("NO SA PAYLOAD")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(PAYLOAD_MALFORMED); + return EFalse; + } + + //requires a special length check to know the proposals and transforms are not bigger than + //the size specified in th SA + TUint32 SALengthLeft = aSA->GetLength() - aSA->Size(); + + TUint8 next_payload = aSA->GetPayload(); + if ((next_payload == ISAKMP_PAYLOAD_P) || (next_payload == ISAKMP_PAYLOAD_T)) + { + DEBUG_LOG(_L("INVALID_PAYLOAD_TYPE (Bad next payload for the SA)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_PAYLOAD_TYPE); // Payloads and transforms are processed as a part of the SA, + return EFalse; + } + + TUint32 doi=aSA->GetDOI(); + if (!CheckDOI(doi)) + { + DEBUG_LOG(_L("DOI_NOT_SUPPORTED in SA payload")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(DOI_NOT_SUPPORTED); //send the informational exchange + return EFalse; + } + + if (iStage == 1) + iDOI = doi; + + //Process SITuation depending on DOI. In this implementation always is IPSEC DOI + if (!CheckSituationL(aSA->GetSIT())) + return EFalse; + + if (aSA->HasLDId()) //If no Labeled Domain Identifier no more processing for the SA + { + DEBUG_LOG(_L("Label Domain Identifier (LDI) not supported")); + return EFalse; + } + + if (iPhase==PHASE_I) //Only used in Phase_I. PHASE_II hashs check it directly from received paylaod + { + //Store the SA payload for further calculations in Hash. + if (iRole==RESPONDER) + { + iSAPayloadSize = aSA->GetLength()-sizeof(TPayloadISAKMP); + delete iSAPayload; + iSAPayload = NULL; + iSAPayload = new (ELeave) (TUint8[iSAPayloadSize]); //Generic payload NOT included + Mem::Copy(iSAPayload,(((TUint8 *)aSA)+sizeof(TPayloadISAKMP)),iSAPayloadSize); + } + } + const TPayloadISAKMP *payload = aSA->Payload(); + return ProcessProposalsL(payload, SALengthLeft, aRecvProposals); +} + + +//Do the process required for proposals and transforms. The aPayload given must be a proposal +TBool CIkev1Negotiation::ProcessProposalsL(const TPayloadISAKMP *aPayload, TUint32 aLengthLeft, TUint8 *aRecvProposals) +{ + TProposalISAKMP *proposal; + const TPayloadISAKMP *ppayload=aPayload; + TUint8 payType = ppayload->GetPayload(); + TUint32 len_left; + CProposal_IIList *recv_proposals = (CProposal_IIList *)aRecvProposals; + CProposal_II *auxProp_II; + TBool found = EFalse; //At least 1 transform matching + + //Many Proposals. The RESPONDER MUST choose a transform for each proposal or reject the + //full suite of attributes. + do + { + //General payload check + if ((payType != ISAKMP_PAYLOAD_NONE) && (payType != ISAKMP_PAYLOAD_P)) + { + DEBUG_LOG(_L("INVALID_PAYLOAD_TYPE (Bad next payload for the proposal)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_PAYLOAD_TYPE); + return EFalse; + } + + if (aPayload->GetReserved() != 0) //Must be always 0 + { + DEBUG_LOG(_L("INVALID RESERVED FIELD")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(PAYLOAD_MALFORMED); + return EFalse; + } + + //requires special length check + if ((aPayload->GetLength() < MIN_ISAKMP_PAYLOAD_SIZE) || (aPayload->GetLength() > aLengthLeft)) + { + DEBUG_LOG(_L("BAD PAYLOAD SIZE")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(PAYLOAD_MALFORMED); + return EFalse; + } + + aLengthLeft -= aPayload->GetLength(); //dcreases the length of the prop. and its transforms + + proposal = TProposalISAKMP::Ptr(ppayload); + + + if (!CheckProtocolL(proposal->GetProtocol())) + return EFalse; + + if (!CheckSPIL(proposal)) + return EFalse; + + len_left = proposal->GetLength() - (proposal->Size() + proposal->GetSPISize()); + //len_left contains the length of the transforms only + + TInt ret = KErrNotFound; + if (iPhase == PHASE_I) + { + iChosenProposal_I.iProtocol = proposal->GetProtocol(); + iChosenProposal_I.iSPI.Copy((TUint8 *)proposal->SPI(), proposal->GetSPISize()); + iChosenProposal_I.iNumTransforms = 1; //Phase I only one transf chosen + iChosenProposal_I.iProposalNum = proposal->GetNum();//Not compulsory but preferable to speed up the search process in the peer + + ret = ProcessTransformsL(ppayload,len_left); + + if (ret == KErrNone) + return ETrue;//valid transform found + else if (ret != KErrNotFound) + { + DEBUG_LOG(_L("ATTRIBUTES_NOT_SUPPORTED")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(ATTRIBUTES_NOT_SUPPORTED); + return EFalse; + } + //If not found there may be other proposal to check + } + else //PHASE_II + { + auxProp_II = new (ELeave) CProposal_II(); + CleanupStack::PushL(auxProp_II); + auxProp_II->ConstructL(proposal->GetNumTrans()); + auxProp_II->iProtocol=proposal->GetProtocol(); + auxProp_II->iSPI.Copy((TUint8 *)proposal->SPI(), proposal->GetSPISize()); + auxProp_II->iNumTransforms = proposal->GetNumTrans(); //Number of transforms in the proposal + auxProp_II->iProposalNum = proposal->GetNum(); //Proposal num + + ret = ProcessTransforms2L(ppayload, auxProp_II, len_left); + if (ret==KErrNone)//valid transform found + { + //Adds the new proposal to the list of chosen proposals + recv_proposals->AppendL(auxProp_II); + CleanupStack::Pop(); //auxProp_II safe + found = ETrue; + //go for the next proposal + } + else + { + DEBUG_LOG(_L("ATTRIBUTES_NOT_SUPPORTED")); + SendNotifyL(ATTRIBUTES_NOT_SUPPORTED); + CleanupStack::PopAndDestroy(); //delete auxProp_II; //delete the current proposal + return EFalse; + } + } + + payType = ppayload->GetPayload(); + ppayload = ppayload->Next(); //Next payload if there's any + } while (payType!=ISAKMP_PAYLOAD_NONE); //Proposal loop + + if (!found) + { + DEBUG_LOG(_L("ATTRIBUTES_NOT_SUPPORTED")); + SendNotifyL(ATTRIBUTES_NOT_SUPPORTED); + return EFalse; + } + + return found; +} + +//processes all the PHASE I transforms. The parameter payload is the proposal containing +//the transforms to be able to access the # of transforms. +//Returns if any transform accepted (KErrNone) or not (KErrNotFound) or processing error (KErrGeneral) +TInt CIkev1Negotiation::ProcessTransformsL(const TPayloadISAKMP *aPayload,TUint32 aLengthLeft) +{ + DEBUG_LOG(_L("-> CIkev1Negotiation::ProcessTransformsL()")); + TUint16 reason; + TInt ret = KErrGeneral; + const TTransformISAKMP *transf; + const TProposalISAKMP *proposal=TProposalISAKMP::Ptr(aPayload); + //First transform. Not Next() because would be the next proposal or non-sa payload + const TPayloadISAKMP *tpayload=proposal->Payload(); + + TInt payType = tpayload->GetPayload(); //Type of the payload following the first transform + transf = TTransformISAKMP::Ptr(tpayload); + + TInt numTransf = (TInt)transf->GetNum(); // First transform number + TInt lastTransf = numTransf + (TInt)proposal->GetNumTrans(); // Last transform number + + while ( numTransf < lastTransf ) + { + //only permited payload codes + if ((payType != ISAKMP_PAYLOAD_NONE) && (payType != ISAKMP_PAYLOAD_T)) + { + DEBUG_LOG(_L("INVALID_PAYLOAD_TYPE (Bad next payload for the transform)")); + SendNotifyL(INVALID_PAYLOAD_TYPE); + return KErrGeneral; + } + + if (tpayload->GetReserved() != 0) //Must be always 0 + { + DEBUG_LOG(_L("INVALID RESERVED FIELD")); + SendNotifyL(PAYLOAD_MALFORMED); + return KErrGeneral; + } + + //requires special length check + if ((tpayload->GetLength() < MIN_ISAKMP_PAYLOAD_SIZE) || (tpayload->GetLength() > aLengthLeft)) + { + DEBUG_LOG(_L("BAD PAYLOAD SIZE")); + SendNotifyL(PAYLOAD_MALFORMED); + return KErrGeneral; + } + + if (!CheckTransformID(PROTO_ISAKMP,transf->GetID())) + { + DEBUG_LOG(_L(" Continue")); + + numTransf++; // Next supposed transform # + payType = tpayload->GetPayload(); + tpayload = tpayload->Next(); //next payload (transform) + transf = TTransformISAKMP::Ptr(tpayload); + + continue; //If fails, transform discarded!, not error + } + + if ( transf->GetNum() != numTransf ) //Not the correct # + { + DEBUG_LOG1(_L("BAD_PROPOSAL_SYNTAX (Non conscutive transform number (%d)"),transf->GetNum()); + SendNotifyL(BAD_PROPOSAL_SYNTAX); + DEBUG_LOG(_L("<- CIkev1Negotiation::ProcessTransformsL() KErrGeneral")); + return KErrGeneral; + } + + if (transf->GetReserved() != 0 ) //Should be always 0 + { + DEBUG_LOG(_L("INVALID RESERVED FIELD")); + SendNotifyL(PAYLOAD_MALFORMED); + DEBUG_LOG(_L("<- CIkev1Negotiation::ProcessTransformsL() KErrGeneral")); + return KErrGeneral; + } + + numTransf++; // Next supposed transform # + //Attributes to be checked depending on Transf ID + TAttrib attrib; + + ret = ProcessAttributesL(tpayload, &attrib); + + if (ret != KErrNone) + { + if (ret != KErrNotFound) + { + DEBUG_LOG(_L("<- CIkev1Negotiation::ProcessTransformsL() KErrGeneral")); + return KErrGeneral; //Error in the attributes. Already reported + } + //Not accepted but correct + } + else // Accepted attributes if (AttrChosen(attrib)) + { + //Checks the response or proposal is the same as one of our proposals + TAttrib *attr_list = iProposal_I.iAttrList; + TInt ret = KErrNotFound; +#ifdef _DEBUG + TBuf<256> buf; +#endif + while (attr_list && (ret != KErrNone) ) + { + ret = attrib.Compare(*attr_list, iRole==RESPONDER); //If RESPONDER relaxed comparison (no lifetimes checked) + if (ret != KErrNone) + { +#ifdef _DEBUG + DEBUG_LOG1(_L("Transform #%d not matching proposal Reason: "), attrib.iTransformNum); + AppendAttributeError(ret, buf); + DEBUG_LOG(buf); +#endif + } + attr_list = attr_list->iNext; //next transform proposed + + } + if (ret == KErrNone) + { + *iChosenProposal_I.iAttrList = attrib; + DEBUG_LOG(_L("<- CIkev1Negotiation::ProcessTransformsL() KErrNone")); + return KErrNone; //If the attibute are supported there's no need to check more SA + } + else //No proposal matches + { + if ( numTransf == lastTransf ) //Is there more transforms to check + { + if (iRole == INITIATOR) + { + reason = BAD_PROPOSAL_SYNTAX; + DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (Phase I reply don't match proposal)")); + SetErrorStatus( KKmdIkeNegotFailed ); + } + else + { + reason = NO_PROPOSAL_CHOSEN; + DEBUG_LOG(_L("NO_PROPOSAL_CHOSEN (Received Proposal doesn't match accepted attributes (Check own proposals))")); + } + SendNotifyL(reason); + DEBUG_LOG(_L("<- CIkev1Negotiation::ProcessTransformsL() KErrNotFound")); + return KErrNotFound; + } + } + } + + payType = tpayload->GetPayload(); + tpayload = tpayload->Next(); //next payload (transform) + transf = TTransformISAKMP::Ptr(tpayload); + + } + + DEBUG_LOG(_L("<- CIkev1Negotiation::ProcessTransformsL() KErrNotFound")); + + //if reaches this point meanse no transform accepted in this proposal + //Notifies to the upper level + return KErrNotFound; + +} + + +//Logs the error when comparing a proposal +//void CIkev1Negotiation::LogAttributeError(TInt aTransformNum, TInt aErr) +void CIkev1Negotiation::AppendAttributeError(TInt aErr, TDes &aBuf) const +{ +#ifndef _DEBUG + (void)aErr; + (void)aBuf; +#endif + +#ifdef _DEBUG + switch (aErr) + { + case KErrNotFound: + aBuf.Append(_L("No proposals\n")); + break; + case KErrTransformID: + aBuf.Append(_L("Different Transform Algorithm\n")); + break; + case KErrEncrAlg: + aBuf.Append(_L("Different Encryption Algorithm\n")); + break; + case KErrHashAlg: + aBuf.Append(_L("Different Hash Algorithm\n")); + break; + case KErrAuthMethod: + aBuf.Append(_L("Different Authentication Method\n")); + break; + case KErrGroupDesc: + aBuf.Append(_L("Different Group Description\n")); + break; + case KErrGroupType: + aBuf.Append(_L("Different Group Type\n")); + break; + case KErrGroupPrime: + aBuf.Append(_L("Different Group Prime\n")); + break; + case KErrGroupGen1: + aBuf.Append(_L("Different Group Generator 1\n")); + break; + case KErrGroupGen2: + aBuf.Append(_L("Different Group Generator 2\n")); + break; + case KErrGroupCurveA: + aBuf.Append(_L("Different Group Curve A\n")); + break; + case KErrGroupCurveB: + aBuf.Append(_L("Different Group Curve A\n")); + break; + case KErrPRF: + aBuf.Append(_L("Different PRF\n")); + break; + case KErrKeyLength: + aBuf.Append(_L("Different Key Length\n")); + break; + case KErrFieldSize: + aBuf.Append(_L("Different Field Size\n")); + break; + case KErrGroupOrder: + aBuf.Append(_L("Different Group Order\n")); + break; + case KErrLifeTime: + aBuf.Append(_L("Different Lifetime\n")); + break; + case KErrLifeSize: + aBuf.Append(_L("Different LifeSize\n")); + break; + case KErrEncMode: + aBuf.Append(_L("Different Encapsulation Mode\n")); + break; + case KErrAuthAlg: + aBuf.Append(_L("Different Authentication Algorithm\n")); + break; + case KErrKeyRounds: + aBuf.Append(_L("Different Key Rounds\n")); + break; + case KErrComprDicSize: + aBuf.Append(_L("Different Compress Dictionary Size\n")); + break; + case KErrComprPrivAlg: + aBuf.Append(_L("Different Compress Private Algorithm\n")); + break; + case KErrTransformNum: + aBuf.Append(_L("Different Transform Num.\n")); + break; + case KErrPropProtocol: + aBuf.Append(_L("Proposals have different protocol.\n")); + break; + case KErrNoTransforms: + aBuf.Append(_L("Proposal has no transforms \n")); + break; + case KErrNoRemoteProposals: + aBuf.Append(_L("Remote Proposals list is empty\n")); + break; + case KErrNoLocalProposals: + aBuf.Append(_L("Local Proposals list is empty\n")); + break; + case KErrPropNumberMismatch: + aBuf.Append(_L("The proposals lists have diferent number of AND'd proposals")); + break; + default: + aBuf.Append(_L("Unknown\n")); + } +#endif +} + +//processes all the PHASE II transforms. The parameter payload is the proposal containing +//the transforms to be able to access the # of transforms. +//Returns if any transform accepted (KErrNone) or not (KErrNotFound) or processing error (KErrGeneral) +TInt CIkev1Negotiation::ProcessTransforms2L(const TPayloadISAKMP *aPayload,CProposal_II *aProp,TUint32 aLengthLeft) +{ + DEBUG_LOG(_L("-> CIkev1Negotiation::ProcessTransforms2L()")); + + TInt ret; + const TTransformISAKMP *transf; + const TProposalISAKMP *proposal=TProposalISAKMP::Ptr(aPayload); + //First transform. Not Next() because would be the next proposal or non-sa payload + const TPayloadISAKMP *tpayload = proposal->Payload(); + + TAttrib_II *attr_II = NULL; + TInt payType = tpayload->GetPayload(); //Type of the payload following the first transform + transf = TTransformISAKMP::Ptr(tpayload); + + TInt numTransf = (TInt)transf->GetNum(); // First transform number + TInt lastTransf = numTransf + (TInt)proposal->GetNumTrans(); // Last transform number + + while ( numTransf < lastTransf ) + { + //only permited payload codes + if ((payType != ISAKMP_PAYLOAD_NONE) && (payType != ISAKMP_PAYLOAD_T)) + { + DEBUG_LOG(_L("INVALID_PAYLOAD_TYPE (Bad next payload for the transform)")); + SendNotifyL(INVALID_PAYLOAD_TYPE); + return KErrGeneral; + } + + if (tpayload->GetReserved() != 0) //Must be always 0 + { + DEBUG_LOG(_L("INVALID RESERVED FIELD")); + SendNotifyL(PAYLOAD_MALFORMED); + return KErrGeneral; + } + + //requires special length check + if ((tpayload->GetLength() < MIN_ISAKMP_PAYLOAD_SIZE) || (tpayload->GetLength() > aLengthLeft)) + { + DEBUG_LOG(_L("BAD PAYLOAD SIZE")); + SendNotifyL(PAYLOAD_MALFORMED); + return KErrGeneral; + } + + if (!CheckTransformID(aProp->iProtocol,transf->GetID())) + { + DEBUG_LOG(_L(" Transform doesn't match, moving on to the next one")); + payType = tpayload->GetPayload(); + tpayload = tpayload->Next(); //next payload (transform) + transf = TTransformISAKMP::Ptr(tpayload); + numTransf++; // Next supposed transform # + continue; //If fails, transform discarded!, not error + } + + if ( transf->GetNum() != numTransf ) //Not the correct #. Must be consecutive + { + DEBUG_LOG1(_L("BAD_PROPOSAL_SYNTAX (Non conscutive transform number (%d)"),transf->GetNum()); + SendNotifyL(BAD_PROPOSAL_SYNTAX); + return KErrGeneral; + } + + if (transf->GetReserved() != 0 ) //Must be always 0 + { + DEBUG_LOG(_L("INVALID RESERVED FIELD")); + SendNotifyL(PAYLOAD_MALFORMED); + return KErrGeneral; + } + + //Attributes to be checked depending on Transf ID + attr_II = new (ELeave) TAttrib_II(); + CleanupStack::PushL(attr_II); + ret = ProcessAttributes2L(tpayload, attr_II, aProp->iProtocol); + if (ret != KErrNone) //Some invalid attribute + { + DEBUG_LOG(_L(" Invalid attribute")); + CleanupStack::PopAndDestroy(); //delete attr_II; + if (ret != KErrNotFound) + return KErrGeneral; //Error in the attributes. Already reported + else //Invalid transform- Ignored + { + DEBUG_LOG2(_L("Transform %d of proposal %d ignored"), transf->GetNum(), aProp->iProposalNum); + } + } + else //Accepted, must check if really proposed or if matches the configuration if RESPONDER + { + DEBUG_LOG(_L(" Adding new attribute")); + aProp->iAttrList->AppendL(attr_II); //Add the new attribute + CleanupStack::Pop(); //attr_II saf + } + payType = tpayload->GetPayload(); + tpayload = tpayload->Next(); //next payload (transform) + transf = TTransformISAKMP::Ptr(tpayload); + numTransf++; // Next supposed transform # + + } + + //No valid transform found + if (aProp->iAttrList->Count() == 0) + { + DEBUG_LOG(_L("<- CIkev1Negotiation::ProcessTransforms2L() KErrNotFound")); + return KErrNotFound; + } + + DEBUG_LOG(_L("<- CIkev1Negotiation::ProcessTransforms2L() KErrNone")); + return KErrNone; +} + + +//Copies and checks the values of the attributes. The parameter aPayload must be a transform +//aAttrib will contain the sent attributes if the return value is KErrNone, otherwise should be +//ignore because there was an error reading them (KErrGeneral) or the transform was not accepted (KErrNotFound) +TInt CIkev1Negotiation::ProcessAttributesL(const TPayloadISAKMP *aPayload, TAttrib *aAttrib) +{ + const TTransformISAKMP *transf = TTransformISAKMP::Ptr(aPayload); + TInt length= aPayload->GetLength() - sizeof(*transf); //To process the attribs + TDataISAKMP *attr= transf->SAAttrib(); + + aAttrib->iTransformNum = transf->GetNum(); + aAttrib->iTransformID = transf->GetID(); + // + // Store parameters for extended authentication + // + aAttrib->iXauthUsed = iHostData->iUseXauth; + aAttrib->iRole = iRole; + + TUint16 lifeType = 0; //No type assigned yet + TUint32 lifeValue = 0; //No value assigned yet + TUint16 val; + + while ( length>0 ) + { + length = length - attr->Size(); + if (length<0) //Mismatch between lengths!!! + { + DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (Length mismatch in the attibutes)")); + SendNotifyL(BAD_PROPOSAL_SYNTAX); + return KErrGeneral; + } + switch (attr->Type()) + { + case OAKLEY_ATTR_TYPE_ENCR_ALG: + if (!CheckEncrAlg(attr->Value())) + return KErrNotFound; + aAttrib->iEncrAlg=attr->Value(); + break; + case OAKLEY_ATTR_TYPE_HASH_ALG: + if (!CheckHashAlg(attr->Value())) + return KErrNotFound; + aAttrib->iHashAlg = attr->Value(); + break; + case OAKLEY_ATTR_TYPE_AUTH_METH: + val = CTransNegotiation::GetAuthMethod(attr->Value(), iHostData->iUseXauth, iRole); + if (!CheckAuthMethod(val)) + return KErrNotFound; + aAttrib->iAuthMethod = val; + break; + case OAKLEY_ATTR_TYPE_GROUP_DESC: + if (!CheckGroupDesc(attr->Value())) + return KErrNotFound; + aAttrib->iGroupDesc = attr->Value(); + break; + case OAKLEY_ATTR_TYPE_GROUP_TYPE: + if (!CheckGroupType(attr->Value())) + return KErrNotFound; + aAttrib->iGroupType = attr->Value(); + break; + case OAKLEY_ATTR_TYPE_GROUP_PRIME: + if (attr->IsBasic()) + { + val = attr->Value(); + aAttrib->iGroupPrime.Copy((TUint8*)&val, sizeof(val)); + } + else + aAttrib->iGroupPrime.Copy(attr->VarValue(),attr->Length()); + break; + case OAKLEY_ATTR_TYPE_GROUP_GEN1: + if (attr->IsBasic()) + { + val = attr->Value(); + aAttrib->iGroupGen1.Copy((TUint8*)&val, sizeof(val)); + } + else + aAttrib->iGroupGen1.Copy(attr->VarValue(),attr->Length()); + break; + case OAKLEY_ATTR_TYPE_GROUP_GEN2: + if (attr->IsBasic()) + { + val = attr->Value(); + aAttrib->iGroupGen2.Copy((TUint8*)&val, sizeof(val)); + } + else + aAttrib->iGroupGen2.Copy(attr->VarValue(),attr->Length()); + break; + case OAKLEY_ATTR_TYPE_GROUP_CRVA: + if (attr->IsBasic()) + { + val = attr->Value(); + aAttrib->iGroupCurveA.Copy((TUint8*)&val, sizeof(val)); + } + else + aAttrib->iGroupCurveA.Copy(attr->VarValue(),attr->Length()); + break; + case OAKLEY_ATTR_TYPE_GROUP_CRVB: + if (attr->IsBasic()) + { + val = attr->Value(); + aAttrib->iGroupCurveB.Copy((TUint8*)&val, sizeof(val)); + } + else + aAttrib->iGroupCurveB.Copy(attr->VarValue(),attr->Length()); + break; + case OAKLEY_ATTR_TYPE_LIFE_TYPE: + lifeType = attr->Value(); + if (!CheckLifeType(lifeType)) + { + DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (Invalid lifetime type)")); + SendNotifyL(BAD_PROPOSAL_SYNTAX); + return KErrGeneral; + } + break; + case OAKLEY_ATTR_TYPE_LIFE_DUR: + if (attr->IsBasic()) + { + lifeValue = ByteOrder::Swap32(attr->Value()); + if (lifeType == SECONDS) + aAttrib->iLifeDurationSecs.Copy((TUint8 *)&lifeValue, sizeof(lifeValue)); + else if (lifeType == KBYTES) + aAttrib->iLifeDurationKBytes.Copy((TUint8 *)&lifeValue, sizeof(lifeValue)); + else + { + DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (Invalid lifetime type)")); + SendNotifyL(BAD_PROPOSAL_SYNTAX); + return KErrGeneral; + } + } + else //Not basic + { + if (lifeType == SECONDS) + aAttrib->iLifeDurationSecs.Copy(attr->VarValue(),attr->Length()); + else if (lifeType == KBYTES) + aAttrib->iLifeDurationKBytes.Copy(attr->VarValue(),attr->Length()); + else + { + DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (Invalid lifetime type)")); + SendNotifyL(BAD_PROPOSAL_SYNTAX); + return KErrGeneral; + } + } + break; + case OAKLEY_ATTR_TYPE_PRF: + if (!CheckPRF(attr->Value())) + return KErrNotFound; + aAttrib->iPRF=attr->Value(); + break; + case OAKLEY_ATTR_TYPE_KEY_LEN: + aAttrib->iKeyLength = attr->Value(); + break; + case OAKLEY_ATTR_TYPE_FIELD_SIZE: + if (!CheckFieldSize(attr->Value())) + return KErrNotFound; + aAttrib->iFieldSize=attr->Value(); + break; + case OAKLEY_ATTR_TYPE_GROUP_ORDER: + if (attr->IsBasic()) + { + val = attr->Value(); + aAttrib->iGroupOrder.Copy((TUint8*)&val, sizeof(val)); + } + else + aAttrib->iGroupOrder.Copy(attr->VarValue(),attr->Length()); + break; + default: + DEBUG_LOG(_L("ATTRIBUTES_NOT_SUPPORTED (Invalid attribute number)")); + SendNotifyL(ATTRIBUTES_NOT_SUPPORTED); + return KErrGeneral; + } + attr = attr->Next(); + } + + //Done here to ensure both received + if (aAttrib->iKeyLength !=0) + if (!CheckKeyLength(aAttrib->iKeyLength, (TUint8)aAttrib->iEncrAlg ,PROTO_ISAKMP)) + return KErrNotFound; + + return KErrNone; +} + +//Copies and checks the values of the attributes. The parameter aPayload must be a transform +//aAttrib will contain the sent attributes if the return value is KErrNone, otherwise should be +//ignore because there was an error reading them (KErrGeneral) or the transform was not accepted (KErrNotFound) +TInt CIkev1Negotiation::ProcessAttributes2L(const TPayloadISAKMP *aPayload, TAttrib_II *aAttrib,TUint8 aProtocol) +{ + const TTransformISAKMP *transf = TTransformISAKMP::Ptr(aPayload); + TInt length= aPayload->GetLength() - sizeof(*transf); //To process the attribs + + aAttrib->iTransformNum = transf->GetNum(); + aAttrib->iTransformID = transf->GetID(); + TDataISAKMP *attr= transf->SAAttrib(); + TUint16 lifeType = 0; //No type assigned yet + TUint32 lifeValue = 0; + while (length>0) + { + length = length - attr->Size(); + if (length<0) //Mismatch between lengths!!! + { + DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (Length mismatch in the attibutes)")); + SendNotifyL(BAD_PROPOSAL_SYNTAX); + return KErrGeneral; + } + switch (attr->Type()) + { + case DOI_ATTR_TYPE_LIFE_TYPE: + lifeType=attr->Value(); + if (!CheckLifeType(lifeType)) + { + DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (Invalid lifetime type)")); + SendNotifyL(BAD_PROPOSAL_SYNTAX); + return KErrGeneral; + } + break; + case DOI_ATTR_TYPE_LIFE_DUR: + if (attr->IsBasic()) + { + lifeValue = ByteOrder::Swap32(attr->Value()); + if (lifeType==SECONDS) + aAttrib->iLifeDurationSecs.Copy((TUint8 *)&lifeValue, sizeof(lifeValue)); + else if (lifeType==KBYTES) + aAttrib->iLifeDurationKBytes.Copy((TUint8 *)&lifeValue, sizeof(lifeValue)); + else + { + DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (No lifetime type received)")); + SendNotifyL(BAD_PROPOSAL_SYNTAX); + return KErrGeneral; + } + } + else + { + if (lifeType==SECONDS) + aAttrib->iLifeDurationSecs.Copy(attr->VarValue(),attr->Length()); + else if (lifeType==KBYTES) + aAttrib->iLifeDurationKBytes.Copy(attr->VarValue(),attr->Length()); + else + { + DEBUG_LOG(_L("BAD_PROPOSAL_SYNTAX (No lifetime type received)")); + SendNotifyL(BAD_PROPOSAL_SYNTAX); + return KErrGeneral; + } + } + lifeType = 0; //Cannot received another lifetime without setting the type again + break; + case DOI_ATTR_TYPE_GROUP_DESC: + if (!CheckGroupDesc(attr->Value())) + return KErrNotFound; + aAttrib->iGroupDesc=attr->Value(); + break; + case DOI_ATTR_TYPE_ENC_MODE: //Encapsulation Mode + if (!CheckEncMode(attr->Value())) + return KErrNotFound; + aAttrib->iEncMode=attr->Value(); + if ( aAttrib->iEncMode == UDP_ENC_TUNNEL || aAttrib->iEncMode == UDP_RFC_ENC_TUNNEL ) + aAttrib->iEncMode = DOI_TUNNEL; + if ( aAttrib->iEncMode == UDP_ENC_TRANSPORT || aAttrib->iEncMode == UDP_RFC_ENC_TRANSPORT) + aAttrib->iEncMode = DOI_TRANSPORT; + break; + case DOI_ATTR_TYPE_AUTH_ALG: + if (!CheckAuthAlg(attr->Value())) + return KErrNotFound; + aAttrib->iAuthAlg=attr->Value(); + break; + case DOI_ATTR_TYPE_KEY_LEN: + aAttrib->iKeyLength = attr->Value(); + break; + case DOI_ATTR_TYPE_KEY_ROUNDS: + aAttrib->iKeyRounds=attr->Value(); + break; +/* + case DOI_ATTR_TYPE_COMP_DIC_SIZE: //Compress Dictionary size + aAttrib->iComprDicSize=attr->Value(); + break; + case DOI_ATTR_TYPE_COMP_PRIV_ALG: //Compress Dictionary size + aAttrib->iComprPrivAlg=attr->Value(); + break; +*/ + default: + DEBUG_LOG(_L("ATTRIBUTES_NOT_SUPPORTED (Invalid attribute number)")); + SendNotifyL(ATTRIBUTES_NOT_SUPPORTED); + return KErrGeneral; + } + attr = attr->Next(); + } + + if (lifeType != 0) //Type set but not sent + { + DEBUG_LOG(_L("Lifetime type set but value not sent!")); + return KErrNotFound; + } + + if (aAttrib->iKeyLength !=0) + if (!CheckKeyLength(aAttrib->iKeyLength,transf->GetID(),aProtocol)) //Check key length correct + return KErrNotFound; + + return KErrNone; +} + + +//returns KErrNone if OK, otherwise error already treated. +TBool CIkev1Negotiation::ProcessKeyL(const TKeyISAKMP *aKey) +{ + //const TKeyISAKMP *key = TKeyISAKMP::Ptr(aPayload); + + //payload not present + if (iPhase==PHASE_I) + { + if (!aKey) + { + DEBUG_LOG(_L("NO KEY Payload")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(PAYLOAD_MALFORMED); + return EFalse; + } + //Doesn't return yet because it needs to copy the received key + } + else //PHASE_II + { + if (!aKey) + { + if (iPFS) + { + DEBUG_LOG(_L("KEY Payload Expected (PFS is enabled)")); + return EFalse; + } + + return ETrue; + + } + else // Key present + { + if (!iPFS) + { + DEBUG_LOG(_L("KEY Payload NOT Expected (PFS is disabled)")); + return EFalse; + } + //Doesn't return yet because it needs to copy the received key + } + } + + //stores the public key sent by the other peer. Only if key received and PFS enabled (PHASE II only) + iPeerPublicKey.Copy(aKey->KeyData(), aKey->GetLength() - sizeof(*aKey)); + return ETrue; +} + + +TBool CIkev1Negotiation::ProcessNonceL(const TPayloadISAKMP *aPayload) +{ + const TNonceISAKMP *nonce = TNonceISAKMP::Ptr(aPayload); + + //payload not present + if (!nonce) + { + DEBUG_LOG(_L("NO NONCE PAYLOAD")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(PAYLOAD_MALFORMED); + return EFalse; + } + + //stores the nonce sent by the other peer + if (iRole==RESPONDER) + iNONCE_I.Copy(nonce->NonceData(),nonce->NonceDataLen()); + else + iNONCE_R.Copy(nonce->NonceData(),nonce->NonceDataLen()); + + return ETrue; + +} + +TBool CIkev1Negotiation::ProcessStage1_II_IDsL(const TIdentISAKMP *aInit_ID_payload,const TIdentISAKMP *aResp_ID_payload, CProposal_IIList *aRecv_proposals) +{ + //IDci + //First we check the received IDs to be able to build the proposals for phase_II + TInt32 addr; //Contains a numeric IPv4 addr to be sent + TBuf<40> addr_buf; //Contains a text IPv4/IPv6 addr to be sent + + TIp6Addr ip6addr; //IPV6 raw address + + //We receive the peer proxy address or gateway client + TAttrib_II *attr_II = aRecv_proposals->At(0)->iAttrList->At(0); + if (aInit_ID_payload) //ID Payload received + { + iIDReceived = ETrue; + if (!CheckIdentL(aInit_ID_payload)) + return EFalse; + + iIDRemotePort = aInit_ID_payload->GetPort(); + iIDProtocol = aInit_ID_payload->GetProtocol(); + iRemoteIDType_II = aInit_ID_payload->GetIDType(); + + switch (aInit_ID_payload->GetIDType()) + { + case ID_IPV4_ADDR: + Mem::Copy((TUint8 *)&addr, aInit_ID_payload->IDData(),sizeof(TInt32)); + iRemoteAddr1_ID_II.SetAddress(ByteOrder::Swap32(addr)); + DEBUG_LOG(_L("Remote ID received")); + DEBUG_LOG(_L("Setting Remote ID to:")); + iRemoteAddr1_ID_II.OutputWithScope(addr_buf); + DEBUG_LOG(addr_buf); + if (iRemoteAddr.Match(iRemoteAddr1_ID_II)) + iDefaultRemoteID = ETrue; //Must be sent but won't be used when updating the SAD + else if (attr_II->iEncMode == DOI_TRANSPORT) + { + DEBUG_LOG(_L("ADDRESS_NOTIFICATION (Received ID MUST match the Remote addr in Transport mode)")); + SendNotifyL(ADDRESS_NOTIFICATION); + return EFalse; + } + break; + case ID_IPV4_ADDR_SUBNET: + Mem::Copy((TUint8 *)&addr, aInit_ID_payload->IDData(),sizeof(TInt32)); //Address + iRemoteAddr1_ID_II.SetAddress(ByteOrder::Swap32(addr)); + Mem::Copy((TUint8 *)&addr, aInit_ID_payload->IDData() + sizeof(TInt32),sizeof(TInt32)); //Mask + iRemoteAddr2_ID_II.SetAddress(ByteOrder::Swap32(addr)); + iRemoteAddr1_ID_II.OutputWithScope(addr_buf); + DEBUG_LOG(_L("Setting Remote ID to: addr = ")); + DEBUG_LOG(addr_buf); + iRemoteAddr2_ID_II.OutputWithScope(addr_buf); + DEBUG_LOG(_L(" mask = ")); + DEBUG_LOG(addr_buf); + if (PrefixLen(iRemoteAddr2_ID_II) < KErrNone) //Invalid Mask (can't be > 32 bec. we get only 4 bytes) + { + DEBUG_LOG(_L("INVALID_ID_INFORMATION (Invalid peer proxy mask for type ID_IPV4_ADDR_SUBNET)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + if (attr_II->iEncMode == DOI_TRANSPORT) + { + if (!iRemoteAddr.Match(iRemoteAddr1_ID_II, iRemoteAddr2_ID_II)) + { + DEBUG_LOG(_L("ADDRESS_NOTIFICATION (Remote ID MUST match the net & mask received)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(ADDRESS_NOTIFICATION); + return EFalse; + } + } + break; + case ID_IPV6_ADDR: + Mem::Copy(&ip6addr.u.iAddr8, aInit_ID_payload->IDData(), sizeof(ip6addr.u.iAddr8)); + iRemoteAddr1_ID_II.SetAddress(ip6addr); + DEBUG_LOG(_L("Remote ID received")); + DEBUG_LOG(_L("Setting Remote ID to:")); + iRemoteAddr1_ID_II.OutputWithScope(addr_buf); + DEBUG_LOG(addr_buf); + if (iRemoteAddr.Match(iRemoteAddr1_ID_II)) + iDefaultRemoteID = ETrue; //Must be sent but won't be used when updating the SAD + else if (attr_II->iEncMode == DOI_TRANSPORT) + { + DEBUG_LOG(_L("ADDRESS_NOTIFICATION (Remote ID doesn't match received IDi in Transport mode)")); + SendNotifyL(ADDRESS_NOTIFICATION); + return EFalse; + } + break; + case ID_IPV6_ADDR_SUBNET: + Mem::Copy(&ip6addr.u.iAddr8, aInit_ID_payload->IDData(), sizeof(ip6addr.u.iAddr8)); //Address + iRemoteAddr1_ID_II.SetAddress(ip6addr); + Mem::Copy(&ip6addr.u.iAddr8, aInit_ID_payload->IDData() + sizeof(ip6addr.u.iAddr8), sizeof(ip6addr.u.iAddr8)); //Mask + iRemoteAddr2_ID_II.SetAddress(ip6addr); + DEBUG_LOG(_L("Remote ID (subnet) received")); + DEBUG_LOG(_L("Setting Remote ID to: addr = ")); + iRemoteAddr1_ID_II.OutputWithScope(addr_buf); + DEBUG_LOG(addr_buf); + DEBUG_LOG(_L(" mask = ")); + iRemoteAddr2_ID_II.OutputWithScope(addr_buf); + DEBUG_LOG(addr_buf); + if (PrefixLen(iRemoteAddr2_ID_II) < 0) //Invalid Mask + { + DEBUG_LOG(_L("INVALID_ID_INFORMATION (Invalid peer proxy mask for type ID_IPV6_ADDR_SUBNET)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + if (attr_II->iEncMode == DOI_TRANSPORT) + { + if (!iRemoteAddr.Match(iRemoteAddr1_ID_II, iRemoteAddr2_ID_II)) + { + DEBUG_LOG(_L("ADDRESS_NOTIFICATION (Remote ID MUST match the net & mask received)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(ADDRESS_NOTIFICATION); + return EFalse; + } + } + break; + default: //redundant. Detected in CheckIdentL() + DEBUG_LOG(_L("INVALID_ID_INFORMATION (ID Type not supported)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + }//switch + } + else //No id received (That means we're negotiating directly with the end host) (RFC 2409 5.5) + { + //For TRANSPORT we don't need to do anything + iIDLocalPort = 0; + iIDRemotePort = 0; + iIDProtocol = 0; + return ETrue; //No need to check the Responder ID if no Initiator ID received + } + + //IDcr + //Receive our proxy. We don't know it because we are responders so the other peer tells us who does it + //want to communicate with + if (aResp_ID_payload) //ID Payload received + { + if (!CheckIdentL(aResp_ID_payload)) + return EFalse; + + iIDLocalPort = aResp_ID_payload->GetPort(); + iLocalIDType_II = aResp_ID_payload->GetIDType(); + if (iIDProtocol != aResp_ID_payload->GetProtocol()) //Must be the same sent in the IDCi + { + DEBUG_LOG(_L("INVALID_ID_INFORMATION (Local ID Protocol different from Remote ID Protocol. Must be the same)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + + switch (aResp_ID_payload->GetIDType()) + { + case ID_IPV4_ADDR: + Mem::Copy((TUint8 *)&addr, aResp_ID_payload->IDData(),sizeof(TInt32)); + iLocalAddr1_ID_II.SetAddress(ByteOrder::Swap32(addr)); + DEBUG_LOG(_L("Local ID received")); + DEBUG_LOG(_L("Setting Local ID to:")); + iLocalAddr1_ID_II.OutputWithScope(addr_buf); + DEBUG_LOG(addr_buf); + if ( iInternalAddr ) { + // + // Check ID against internal address instead of local address + // + if (iInternalAddr->iClientIntAddr.Match(iLocalAddr1_ID_II)) + iDefaultLocalID = ETrue; //Must be sent but won't be used when updating the SAD + } + else { + if (iLocalAddr.Match(iLocalAddr1_ID_II)) + iDefaultLocalID = ETrue; //Must be sent but won't be used when updating the SAD + else if (attr_II->iEncMode == DOI_TRANSPORT) + { + DEBUG_LOG(_L("ADDRESS_NOTIFICATION (Local ID MUST match the net & mask received)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(ADDRESS_NOTIFICATION); + return EFalse; + } + } + break; + case ID_IPV4_ADDR_SUBNET: + Mem::Copy((TUint8 *)&addr, aResp_ID_payload->IDData(),sizeof(TInt32)); //Address + iLocalAddr1_ID_II.SetAddress(ByteOrder::Swap32(addr)); + Mem::Copy((TUint8 *)&addr, aResp_ID_payload->IDData() + sizeof(TInt32),sizeof(TInt32)); //Mask + iLocalAddr2_ID_II.SetAddress(ByteOrder::Swap32(addr)); + DEBUG_LOG(_L("Setting Local ID to: addr = ")); + iLocalAddr1_ID_II.OutputWithScope(addr_buf); + DEBUG_LOG(addr_buf); + DEBUG_LOG(_L(" mask = ")); + iLocalAddr2_ID_II.OutputWithScope(addr_buf); + DEBUG_LOG(addr_buf); + if (PrefixLen(iLocalAddr2_ID_II) < 0) //Invalid Mask + { + DEBUG_LOG(_L("INVALID_ID_INFORMATION (Invalid Remote ID mask for type ID_IPV4_ADDR_SUBNET)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + if (attr_II->iEncMode == DOI_TRANSPORT) + { + if (!iLocalAddr.Match(iLocalAddr1_ID_II, iLocalAddr2_ID_II)) + { + DEBUG_LOG(_L("ADDRESS_NOTIFICATION (Local ID MUST match the net & mask received)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(ADDRESS_NOTIFICATION); + return EFalse; + } + } + break; + case ID_IPV6_ADDR: + Mem::Copy(&ip6addr.u.iAddr8, aResp_ID_payload->IDData(), sizeof(ip6addr.u.iAddr8)); + //iOwnProxyAddr.SetAddress(ip6addr); + iLocalAddr1_ID_II.SetAddress(ip6addr); + DEBUG_LOG(_L("Own Proxy received")); + DEBUG_LOG(_L("Setting Own Proxy address to:")); + iLocalAddr1_ID_II.OutputWithScope(addr_buf); + DEBUG_LOG(addr_buf); + if (iLocalAddr.Match(iLocalAddr1_ID_II)) + iDefaultLocalID = ETrue; //Must be sent but won't be used when updating the SAD + else if (attr_II->iEncMode == DOI_TRANSPORT) + { + DEBUG_LOG(_L("ADDRESS_NOTIFICATION (Local ID MUST match the net & mask received)")); + SendNotifyL(ADDRESS_NOTIFICATION); + return EFalse; + } + break; + case ID_IPV6_ADDR_SUBNET: + Mem::Copy(&ip6addr.u.iAddr8, aResp_ID_payload->IDData(), sizeof(ip6addr.u.iAddr8)); //Address + iLocalAddr1_ID_II.SetAddress(ip6addr); + Mem::Copy(&ip6addr.u.iAddr8, aResp_ID_payload->IDData() + sizeof(ip6addr.u.iAddr8), sizeof(ip6addr.u.iAddr8)); //Mask + iLocalAddr2_ID_II.SetAddress(ip6addr); + DEBUG_LOG(_L("Setting Own Proxy to: addr = ")); + iLocalAddr1_ID_II.OutputWithScope(addr_buf); + DEBUG_LOG(addr_buf); + DEBUG_LOG(_L(" mask = ")); + iLocalAddr2_ID_II.OutputWithScope(addr_buf); + DEBUG_LOG(addr_buf); + if (PrefixLen(iLocalAddr2_ID_II) < 0) //Invalid Mask + { + DEBUG_LOG(_L("INVALID_ID_INFORMATION (Invalid Remote ID mask for type ID_IPV6_ADDR_SUBNET)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + if (attr_II->iEncMode == DOI_TRANSPORT) + { + if (!iLocalAddr.Match(iLocalAddr1_ID_II, iLocalAddr2_ID_II)) + { + DEBUG_LOG(_L("ADDRESS_NOTIFICATION (Local ID MUST match the net & mask received)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(ADDRESS_NOTIFICATION); + return EFalse; + } + } + break; + default: + DEBUG_LOG(_L("INVALID_ID_INFORMATION (ID Type not supported)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + }//switch + } + + return ETrue; +} + + +TBool CIkev1Negotiation::ProcessStage2_II_IDsL(const TIdentISAKMP *aInit_ID_payload,const TIdentISAKMP *aResp_ID_payload)//, CProposal_IIList *aRecv_proposals) +{ + TInt32 addr4_int; //Contains a numeric IPv4 addr to be sent + TIp6Addr ip6addr; //IPV6 raw address + TInetAddr tmp_addr; + //Here we check the initator proxy (Our client) sent by us has been received correctly + if (aInit_ID_payload) //ID Payload received + { + if (!CheckIdentL(aInit_ID_payload)) + return EFalse; + + if (aInit_ID_payload->GetPort() != iIDLocalPort) + { + DEBUG_LOG(_L("INVALID_ID_INFORMATION (Local ID Port different from the one sent)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + + if (aInit_ID_payload->GetProtocol() != iIDProtocol) + { + DEBUG_LOG(_L("INVALID_ID_INFORMATION (Local ID Protocol different from the one sent)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + + switch (aInit_ID_payload->GetIDType()) + { + case ID_IPV4_ADDR: + Mem::Copy((TUint8 *)&addr4_int,aInit_ID_payload->IDData(),sizeof(TInt32)); + tmp_addr.SetAddress(ByteOrder::Swap32(addr4_int)); + if (!tmp_addr.Match(iLocalAddr1_ID_II)) + { + DEBUG_LOG(_L("Wrong Own ID received (Different from the one sent)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + break; + case ID_IPV4_ADDR_SUBNET: + //Subnet + Mem::Copy((TUint8 *)&addr4_int,aInit_ID_payload->IDData(),sizeof(TInt32)); + tmp_addr.SetAddress(ByteOrder::Swap32(addr4_int)); + if (!tmp_addr.Match(iLocalAddr1_ID_II)) + { + //The ID subnet is not the one we sent! + DEBUG_LOG(_L("Wrong Own ID subnet received (Different from the one sent)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + //Mask + Mem::Copy((TUint8 *)&addr4_int,aInit_ID_payload->IDData() + sizeof(TInt32),sizeof(TInt32)); + tmp_addr.SetAddress(ByteOrder::Swap32(addr4_int)); + if (!tmp_addr.Match(iLocalAddr2_ID_II)) + { + //The ID mask is not the one we sent! + DEBUG_LOG(_L("Wrong Own ID mask received (Different from the one sent)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + break; + case ID_IPV6_ADDR: + Mem::Copy(&ip6addr.u.iAddr8, aInit_ID_payload->IDData(), sizeof(ip6addr.u.iAddr8)); + tmp_addr.SetAddress(ip6addr); + if (!tmp_addr.Match(iLocalAddr1_ID_II)) + { + //The ID is not the one we sent! + DEBUG_LOG(_L("Wrong Local ID received (Different from the one sent)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + break; + case ID_IPV6_ADDR_SUBNET: + //subnet + Mem::Copy(&ip6addr.u.iAddr8, aInit_ID_payload->IDData(), sizeof(ip6addr.u.iAddr8)); + tmp_addr.SetAddress(ip6addr); + if (!tmp_addr.Match(iLocalAddr1_ID_II)) + { + //The ID is not the one we sent! + DEBUG_LOG(_L("Wrong Local ID subnet received (Different from the one sent)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + //mask + Mem::Copy(&ip6addr.u.iAddr8, aInit_ID_payload->IDData() + sizeof(ip6addr.u.iAddr8), sizeof(ip6addr.u.iAddr8)); + tmp_addr.SetAddress(ip6addr); + if (!tmp_addr.Match(iLocalAddr2_ID_II)) + { + //The ID is not the one we sent! + DEBUG_LOG(_L("Wrong Local ID mask received (Different from the one sent)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + break; + default: + DEBUG_LOG(_L("INVALID_ID_INFORMATION (ID Type not supported)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + }//switch + } + else //No id sent (That means we're negotiating directly with the end host + { + if (!iLocalAddr1_ID_II.IsUnspecified()) + { + DEBUG_LOG(_L("IDci expected and not received!")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + } + + //We receive the peer (responder) proxy address or gateway client + if (aResp_ID_payload) //ID Payload received + { + if (!CheckIdentL(aResp_ID_payload)) + return EFalse; + + if (aResp_ID_payload->GetPort() != iIDRemotePort) + { + DEBUG_LOG(_L("INVALID_ID_INFORMATION (Remote Port different from the one sent)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + + if (aResp_ID_payload->GetProtocol() != iIDProtocol) + { + DEBUG_LOG(_L("INVALID_ID_INFORMATION (Responder ID Protocol different from the one sent)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + + switch (aResp_ID_payload->GetIDType()) + { + case ID_IPV4_ADDR: + Mem::Copy((TUint8 *)&addr4_int,aResp_ID_payload->IDData(),sizeof(TInt32)); + tmp_addr.SetAddress(ByteOrder::Swap32(addr4_int)); + DEBUG_LOG(_L("IDcr received")); + if (!iRemoteAddr1_ID_II.Match(tmp_addr)) + { + DEBUG_LOG(_L("INVALID_ID_INFORMATION (Wrong Remote ID, doesn't match sent one)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + break; + case ID_IPV4_ADDR_SUBNET: + //subnet address + Mem::Copy((TUint8 *)&addr4_int,aResp_ID_payload->IDData(),sizeof(TInt32)); + tmp_addr.SetAddress(ByteOrder::Swap32(addr4_int)); + if (!tmp_addr.Match(iRemoteAddr1_ID_II)) + { + //The ID subnet is not the one we sent! + DEBUG_LOG(_L("Wrong Remote ID subnet received (Different from the one sent)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + //Mask address + Mem::Copy((TUint8 *)&addr4_int,aResp_ID_payload->IDData() + sizeof(TInt32),sizeof(TInt32)); + tmp_addr.SetAddress(ByteOrder::Swap32(addr4_int)); + if (!tmp_addr.Match(iRemoteAddr2_ID_II)) + { + //The ID mask is not the one we sent! + DEBUG_LOG(_L("Wrong Remote ID mask received (Different from the one sent)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + break; + case ID_IPV6_ADDR: + Mem::Copy(&ip6addr.u.iAddr8,aResp_ID_payload->IDData(), sizeof(ip6addr.u.iAddr8)); + tmp_addr.SetAddress(ip6addr); + DEBUG_LOG(_L("IDcr received")); + if (!iRemoteAddr1_ID_II.Match(tmp_addr)) + { + DEBUG_LOG(_L("INVALID_ID_INFORMATION (Wrong ID, doesn't match sent proxy)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + break; + case ID_IPV6_ADDR_SUBNET: + //subnet + Mem::Copy(&ip6addr.u.iAddr8, aResp_ID_payload->IDData(), sizeof(ip6addr.u.iAddr8)); + tmp_addr.SetAddress(ip6addr); + if (!tmp_addr.Match(iRemoteAddr1_ID_II)) + { + //The ID is not the one we sent! + DEBUG_LOG(_L("Wrong Remote ID subnet received (Different from the one sent)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + //mask + Mem::Copy(&ip6addr.u.iAddr8, aResp_ID_payload->IDData() + sizeof(ip6addr.u.iAddr8), sizeof(ip6addr.u.iAddr8)); + tmp_addr.SetAddress(ip6addr); + if (!tmp_addr.Match(iRemoteAddr2_ID_II)) + { + //The ID is not the one we sent! + DEBUG_LOG(_L("Wrong Remote ID mask received (Different from the one sent)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + break; + default: //Only these 2 modes make sense no reason for subnets or range + DEBUG_LOG(_L("INVALID_ID_INFORMATION (Remote ID Type not supported)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + }//switch + } + else //No id sent (That means we're negotiating directly with the end host. We check it's TRUE! + { + if (!iRemoteAddr1_ID_II.IsUnspecified()) + { + DEBUG_LOG(_L("IDcr expected and not received!")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + } + + return ETrue; +} + + +TBool CIkev1Negotiation::CheckIdentL(const TPayloadISAKMP *aPayload) +{ + const TIdentISAKMP *ident = TIdentISAKMP::Ptr(aPayload); + + //payload not present + if (!ident) + { + DEBUG_LOG(_L("NO ID PAYLOAD")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(PAYLOAD_MALFORMED); + return EFalse; + } + + if (iPhase == PHASE_I) + { + TUint8 protocol = ident->GetProtocol(); + if ((protocol != KProtocolInetUdp) && (protocol != 0)) + { + DEBUG_LOG(_L("INVALID_ID_INFORMATION: Bad Phase I Protocol (Only UDP(17) or 0 accepted)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + TUint16 port = ident->GetPort(); + if ((port != 0) && (port != IKE_PORT) && (port != FLOATED_IKE_PORT) ) + { + DEBUG_LOG(_L("INVALID_ID_INFORMATION: Invalid Bad Phase I Port. (Only 0, 500 or 4500 accepted)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + switch (ident->GetIDType()) + { + case ID_IPV4_ADDR: + case ID_IPV6_ADDR: + case ID_FQDN: + case ID_USER_FQDN: + case ID_DER_ASN1_DN: + break; + default: + DEBUG_LOG(_L("INVALID_ID_INFORMATION: Invalid Type (Only IPV4/IPV6/User FQDN and DER ASN1 DN accepted in PHASE I)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_ID_INFORMATION); + return EFalse; + } + } + + return ETrue; +} + + +//Certificate Request Payload processing (all modes). +TBool CIkev1Negotiation::ProcessCertificateReqL(const TCertificateReqISAKMP *aCertReq) +{ + if (iChosenProposal_I.iAttrList->iAuthMethod == IKE_A_CRACK) + { + DEBUG_LOG(_L("CR ignored when CRACK auth !)")); + return ETrue; + } + + TInt ret = CheckEncodingL(aCertReq->GetEncoding()); + switch (ret) + { + case KErrGeneral: + return EFalse; + case KErrNotSupported: //Not supported but not an error, just ignored + return ETrue; + } + + if ( !iPkiService ) + return EFalse; + TBool Status = EFalse; + // + // No specific CA asked. Find a certificate using own trusted CA list + // + if ( ReadOwnCertL()) + { + Status = ETrue; + } + + return Status; + +} + + +//Certificate Request Payload(s) processing (all modes). +TBool CIkev1Negotiation::ProcessCertificateReqArrayL(const CArrayFixFlat *aCRPayloadArray) +{ + + TInt count = aCRPayloadArray->Count(); + if ( count == 0 ) + { + return ETrue; // No Certificate requests + } + + if ( ProcessCertificateReqL(aCRPayloadArray->At(0)) ) + { + DEBUG_LOG(_L("User Certificate required by peer found")); + iSendCert = ETrue; //Requires sending our cert in next interchange where allowed/expected, otherwise not sent + return ETrue; + } + HBufC8* CAName = NULL; + CIkeCaList* trustedCaList = iPkiService->CaList(); + + TInt Status=0; + + for (TInt i=0; i < trustedCaList->Count(); i++) + { + CIkeCaElem* CaElem = (*trustedCaList)[i]; + + CAName = IkeCert::GetCertificateFieldDERL(CaElem->Certificate(), KSubjectName); + CleanupStack::PushL(CAName); + + TRAP_IGNORE(Status=iPkiService->ReadChainL(iHostData, CAName)); + + CleanupStack::PopAndDestroy(CAName); + CAName=NULL; + + if ( Status == KErrNone ) + { + delete iOwnCert; + iOwnCert = iPkiService->GetCertificate(); + + iICA1 = iPkiService->GetTrustedICA1(); + + iICA2 = iPkiService->GetTrustedICA2(); + + iPeerTrustedCA = iPkiService->GetTrustedCA(); + + iSendCert = ETrue; //Requires sending our cert in next interchange where allowed/expected, otherwise not sent + + DEBUG_LOG(_L("Certificate chain Found!")); + return ETrue; + } + } + + + if ( Status == KVpnErrInvalidCaCertFile) + { + SetErrorStatus(KVpnErrInvalidCaCertFile); + + SendNotifyL(CERTIFICATE_UNAVAILABLE); + + DEBUG_LOG(_L("Certificate chain read failed!")); + + return EFalse; + } + + SetErrorStatus(KKmdIkeNoCertFoundErr); + SendNotifyL(CERTIFICATE_UNAVAILABLE); + DEBUG_LOG(_L("Certificate Chain r!")); + + return EFalse; +} + +//Certificate Payload(s) processing (all modes). +TBool CIkev1Negotiation::ProcessCertificateArrayL(CArrayFixFlat* aCertArray) +{ + TBool Status; + if ( iCertRequested ) + Status = EFalse; + else Status = ETrue; + + if ( iPkiService && aCertArray->Count() ) + { + const CIkeCaList* trustedCaList = iPkiService->CaList(); + CX509Certificate* PeerCert = IkePkiUtils::VerifyCertificateL(*aCertArray, + *trustedCaList); + if ( PeerCert ) + { + delete iPeerX509Cert; + iPeerX509Cert = PeerCert; + DEBUG_LOG(_L("Peer Certificate is OK")); + Status = ETrue; + } + else + { + Status = EFalse; + DEBUG_LOG(_L("Peer Certificate is rejected")); + } + } + + return Status; +} + +//Checks the signature sent by the peer host +TBool CIkev1Negotiation::ProcessSignatureL(const TSignatureISAKMP *aSigPayload) +{ + TBool ret; + //payload not present + if (!aSigPayload || !iPeerX509Cert ) + { + DEBUG_LOG(_L("NO SIG PAYLOAD")); + SetErrorStatus(KKmdIkePeerAuthFailed); + SendNotifyL(PAYLOAD_MALFORMED); + return EFalse; + } + + //DSS only allows SHA1 as hash + TUint16 tmp = iChosenProposal_I.iAttrList->iHashAlg; + if (iChosenProposal_I.iAttrList->iAuthMethod==DSS_SIG) + iChosenProposal_I.iAttrList->iHashAlg = HASH_SHA1; + + TBuf8 hash; + //Verify the peer signature + if (iRole==RESPONDER) + { + ComputeHash1L(hash); //Computes the value of iHASH_I the signature checking + //Nothing else to compute. + } + else //Initiator + { + ComputeHashrL(hash); //Computes the value of CRACK digest for signature checking + } + + ret = VerifySignatureL(iPeerX509Cert, (TUint8 *)hash.Ptr(), hash.Length(), aSigPayload->SigData(),aSigPayload->GetDataLength()); + + //restores the value of the Hash alg. + iChosenProposal_I.iAttrList->iHashAlg = tmp; + + if (!ret) + { + DEBUG_LOG(_L("INVALID_SIGNATURE 2")); + SetErrorStatus(KKmdIkePeerAuthFailed); + SendNotifyL(INVALID_SIGNATURE); + return EFalse; + } + + DEBUG_LOG(_L("Peer Signature is OK")); + return ETrue; +} + + +TBool CIkev1Negotiation::ProcessHashL(const THashISAKMP *aHashPayload) +{ + TBool Status = EFalse; + if (aHashPayload) + { + //Compute peer's hash + TBuf8 hash; + if ( (iStage == 6) || ((iStage == 2) && (iExchange == ISAKMP_EXCHANGE_AGGR))) + ComputeHashrL(hash); + else ComputeHash1L(hash); + Status = (Mem::Compare((TUint8 *)hash.Ptr(), hash.Length(), aHashPayload->Data(), aHashPayload->DataLen()) == 0 ); + if ( !Status ) + { + DEBUG_LOG(_L("INVALID_HASH_INFORMATION")); + SendNotifyL(INVALID_HASH_INFORMATION); + } + } + + return Status; +} + + +TBool CIkev1Negotiation::ProcessHash2L(const ThdrISAKMP &aHdr, const THashISAKMP *aHashPayload, TUint aPadding) +{ + TBool Status = EFalse; + if ( aHashPayload ) + { + TUint8* hashMsg = (TUint8*)aHashPayload->Next(); + TInt hashMsgLen = aHdr.GetLength() - sizeof(aHdr) - aHashPayload->GetLength() - aPadding; + Status = VerifyHash2L(aHashPayload, hashMsg, hashMsgLen); + if (!Status) + { + DEBUG_LOG(_L("INVALID_HASH_INFORMATION")); + SendNotifyL(INVALID_HASH_INFORMATION); + } + } + else + { + DEBUG_LOG(_L("PAYLOAD_MALFORMED")); + SendNotifyL(PAYLOAD_MALFORMED); + } + + return Status; +} + + +//Check a notification Payload inserted in a normal exchange (MAIN , AGGR, QUICK) +TBool CIkev1Negotiation::ProcessNotificationL(const TNotificationISAKMP *aNotifPayload) +{ + if (!aNotifPayload) + return ETrue; //optional so noting happens + + if (!CheckDOI(aNotifPayload->GetDOI())) + { + DEBUG_LOG(_L("Bad DOI in the NOT payload")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(DOI_NOT_SUPPORTED); //send the informational exchange + return EFalse; + } + + switch(aNotifPayload->GetMsgType()) + { + case DOI_RESPONDER_LIFETIME: + return ProcessResponderLifetimeL(aNotifPayload); + case DOI_REPLAY_STATUS: + return ProcessReplayStatus(aNotifPayload); + case DOI_INITIAL_CONTACT: + return ProcessInitialContactL(aNotifPayload); + default: + DEBUG_LOG(_L("INVALID MESSAGE TYPE in NOT payload")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(PAYLOAD_MALFORMED); + return EFalse; + } + +} + + +//Processes a RESPONDER-LIFETIME NOT payload +TBool CIkev1Negotiation::ProcessResponderLifetimeL(const TNotificationISAKMP *aNotifPayload) +{ + TBuf8<2 * ISAKMP_COOKIE_SIZE> spi, own_neg_spi; + DEBUG_LOG(_L("Processing RESPONDER-LIFETIME")); + + + if (!((iPhase == PHASE_II) && (iStage == 2))) + { + if ( iPhase == PHASE_I ) { + DEBUG_LOG(_L("RESPONDER-LIFETIME payload in phase 1, ignored !!")); + return ETrue; + } + else { + DEBUG_LOG(_L("Unexpected RESPONDER-LIFETIME payload (Bad stage)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_PAYLOAD_TYPE); + return EFalse; + } + } + + TUint8 protocol = aNotifPayload->GetProtocol(); + if ((protocol != PROTO_IPSEC_AH) && (protocol != PROTO_IPSEC_ESP) && + (protocol != PROTO_ISAKMP) && (protocol != 0)) + { + DEBUG_LOG(_L("Bad protocol in the RESPONDER-LIFETIME payload")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_PROTOCOL_ID); + return EFalse; + } + + TUint8 spi_size = aNotifPayload->GetSPISize(); + CProposal_II *prop; + TInt i; + //If SPI sent + switch (spi_size) + { + case 2 * ISAKMP_COOKIE_SIZE: //ISAKMP spi + spi.Copy(aNotifPayload->GetSPI(), aNotifPayload->GetSPISize()); + own_neg_spi.Copy(iCookie_I); + own_neg_spi.Append(iCookie_R); + + if (spi.Compare(own_neg_spi) != 0) + { + DEBUG_LOG(_L("Invalid SPI size in the RESPONDER-LIFETIME payload. Payload ignored")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_SPI); + return EFalse; + } + if (iChosenProp_IIList->Count() > 1) + { + DEBUG_LOG(_L("RESPONDER-LIFETIME ignored. More than one SA (need a IPsec SPI to know which one to use) ")); + return EFalse; + } + prop = iChosenProp_IIList->At(0); //Only one proposal + break; + case 0: //Compatibility with Alchemy cc500 + if (iChosenProp_IIList->Count() > 1) + { + DEBUG_LOG(_L("RESPONDER-LIFETIME ignored. More than one SA (need a IPsec SPI to know which one to use) ")); + return EFalse; + } + + prop = iChosenProp_IIList->At(0); //Only one proposal + break; + case sizeof(TUint32): //IPSEC SPI + spi.Copy(aNotifPayload->GetSPI(), aNotifPayload->GetSPISize()); + prop = NULL; //Only for the debugger, the loop will have at least one proposal + for (i = 0; i < iChosenProp_IIList->Count(); i++) + { + prop = iChosenProp_IIList->At(i); //Only one proposal + if (((prop->iSPI.Compare(spi) == 0) && prop->iProtocol == protocol)) //right prop + break; + } + + if (i == iChosenProp_IIList->Count()) //No prop matches + { + DEBUG_LOG(_L("RESPONDER-LIFETIME ignored. IPsec SPI doesn't match any chosen proposal")); + return EFalse; + } + break; + default: + DEBUG_LOG(_L("Bad SPI size in the RESPONDER-LIFETIME payload")); + return EFalse; + } + TAttrib_II *transform = prop->iAttrList->At(0); //Only one transform + TInt data_len = aNotifPayload->GetNotifDataSize(); + TUint8 *data_ptr = aNotifPayload->GetNotifData(); + TUint16 lifeType = 0; //No type assigned yet + TInt64 lifeValue = 0; //No type assigned yet + TInt64 lifeValue32; + TInt64 curr_lifeValue = 0; + TInt32 duration; + + TDataISAKMP *attr = (TDataISAKMP*)data_ptr; + while (data_len > 0) + { + data_len = data_len - attr->Size(); + if (data_len < 0) //Mismatch between lengths!!! + { + DEBUG_LOG(_L("RESPONDER-LIFETIME (Length mismatch in the attibutes)")); + return EFalse; + } + switch (attr->Type()) + { + case DOI_ATTR_TYPE_LIFE_TYPE: + case OAKLEY_ATTR_TYPE_LIFE_TYPE: + lifeType = attr->Value(); + if (!CheckLifeType(lifeType)) + { + DEBUG_LOG(_L("RESPONDER-LIFETIME (Invalid lifetime type)")); + return EFalse; + } + break; + case DOI_ATTR_TYPE_LIFE_DUR: + case OAKLEY_ATTR_TYPE_LIFE_DUR: + if (attr->IsBasic()) + { + duration = ByteOrder::Swap32(attr->Value()); + lifeValue = MAKE_TINT64(0, duration); + lifeValue32 = I64LOW(lifeValue); + if (lifeType == SECONDS) + { + Desc8ToTInt64(transform->iLifeDurationSecs, curr_lifeValue); //can't fail + if (lifeValue < curr_lifeValue) + transform->iLifeDurationSecs.Copy((TUint8 *)&lifeValue32, sizeof(lifeValue32)); + } + else if (lifeType == KBYTES) + { + Desc8ToTInt64(transform->iLifeDurationKBytes, curr_lifeValue); //can't fail + if (lifeValue < curr_lifeValue) + transform->iLifeDurationKBytes.Copy((TUint8 *)&lifeValue32, sizeof(lifeValue32)); + } + else + { + DEBUG_LOG(_L("RESPONDER-LIFETIME (Invalid lifetime type)")); + return EFalse; + } + } + else //Not basic + { + TPtrC8 ptr(attr->VarValue(),attr->Length()); + + if (lifeType == SECONDS) + { + if (Desc8ToTInt64(ptr, lifeValue) != KErrNone) + { + DEBUG_LOG(_L("RESPONDER-LIFETIME Lifetime(Sec) Overflowed Setting to maximum value")); + } + Desc8ToTInt64(transform->iLifeDurationSecs, curr_lifeValue); //can't fail + if (lifeValue < curr_lifeValue) + transform->iLifeDurationSecs.Copy(attr->VarValue(),attr->Length()); + } + else if (lifeType == KBYTES) + { + if (Desc8ToTInt64(ptr, lifeValue) != KErrNone) + { + DEBUG_LOG(_L("RESPONDER-LIFETIME Lifetime(KBytes) Overflowed Setting to maximum value")); + } + Desc8ToTInt64(transform->iLifeDurationKBytes, curr_lifeValue); //can't fail + if (lifeValue < curr_lifeValue) + transform->iLifeDurationKBytes.Copy(attr->VarValue(),attr->Length()); + } + else + { + DEBUG_LOG(_L("RESPONDER-LIFETIME (Invalid lifetime type)")); + return EFalse; + } + } + break; + default: + DEBUG_LOG1(_L("RESPONDER-LIFETIME (Invalid attribute (%d) received)"), attr->Type()); + return EFalse; + }//switch + attr = attr->Next(); + }//while + + return ETrue; +} + +//Processes a REPLAY-STATUS NOT payload +TBool CIkev1Negotiation::ProcessReplayStatus(const TNotificationISAKMP *aNotifPayload) +{ + TBuf8<2 * ISAKMP_COOKIE_SIZE> spi, own_neg_spi; + + DEBUG_LOG(_L("Processing REPLAY-STATUS")); + + if (!((iPhase == PHASE_II) && ((iStage == 1) || (iStage == 2)))) + { + DEBUG_LOG(_L("Unexpected REPLAY-STATUS payload (Bad stage)")); + return EFalse; + } + + TUint8 protocol = aNotifPayload->GetProtocol(); + if ((protocol != PROTO_IPSEC_AH) && (protocol != PROTO_IPSEC_ESP) && + (protocol != PROTO_ISAKMP) && (protocol != 0)) + { + DEBUG_LOG(_L("Bad protocol in the REPLAY-STATUS payload")); + return EFalse; + } + + TInt i; + TUint8 spi_size = aNotifPayload->GetSPISize(); + CProposal_II *prop; + //If SPI sent + switch (spi_size) + { + case 2 * ISAKMP_COOKIE_SIZE: //ISAKMP spi + spi.Copy(aNotifPayload->GetSPI(), aNotifPayload->GetSPISize()); + own_neg_spi.Copy(iCookie_I); + own_neg_spi.Append(iCookie_R); + if (spi.Compare(own_neg_spi) != 0) + { + DEBUG_LOG(_L("Invalid SPI size in the REPLAY-STATUS payload. Payload ignored")); + return EFalse; + } + if (iChosenProp_IIList->Count() > 1) + { + DEBUG_LOG(_L("REPLAY-STATUS ignored. More than one IPsec SA (need an IPsec SPI to know which one to use) ")); + return EFalse; + } + break; + case 0: //Compatibility with Alchemy cc500 + if (iChosenProp_IIList->Count() > 1) + { + DEBUG_LOG(_L("RESPONDER-LIFETIME ignored. More than one SA (need a IPsec SPI to know which one to use) ")); + return EFalse; + } + prop = iChosenProp_IIList->At(0); //Only one proposal + break; + case sizeof(TUint32): //IPSEC SPI + spi.Copy(aNotifPayload->GetSPI(), aNotifPayload->GetSPISize()); + for (i = 0; i < iChosenProp_IIList->Count(); i++) + { + prop = iChosenProp_IIList->At(i); //Only one proposal + if (((prop->iSPI.Compare(spi) == 0) && prop->iProtocol == protocol)) //right prop + break; + } + if (i == iChosenProp_IIList->Count()) //No prop matches + { + DEBUG_LOG(_L("REPLAY-STATUS ignored. IPsec SPI doesn't match any chosen proposal")); + return EFalse; + } + break; + default: + DEBUG_LOG(_L("Bad SPI size in the REPLAY-STATUS payload")); + return EFalse; + } + + TInt data_len = aNotifPayload->GetNotifDataSize(); + TUint32 *data = (TUint32 *)aNotifPayload->GetNotifData(); + if (STATIC_CAST(TUint, data_len) < sizeof(*data)) + { + DEBUG_LOG(_L("REPLAY-STATUS (Length mismatch in the attibutes)")); + return EFalse; + } + +#ifdef _DEBUG + if (ByteOrder::Swap32(*data) == 0) + DEBUG_LOG(_L("Anti-Replay Disabled on Peer Host")); + else + DEBUG_LOG(_L("Anti-Replay Enabled on Peer Host")); +#endif + return ETrue; +} + + +TBool CIkev1Negotiation::ProcessInitialContactL(const TNotificationISAKMP *aNotifPayload) +{ + TBuf8<2 * ISAKMP_COOKIE_SIZE> spi, neg_spi; + + DEBUG_LOG(_L("Processing INITIAL-CONTACT")); + // 7 = CRACK + if (!(iPhase == PHASE_I && (iStage == 5 || iStage == 6 || iStage == 7))) + { + DEBUG_LOG(_L("Unexpected INITIAL-CONTACT payload (Bad stage)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_PAYLOAD_TYPE); + return EFalse; + } + + if (aNotifPayload->GetProtocol() != PROTO_ISAKMP && + aNotifPayload->GetProtocol() != 0 ) + + { + DEBUG_LOG(_L("Bad protocol in the INITIAL_CONTACT payload")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_PROTOCOL_ID); + return EFalse; + } + + if (aNotifPayload->GetSPISize() != 2 * ISAKMP_COOKIE_SIZE) + { + DEBUG_LOG(_L("Bad SPI size in the INITIAL_CONTACT payload")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_SPI); + return EFalse; + } + spi.Copy(aNotifPayload->GetSPI(), aNotifPayload->GetSPISize()); + neg_spi.Copy(iCookie_I); + neg_spi.Append(iCookie_R); + + if (spi.Compare(neg_spi) != 0) + { + DEBUG_LOG(_L("Invalid SPI size in the INITIAL_CONTACT payload")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_SPI); + return EFalse; + } + + if ( iRole == RESPONDER ) + { + // Expired SAs are not returned. + TIkev1SAData* sa = iPluginSession->FindIkev1SADataWithAddr( iRemoteAddr ); + while ( sa != NULL ) + { + iPluginSession->UpdateIkev1SAL( sa->iSAId, ETrue ); + sa = iPluginSession->FindIkev1SADataWithAddr( iRemoteAddr ); + } + + // Delete other ongoing negotiations. + CIkev1Negotiation* next = iPluginSession->FirstNegotiation(); + while ( next != NULL ) + { + CIkev1Negotiation* current = next; + next = current->iNext; + if ( current != this ) + { + delete current; + } + } + } + + return ETrue; +} + + + +void CIkev1Negotiation::ProcessVendorL(CArrayFixFlat* aVids) +{ + TBool result; + TInt i = 0; + + while ( i < aVids->Count() ) + { + TVendorISAKMP* VendorPayload = (TVendorISAKMP*)aVids->At(i); + DEBUG_LOG(_L("Vendor ID received!\nHex: ")); + DEBUG_LOG_ARRAY(VendorPayload->VIDData(), VendorPayload->GetLength() - sizeof(*VendorPayload)); + + if ( iLocalAddr.Family() == KAFUnspec ) + User::LeaveIfError( iPluginSession->GetLocalAddress( iLocalAddr ) ); // No local address info, get it ! + + result = EFalse; + iNAT_T_Required = ProcessVendorId(&result, + (TUint8*)iCookie_I.Ptr(), + (TUint8*)iCookie_R.Ptr(), + iLocalAddr, + VendorPayload); + if ( result ) + { + iFamiliarPeer = result; +#ifdef _DEBUG + DEBUG_LOG(_L("Nokia VPN gateway in peer!")); + if ( iNAT_T_Required ) { + DEBUG_LOG(_L("NAT Traversal needed!")); + if ( !iHostData->iUseNatProbing ) + DEBUG_LOG(_L(" NAT probe not requested! NAT-T not used!")); + } +#endif // _DEBUG + iNAT_T_Required = iNAT_T_Required & iHostData->iUseNatProbing; + } + else + { + if ( CheckDPDVendorId(VendorPayload) ) + { + DEBUG_LOG(_L("Peer supports IETF Dead Peer Detection!")); + iDPDSupported = ETrue; + } + else if ( iNatDiscovery ) + { + result = iNatDiscovery->CheckNatVendorId(VendorPayload); + if ( result ) + { + DEBUG_LOG(_L("Peer supports IETF (draft-03) NAT Traversal!")); + } + else + { + result = iNatDiscovery->CheckRfcNatVendorId(VendorPayload); + if ( result ) + { + iVendorIDRfc=ETrue; + DEBUG_LOG(_L("Peer supports IETF NAT Traversal!")); + } + } + } + } + + i ++; + } + +} + +// +//Process Internal address payload received +// +void CIkev1Negotiation::ProcessIntAddrL(const TINTNETISAKMP *aIntnetPayload) +{ + if ( aIntnetPayload && iFamiliarPeer && iHostData->iUseInternalAddr ) { + delete iInternalAddr; //delete if already exists (old) + iInternalAddr = NULL; + iInternalAddr = ProcessIntNetL((TINTNETISAKMP*) aIntnetPayload); +#ifdef _DEBUG + if ( iInternalAddr) { + TBuf<80> buf; + TBuf<40> txt_addr; + iInternalAddr->iClientIntAddr.OutputWithScope(txt_addr); + DEBUG_LOG1(_L("Internal address received: %S"),&txt_addr); + } +#endif + } +} + +//Computes the hash for phase II +void CIkev1Negotiation::ComputeHash2L(TDes8& aHash, TInt aStage, const TUint8 *aHashMsg, TInt aHashMsgLen) +{ + + HBufC8* prf_data = + HBufC8::NewLC(((aHashMsgLen + iNONCE_I.Length() + iNONCE_R.Length() + (2*sizeof(TUint32))) | 0x3) + 1); + + if (aStage == 3) + prf_data->Des().Append(0); + + TUint32 id = ByteOrder::Swap32(iMessageId); + prf_data->Des().Append((TUint8*)&id,sizeof(iMessageId)); + DEBUG_LOG(_L("ID")); + switch (aStage) + { + case 2: + prf_data->Des().Append(iNONCE_I); + //No break is intended + case 1: + prf_data->Des().Append(aHashMsg,aHashMsgLen); + break; + case 3: + + prf_data->Des().Append(iNONCE_I); + DEBUG_LOG(_L("iNONCE_I")); + prf_data->Des().Append(iNONCE_R); + DEBUG_LOG(_L("iNONCE_R")); + break; + default: + CleanupStack::PopAndDestroy(); //prf_data + return; + } + + DEBUG_LOG1(_L("Hash_II(%d) prf"),aStage); + + ComputePRFL(aHash, iSKEYID_a, prf_data->Des()); + + DEBUG_LOG(_L("HASH")); + + CleanupStack::PopAndDestroy(); //prf_data + +} + +//Computes the hash for a protected informational exchange +void CIkev1Negotiation::ComputeHashInfL(TDes8& aHash, const TUint8 *aHashMsg, TInt aHashMsgLen) +{ + + HBufC8* prf_data = + HBufC8::NewLC(((aHashMsgLen + sizeof(iMessageId)) | 0x3) + 1); + + //prf(SKEYID_a, M_ID | N/D) + TUint32 id = ByteOrder::Swap32(iMessageId); + prf_data->Des().Append((TUint8*)&id, sizeof(iMessageId)); + + prf_data->Des().Append(aHashMsg, aHashMsgLen); + + DEBUG_LOG(_L("Hash_NOT prf")); + + ComputePRFL(aHash, iSKEYID_a, prf_data->Des()); + + DEBUG_LOG(_L("HASH")); + + CleanupStack::PopAndDestroy(); //prf_data + +} + +//Verifies that aHash is correct +TBool CIkev1Negotiation::VerifyHash2L(const THashISAKMP *aHash,const TUint8 *aHashMsg, TInt aHashMsgLen) +{ + TBuf8 tmp_hash; + + ComputeHash2L(tmp_hash, iStage, aHashMsg, aHashMsgLen); //Computes the specified phase II hash + + TBool Status = (Mem::Compare((TUint8*)tmp_hash.Ptr(), tmp_hash.Length(), aHash->Data(), aHash->DataLen()) == 0); + + return Status; +} + +//Verifies the hash of a Notification or Delete payload +// Used also to verify the hash of Transaction exchange (Attribute payload) +TBool CIkev1Negotiation::VerifyInformationalHashL(const THashISAKMP *aHash,const TPayloadISAKMP *aPayload, TUint32 aMessageId) +{ + TBuf8 tmp_hash; + + TUint32 tmp_id = ByteOrder::Swap32(aMessageId); + HBufC8 *prf_buf = HBufC8::NewLC(sizeof(tmp_id) + aPayload->GetLength()); + prf_buf->Des().Copy((TUint8 *)&tmp_id , sizeof(tmp_id)); + prf_buf->Des().Append((TUint8 *)aPayload, aPayload->GetLength()); + + ComputePRFL(tmp_hash, iSKEYID_a, prf_buf->Des()); + TPtrC8 hash_ptr(aHash->Data(),aHash->DataLen()); + TBool b = (tmp_hash.Compare(hash_ptr)==0); + CleanupStack::PopAndDestroy(); //prf_buf + return (b); +} + + +//Computes Own Nonce using current time a seed +void CIkev1Negotiation::ComputeNonceL() +{ + DEBUG_LOG(_L("Computed NONCE.")); + if (iRole==INITIATOR) + { + iNONCE_I.SetLength(OAKLEY_DEFAULT_NONCE_SIZE); + TRandom::RandomL(iNONCE_I); + } + else + { + iNONCE_R.SetLength(OAKLEY_DEFAULT_NONCE_SIZE); + TRandom::RandomL(iNONCE_R); + } +} + +//Computes HASH_R value +void CIkev1Negotiation::ComputeHashrL(TDes8 &aHash) +{ + TInt id_size = 0; + TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod; + + DEBUG_LOG(_L("Computing HASH_R")); + + if ( auth_method != IKE_A_CRACK ) { + if (iRole==INITIATOR) + { //peer id. payload + id_size = iPeerIdentPayloadSize; + DEBUG_LOG(_L("PeerID")); + } + else + { //Own identification payload + id_size = iOwnIdentPayloadSize; + DEBUG_LOG(_L("OwnID")); + } + } + + DEBUG_LOG(_L("SKEYID")); + + HBufC8 *prf_data; + if (iRole==INITIATOR) //peer id. payload + { + prf_data = HBufC8::NewLC(iPeerPublicKey.Length() + iOwnPublicKey_ptr.Length() + iCookie_R.Length() + + iCookie_I.Length() + iSAPayloadSize + id_size); + prf_data->Des().Copy(iPeerPublicKey); + prf_data->Des().Append(iOwnPublicKey_ptr); + prf_data->Des().Append(iCookie_R); + prf_data->Des().Append(iCookie_I); + prf_data->Des().Append(iSAPayload,iSAPayloadSize); //stored at the begining + if ( auth_method != IKE_A_CRACK ) + prf_data->Des().Append(iPeerIdentPayload, iPeerIdentPayloadSize); + } + else //RESPONDER + { + prf_data = HBufC8::NewLC(iOwnPublicKey_ptr.Length() + iPeerPublicKey.Length() + iCookie_R.Length() + + iCookie_I.Length() + iSAPayloadSize + id_size); + prf_data->Des().Copy(iOwnPublicKey_ptr); + prf_data->Des().Append(iPeerPublicKey); + prf_data->Des().Append(iCookie_R); + prf_data->Des().Append(iCookie_I); + prf_data->Des().Append(iSAPayload,iSAPayloadSize); //stored at the begining + if ( auth_method != IKE_A_CRACK ) + prf_data->Des().Append(iOwnIdentPayload, iOwnIdentPayloadSize); + } + + DEBUG_LOG(_L("PRF")); + + ComputePRFL(aHash, iSKEYID, prf_data->Des()); + + CleanupStack::PopAndDestroy(); //prf_data + + DEBUG_LOG(_L("HASH_R")); + +} + + +//Computes the value of iHASH_I +void CIkev1Negotiation::ComputeHash1L(TDes8 &aHash) +{ + TInt id_size = 0; + TUint16 auth_method = iChosenProposal_I.iAttrList->iAuthMethod; + + DEBUG_LOG(_L("Computing HASH_I")); + + if ( auth_method != IKE_A_CRACK ) { + if (iRole==INITIATOR) //Own identification payload + { + id_size = iOwnIdentPayloadSize; + DEBUG_LOG(_L("OwnID")); + } + else //peer id. payload + { + id_size = iPeerIdentPayloadSize; + DEBUG_LOG(_L("PeerID")); + } + } + + + DEBUG_LOG(_L("SKEYID")); + + HBufC8 *prf_data; + if (iRole==INITIATOR) + { + prf_data = HBufC8::NewLC(iOwnPublicKey_ptr.Length() + iPeerPublicKey.Length() + iCookie_I.Length() + + iCookie_R.Length() + iSAPayloadSize + id_size); + prf_data->Des().Copy(iOwnPublicKey_ptr); + prf_data->Des().Append(iPeerPublicKey); + prf_data->Des().Append(iCookie_I); + prf_data->Des().Append(iCookie_R); + prf_data->Des().Append(iSAPayload,iSAPayloadSize); //stored at the begining + if ( auth_method != IKE_A_CRACK ) + prf_data->Des().Append(iOwnIdentPayload,iOwnIdentPayloadSize); + } + else //RESPONDER + { + prf_data = HBufC8::NewLC(iPeerPublicKey.Length() + iOwnPublicKey_ptr.Length() + iCookie_I.Length() + + iCookie_R.Length() + iSAPayloadSize + id_size); + prf_data->Des().Copy(iPeerPublicKey); + prf_data->Des().Append(iOwnPublicKey_ptr); + prf_data->Des().Append(iCookie_I); + prf_data->Des().Append(iCookie_R); + prf_data->Des().Append(iSAPayload,iSAPayloadSize); //stored at the begining + + if ( auth_method != IKE_A_CRACK ) + prf_data->Des().Append(iPeerIdentPayload, iPeerIdentPayloadSize); + } + + DEBUG_LOG(_L("PRF")); + + ComputePRFL(aHash, iSKEYID, prf_data->Des()); + CleanupStack::PopAndDestroy(); //prf_buf + DEBUG_LOG(_L("HASH_I")); +} + + +//Checks the encryption alg is valid +TBool CIkev1Negotiation::CheckEncrAlg(TUint16 aValue) +{ + switch (aValue) + { + case DES_CBC: + case DES3_CBC: + case AES_CBC: + return ETrue; + case IDEA_CBC: + case BLOWFISH_CBC: + case RC5_R16_B64_CBC: + case CAST_CBC: + DEBUG_LOG(_L("Not implemented Encr algorithm")); + return ETrue; // Unknown attribute value NOT a fatal error ! + } + DEBUG_LOG(_L("Bad Encr algorithm")); + + return ETrue; // Unknown attribute value NOT a fatal error ! +} + + + +TBool CIkev1Negotiation::CheckHashAlg(TUint16 aValue) +{ + switch (aValue) + { + case HASH_MD5: + case HASH_SHA1: + return ETrue; + case HASH_TIGER: + DEBUG_LOG(_L("Not implemented Hash algorithm")); + return ETrue; // Unknown attribute value NOT a fatal error ! + } + DEBUG_LOG(_L("Bad Hash algorithm")); + return ETrue; // Unknown attribute value NOT a fatal error ! + +} + + +TBool CIkev1Negotiation::CheckAuthMethod(TUint16 aValue) +{ + switch (aValue) + { + case PRE_SHARED: + if (iHostData->iPresharedKey.iKey.Length()==0) //No preshared key defined + { + DEBUG_LOG(_L("Authentication method error (No Preshared key available")); + return EFalse; + } + return ETrue; + case RSA_SIG: + case DSS_SIG: + case IKE_A_CRACK: + return ETrue; + } + DEBUG_LOG(_L("Bad Authentication method")); + return ETrue; // Unknown attribute value NOT a fatal error ! + +} + +TBool CIkev1Negotiation::CheckGroupDesc(TUint16 aValue) +{ + switch (aValue) + { + case MODP_768: + case MODP_1024: + case MODP_1536: + case MODP_2048: + return ETrue; + case EC2N_155: + case EC2N_185: + break; + } + + return ETrue; // Unknown attribute value NOT a fatal error ! +} + + +TBool CIkev1Negotiation::CheckGroupType(TUint16 aValue) +{ + switch(aValue) + { + case MODP: + return ETrue; + case ECP: + case EC2N: + break; + } + + return ETrue; // Unknown attribute value NOT a fatal error ! + +} + +TBool CIkev1Negotiation::CheckGroupPrime(const TUint8* /* aValue */, TUint16 /* length */) +{ + return ETrue; +} + +TBool CIkev1Negotiation::CheckGroupGen(const TUint8* /* aValue */, TUint16 /* length */) +{ + return ETrue; +} + +TBool CIkev1Negotiation::CheckGroupCurve(const TUint8* /* aValue */, TUint16 /* length */) +{ + return ETrue; +} + +//Used for Phase I and II +TBool CIkev1Negotiation::CheckLifeType(TUint16 aValue) +{ + switch(aValue) + { + case SECONDS: + case KBYTES: + return ETrue; + } + return EFalse; +} + +TBool CIkev1Negotiation::CheckLifeDuration(const TUint8* /* aValue */, TUint16 /* length */) +{ + return ETrue; +} + +TBool CIkev1Negotiation::CheckPRF(TUint16 aValue) +{ + if (aValue!=OAKLEY_PRF_3DES_CBC_MAC) + { + DEBUG_LOG(_L("Bad PRF")); + return EFalse; + } + return ETrue; +} + +TBool CIkev1Negotiation::CheckKeyLength(TUint16 /*aValue*/,TUint8 aID,TUint8 aProtocol) +{ + TBool Status = ETrue; + switch (aProtocol) + { + case PROTO_ISAKMP: + if ( aID != AES_CBC ) + { + Status = EFalse; //all other supported algs have fixed size + DEBUG_LOG(_L("Key length specified with fixed ISAKMP encryption algorithm")); + } + break; + case PROTO_IPSEC_AH: + Status = EFalse; //Supported algorithms have fixed key length + DEBUG_LOG(_L("Key length specified with fixed AH integrity algorithm")); + break; + case PROTO_IPSEC_ESP: + if ( aID != ESP_AES_CBC ) + { + Status = EFalse; + DEBUG_LOG(_L("Key length specified with fixed ESP encryption algorithm")); + } + break; + default: //Unsupported SA type + Status = EFalse; //Supported algorithms have fixed key length + break; + } + + return Status; +} + +TBool CIkev1Negotiation::CheckFieldSize(TUint16 /* aValue */) +{ + DEBUG_LOG(_L("Field size not supported")); + return EFalse; +} + +TBool CIkev1Negotiation::CheckGroupOrder(const TUint8* /* aValue */, TUint16 /* length */) +{ + DEBUG_LOG(_L("Group Order not supported ")); + return ETrue; // Unknown attribute value NOT a fatal error ! +} + +//Encapsulation mode +TBool CIkev1Negotiation::CheckEncMode(TUint16 aValue) +{ + switch (aValue) + { + case DOI_TUNNEL: + case DOI_TRANSPORT: + return ETrue; + case UDP_ENC_TUNNEL: + case UDP_RFC_ENC_TUNNEL: +// case UDP_ENC_TRANSPORT: + if ( iNAT_D_Flags ) + return ETrue; + break; + } + + DEBUG_LOG(_L("Bad Encapsulation mode")); + return EFalse; + +} + +//defined authentication algorithm types. Other are invalid. +TBool CIkev1Negotiation::CheckAuthAlg(TUint16 aValue) +{ + switch (aValue) + { + case DOI_HMAC_MD5: + case DOI_HMAC_SHA: + return ETrue; + case DOI_DES_MAC: + case DOI_KPDK: + DEBUG_LOG(_L("Unimplemented Auhentication Algorithm")); + } + DEBUG_LOG(_L("Bad Auhentication Algorithm")); + return ETrue; // Unknown attribute value NOT a fatal error ! +} + +//By now only X509_CERT_SIG. Tristate error codes: +//KErrNone -> accepted +//KErrNotSupported ignored but no error Notification. +//KErrGeneral: NOT accepted +TInt CIkev1Negotiation::CheckEncodingL(TUint8 aEncoding) +{ + switch (aEncoding) + { + case X509_CERT_SIG://X.509 Certificate - Signature + break; + case CRL://Certificate Revocation List (CRL) + DEBUG_LOG(_L("WARNING: CRL ignored because not supported")); + return KErrNotSupported; //No notification, just ignored! + case PKCS://PKCS #7 wrapped X.509 certificate + case PGP://PGP Certificate + case DNS ://DNS Signed Key + case X509_CERT_KE://X.509 Certificate - Key Exchange + case KERBEROS://Kerberos Tokens + case ARL://Authority Revocation List (ARL) + case SPKI://SPKI Certificate + case X509_CERT_ATTR://X.509 Certificate - Attribute + DEBUG_LOG(_L("CERT_TYPE_UNSUPPORTED (not supported CERT type)")); + SendNotifyL(CERT_TYPE_UNSUPPORTED); + return KErrNotSupported; // No notification, just ignored! + + default://Invalid encoding type + DEBUG_LOG(_L("INVALID_CERT_ENCODING (not existent CERT type)")); + SendNotifyL(INVALID_CERT_ENCODING); + return KErrNotSupported; // No notification, just ignored! + + } + + return KErrNone; +} + + +//Provisional (Uses as a seed time, Address and port) +TCookie CIkev1Negotiation::CreateCookieL() const +{ + TCookie c; + //Cookie generation is Random no longer uses known data like addr + //or port (wrong?) + c.SetLength(ISAKMP_COOKIE_SIZE); + TRandom::RandomL(c); + return c; +} + +TInt32 CIkev1Negotiation::RandomMessageId() +{ + TTime tmp_time; + tmp_time.UniversalTime(); + TInt64 seed = tmp_time.Int64(); + TInt32 rand = Math::Rand(seed); + return rand; +} + +TBool CIkev1Negotiation::CheckCookies(const TCookie& aInit, const TCookie& aResp) + { + TCookie NULL_COOKIE; + NULL_COOKIE.FillZ(ISAKMP_COOKIE_SIZE); + + if ( iCookie_I.Compare(NULL_COOKIE) != 0 && + iCookie_I.Compare(aInit) != 0 ) + { + DEBUG_LOG(_L("Initiator COOKIE incorrect")); + return EFalse; + } + if ( iCookie_R.Compare(NULL_COOKIE) != 0 && + iCookie_R.Compare(aResp) != 0 ) + { + DEBUG_LOG(_L("Responder COOKIE incorrect")); + return EFalse; + } + + return ETrue; + } + +//Checks if the payload value is correct +TBool CIkev1Negotiation::CheckPayloadCode(TUint8 aPayload) +{ + switch (aPayload) + { + case ISAKMP_PAYLOAD_NONE: + case ISAKMP_PAYLOAD_SA: + case ISAKMP_PAYLOAD_P: + case ISAKMP_PAYLOAD_T: + case ISAKMP_PAYLOAD_KE: + case ISAKMP_PAYLOAD_ID: + case ISAKMP_PAYLOAD_CERT: + case ISAKMP_PAYLOAD_CR: + case ISAKMP_PAYLOAD_HASH: + case ISAKMP_PAYLOAD_SIG: + case ISAKMP_PAYLOAD_NONCE: + case ISAKMP_PAYLOAD_NOTIF: + case ISAKMP_PAYLOAD_D: + case ISAKMP_PAYLOAD_VID: + case ISAKMP_PAYLOAD_ATTRIBUTES: + case ISAKMP_PAYLOAD_CHRE: + case ISAKMP_INT_NETWORK: + case IETF_NAT_DISCOVERY: + case IETF_RFC_NAT_DISCOVERY: + case IETF_NAT_ORIG_ADDR: + case IETF_RFC_NAT_ORIG_ADDR: + return ETrue; //supported payload type + } + DEBUG_LOG1(_L("INVALID_PAYLOAD_TYPE (%x)"),aPayload); + return EFalse; + +} + + +//Checks if the version (major,minor) is supported +TBool CIkev1Negotiation::CheckVersionL(TUint8 aVersion) +{ + if (aVersion >> 4 > MAJOR) + { + DEBUG_LOG(_L("INVALID_MAJOR_VERSION")); + SendNotifyL(INVALID_MAJOR_VERSION); + return EFalse; + } + + if (aVersion & (0x0f) > MINOR) + { + DEBUG_LOG(_L("INVALID_MINOR_VERSION")); + SendNotifyL(INVALID_MINOR_VERSION); + return EFalse; + } + + return ETrue; //version correct +} + +//Checks if the exchange type is valid and the same as in the negotiation +TBool CIkev1Negotiation::CheckExchangeTypeL(TUint8 aType) +{ + switch (aType) + { + case ISAKMP_EXCHANGE_ID: //Main + case ISAKMP_EXCHANGE_AGGR: // Agressive + case ISAKMP_EXCHANGE_INFO: + case IKE_QUICK_MODE: + //invalid Exchange Type Not the same being used and not an error notification + if (aType != iExchange) + { + DEBUG_LOG(_L("INVALID_EXCHANGE_TYPE")); //send the informational exchange + SendNotifyL(INVALID_EXCHANGE_TYPE); //send the informational exchange + return EFalse; //invalid Exchange Type + } + break; + case ISAKMP_EXCHANGE_BASE: // Base + case ISAKMP_EXCHANGE_NONE: // Identity Protection (Main mode in IKE) + case ISAKMP_EXCHANGE_AUTH: // Authentication Only + case IKE_NEW_GROUP_MODE: // New Group Mode + DEBUG_LOG(_L("INVALID_EXCHANGE_TYPE")); //send the informational exchange + SendNotifyL(UNSUPPORTED_EXCHANGE_TYPE); //send the informational exchange + return EFalse; + } + + return ETrue; +} + +//Checks the non-relevant bits are 0. Other comprovations are done when needed +TBool CIkev1Negotiation::CheckFlagsL(TUint8 aFlags) +{ + if (aFlags >> 3 != 0) + { + DEBUG_LOG(_L("INVALID_FLAGS")); //send the informational exchange + SendNotifyL(INVALID_FLAGS); //send the informational exchange + return EFalse; + } + + return ETrue; +} + +//Checks the Id has a correct value. 0 in Phase I, the correct one in Phase II +TBool CIkev1Negotiation::CheckMessageIdL(TUint32 aId) +{ + if (aId != iMessageId) //iMessageId will be 0 during Phase I + { + DEBUG_LOG2(_L("INVALID_MESSAGE_ID %u (neg=%u)"),aId, iMessageId); + SendNotifyL(INVALID_MESSAGE_ID); //send the informational exchange + return EFalse; + } + return ETrue; +} + +//Checks the DOI is valid +TBool CIkev1Negotiation::CheckDOI(TUint32 aDOI) +{ + if (aDOI > IPSEC_DOI) //Not IPSEC nor ISAKMP DOI + return EFalse; + + return ETrue; +} + +//Checks the SIT is valid +TBool CIkev1Negotiation::CheckSituationL(TUint32 aSIT) +{ + //Secrecy and integrity not yet supported + if ((aSIT & IPSEC_SIT_SECRECY) || (aSIT & IPSEC_SIT_INTEGRITY)) + { + DEBUG_LOG(_L("SITUATION_NOT_SUPPORTED")); //send the informational exchange + SendNotifyL(SITUATION_NOT_SUPPORTED); //send the informational exchange + return EFalse; + } + + return ETrue; +} +//check the generic payload is OK. Correct payload + Reserved==0 +TBool CIkev1Negotiation::CheckGenericPayloadL(const TPayloadISAKMP *aPayload) +{ + if (!CheckPayloadCode(aPayload->GetPayload())) + return EFalse; + + if (aPayload->GetReserved() != 0) //Must be always 0 + { + DEBUG_LOG(_L("INVALID RESERVED FIELD")); + SendNotifyL(PAYLOAD_MALFORMED); + return EFalse; + } + + if ((aPayload->GetLength() < MIN_ISAKMP_PAYLOAD_SIZE) || (aPayload->GetLength() > iLengthLeft)) + { + DEBUG_LOG(_L("BAD PAYLOAD SIZE")); + SendNotifyL(PAYLOAD_MALFORMED); + return EFalse; + } + + iLengthLeft -= aPayload->GetLength(); //Updates the length left in the buffer + + return ETrue; + +} + +//checks if protocol supported +TBool CIkev1Negotiation::CheckProtocolL(TUint8 aProtocol) +{ + switch (aProtocol) + { + //PHASE_I Protocol + case PROTO_ISAKMP: //Only when establishing own SA?? + if (iPhase != PHASE_I) + { + DEBUG_LOG(_L("INVALID_PROTOCOL_ID (ISAKMP only allowed in Phase I)")); + SendNotifyL(INVALID_PROTOCOL_ID); + return EFalse; + } + return ETrue; + + //PHASE_II Protocols + case PROTO_IPSEC_AH: + case PROTO_IPSEC_ESP: + if (iPhase != PHASE_II) + { + DEBUG_LOG1(_L("INVALID_PROTOCOL_ID (Prot (%u) only allowed in Phase II)"),aProtocol); + SendNotifyL(INVALID_PROTOCOL_ID); + return EFalse; + } + return ETrue; + } + DEBUG_LOG1(_L("INVALID_PROTOCOL_ID (Unknown Protocol (%u))"),aProtocol); + SendNotifyL(INVALID_PROTOCOL_ID); + return EFalse; +} + +TBool CIkev1Negotiation::CheckSPIL(const TProposalISAKMP *aProposal) +{ + + TUint size=aProposal->GetSPISize(); + if (iPhase == PHASE_I) + { + if (size > MAX_SPI_SIZE) + { + DEBUG_LOG(_L("INVALID_SPI (Bad Size)")); + SendNotifyL(INVALID_SPI); + return EFalse; + } + } + else //Phase II + { + TUint32 spi = 0; + if (aProposal->GetSPISize() > sizeof(TUint32)) + { + DEBUG_LOG(_L("INVALID_SPI (Too big. Max. is 32 bits)")); + SendNotifyL(INVALID_SPI); + return EFalse; + } + Mem::Copy((TUint8 *)&spi, ((TProposalISAKMP *)aProposal)->SPI(), aProposal->GetSPISize()); + spi = ByteOrder::Swap32(spi); + if (spi < 256) //The first 256 are reserved + { + DEBUG_LOG(_L("INVALID_SPI (spi's < 256 are RESERVED)")); + SendNotifyL(INVALID_SPI); + return EFalse; + } + } + return ETrue; +} + +//Checks for transform payloads. MUST NOT abort processing, just discard the payload +TBool CIkev1Negotiation::CheckTransformID(TUint8 aProtocol,TUint8 aID) +{ + switch (aProtocol) + { + case PROTO_ISAKMP: + if (aID != KEY_IKE) + return EFalse; + break; + + case PROTO_IPSEC_AH: + if ( (aID != AH_MD5) && (aID != AH_SHA)) + { + DEBUG_LOG(_L("Unsupported Authentication Algorithm")); + return EFalse; + } + break; + case PROTO_IPSEC_ESP: + switch ( aID ) + { + case ESP_DES_CBC: + case ESP_3DES_CBC: + case ESP_NULL: + case ESP_AES_CBC: + break; + default: + DEBUG_LOG(_L("Unsupported Encryption Algorithm")); + return EFalse; + } + break; + + default: + return EFalse; + } + + return ETrue; +} + + +//Diffie-Hellman key exchange +//The info in iNegotiation MUST be correct +TBool CIkev1Negotiation::ComputeDHPublicValueL() +{ + TUint desc; + if (iPhase == PHASE_I) + { + //If aggressive sends the SA and KE at the same time b4 knowing the chosen group. + //The group in the first proposed transform is chosen. Shouldn't be transforms with + //different groups sent. Checked when using the configuration tool? + if ((iExchange == ISAKMP_EXCHANGE_AGGR) && (iRole == INITIATOR)) + desc = iProposal_I.iAttrList->iGroupDesc; + else + desc = iChosenProposal_I.iAttrList->iGroupDesc; + } + else + { + if (iRole == INITIATOR) //We have to use one of the proposals because we don't have the reply yet + //Anyay only one group can be specified for phase II so it's fine + desc = iProposal_IIList->At(0)->iAttrList->At(0)->iGroupDesc; + else //RESPONDER + desc = iChosenProp_IIList->At(0)->iAttrList->At(0)->iGroupDesc; + } + + delete iOwnKeys; //Happens in phase II because we may recalculate the DH value. + iOwnKeys = NULL; + delete iOwnPublicKey; // Happens in phase II because we may recalculate the DH value. + iOwnPublicKey = NULL; + + iOwnKeys = GeneratePubPrivKeysL(desc); + if (!iOwnKeys) + { + DEBUG_LOG(_L("Error generating DH public and private keys")); + return EFalse; + } + iOwnPublicKey = iOwnKeys->GetPubKey(); //save the public key in a buffer to have easy access + iOwnPublicKey_ptr.Set(iOwnPublicKey->Des()); + return ETrue; +} + + +//Initial IV computation +//Pre:Requires correct Public keys alredy stored!!! +TBool CIkev1Negotiation::InitIVL() +{ + HBufC8* prf_data = + HBufC8::NewLC(((iOwnPublicKey_ptr.Length() + iPeerPublicKey.Length()) | 0x3) + 1); + + if (iRole == INITIATOR) + { + prf_data->Des().Copy(iOwnPublicKey_ptr); + prf_data->Des().Append(iPeerPublicKey); + + } + else //RESPONDER + { + prf_data->Des().Copy(iPeerPublicKey); + prf_data->Des().Append(iOwnPublicKey_ptr); + } + if (iChosenProposal_I.iAttrList->iHashAlg == HASH_MD5) + MD5HashL(prf_data->Des(), iIV); + else SHA1HashL(prf_data->Des(), iIV); + + if (iChosenProposal_I.iAttrList->iEncrAlg == AES_CBC ) + iIVSize = 16; + else iIVSize = 8; + iIV.SetLength(iIVSize); + DEBUG_LOG(_L("Init")); + + CleanupStack::PopAndDestroy(); //prf_data + + return ETrue; +} + + + +//subsequent IV computations. Like when send notifications or beginning of Phase II +TBool CIkev1Negotiation::ComputeIVL(TDes8 &aIV, TInt32 aMessageId) +{ + HBufC8* prf_data = + HBufC8::NewLC(((aIV.Length() + sizeof(aMessageId)) | 0x3) + 1); + + if ((iChosenProposal_I.iAttrList->iEncrAlg != DES3_CBC) && + (iChosenProposal_I.iAttrList->iEncrAlg != AES_CBC) && + (iChosenProposal_I.iAttrList->iEncrAlg != DES_CBC)) + { + return EFalse; + } + //former IV + prf_data->Des().Copy(aIV); + //Message ID + TInt32 id = ByteOrder::Swap32(aMessageId); //Needed to add it + + prf_data->Des().Append((TUint8 *)&id, sizeof(id)); + + DEBUG_LOG(_L("prf")); + if (iChosenProposal_I.iAttrList->iHashAlg == HASH_MD5) + MD5HashL(prf_data->Des(), aIV); + else SHA1HashL(prf_data->Des(), aIV); + + DEBUG_LOG(_L("Computed IV")); + + CleanupStack::PopAndDestroy(); //prf_data + return ETrue; +} + +//Generates all the keying material SKEYID,SKEYID_d,SKEYID_a,SKEYID_e +TBool CIkev1Negotiation::ComputeKeysL() +{ + TUint desc; + //If aggressive sends the SA and KE at the same time b4 knowing the chosen group. + //The group in the first proposed transform is chosen. Shouldn't be transforms with + //different groups sent + if ((iExchange == ISAKMP_EXCHANGE_AGGR) && (iRole == INITIATOR)) + desc = iProposal_I.iAttrList->iGroupDesc; + else + desc = iChosenProposal_I.iAttrList->iGroupDesc; + // + //Computes agreed key + // + HBufC8* agreedKey = ComputeAgreedKeyL(desc, iPeerPublicKey, iOwnKeys); //(gxy) + if ( !agreedKey ) { + DEBUG_LOG(_L("DH secret creation failed (ComputeAgreedKeyL)")); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(INVALID_KEY_INFORMATION); + return EFalse; + } + CleanupStack::PushL(agreedKey); //agreedKey + + // Use prf and agreed DH-key to generate keying material + HBufC8* prf_data = + HBufC8::NewLC(((iNONCE_I.Length() + iNONCE_R.Length() + 2*ISAKMP_COOKIE_SIZE) | 0x3) + 1); + HBufC8* prf_key = + HBufC8::NewLC(((iNONCE_I.Length() + iNONCE_R.Length() ) | 0x3) + 1); + + DEBUG_LOG(_L("Agreed Key.")); + + switch(iChosenProposal_I.iAttrList->iAuthMethod) + { + case RSA_SIG: + case DSS_SIG: + case IKE_A_CRACK: + //For signatures: + //SKEYID = prf(Ni_b|Nr_b, g^xy) + //key + prf_key->Des().Copy(iNONCE_I); + prf_key->Des().Append(iNONCE_R); + ComputePRFL(iSKEYID, prf_key->Des(), agreedKey->Des()); + break; + case PRE_SHARED: + { + //pre-shared keys: + //SKEYID=prf(pre_shared key, Ni_b | Nr_b); + //data + prf_data->Des().Copy(iNONCE_I.Ptr(),iNONCE_I.Length()); + prf_data->Des().Append(iNONCE_R.Ptr(),iNONCE_R.Length()); + DEBUG_LOG(_L("Pre-shared Key")); +#ifdef _UNICODE + HBufC8 *preshared_key_buf = HBufC8::NewLC(iHostData->iPresharedKey.iKey.Length()); + preshared_key_buf->Des().Copy(iHostData->iPresharedKey.iKey); + TPtrC8 preshared_key_ptr(preshared_key_buf->Des()); +#else + TPtrC8 preshared_key_ptr(iHostData->iPresharedKey.iKey); +#endif + ComputePRFL(iSKEYID, preshared_key_ptr, prf_data->Des()); +#ifdef _UNICODE + CleanupStack::PopAndDestroy(); //presharedkey_buf +#endif + } + break; + default://method not implemented + DEBUG_LOG1(_L("ATTRIBUTES_NOT_SUPPORTED:Auth Method %d not supported "),iChosenProposal_I.iAttrList->iAuthMethod); + SetErrorStatus( KKmdIkeNegotFailed ); + SendNotifyL(ATTRIBUTES_NOT_SUPPORTED); + return EFalse; + } + + CleanupStack::PopAndDestroy(2); //prf_data and prf_key + prf_data = + HBufC8::NewLC(((agreedKey->Length() + iSKEYID.Length() + 2*ISAKMP_COOKIE_SIZE + 4) | 0x3) + 1); + + prf_data->Des().Copy(agreedKey->Des()); + prf_data->Des().Append(iCookie_I); + prf_data->Des().Append(iCookie_R); + prf_data->Des().Append(0); + ComputePRFL(iSKEYID_d, iSKEYID, prf_data->Des()); + + prf_data->Des().Copy(iSKEYID_d); + prf_data->Des().Append(agreedKey->Des()); + prf_data->Des().Append(iCookie_I); + prf_data->Des().Append(iCookie_R); + prf_data->Des().Append(1); + ComputePRFL(iSKEYID_a, iSKEYID, prf_data->Des()); + + prf_data->Des().Copy(iSKEYID_a); + prf_data->Des().Append(agreedKey->Des()); + prf_data->Des().Append(iCookie_I); + prf_data->Des().Append(iCookie_R); + prf_data->Des().Append(2); + ComputePRFL(iSKEYID_e, iSKEYID, prf_data->Des()); + + agreedKey->Des().FillZ(); // Zeroe DH secret g^xy + + //Builds the IV + if (!InitIVL()) + { + DEBUG_LOG(_L("Error Computing IV")); + return EFalse; + } + if (iExchange == ISAKMP_EXCHANGE_AGGR) + { + iLastIV.Copy(iIV); //Saves last IV in Phase 1 + iLastIV.SetLength(iIVSize); + DEBUG_LOG(_L("Last IV Saved!")); + } + + //if key extension required: + TUint8 *key; + TInt key_len=0; + TInt total_key_len = ISAKMPEncrKeyLength((TUint8)iChosenProposal_I.iAttrList->iEncrAlg); + if (iSKEYID_e.Length() < total_key_len) + { + DEBUG_LOG(_L("Extending encrytion key...")); + key = new (ELeave) TUint8[total_key_len*2]; + CleanupStack::PushL(key); + key[0] = 0; + TPtr8 kx0_ptr(key, 1, 1); + TPtr8 kx1_ptr(key, 0, total_key_len * 2); + ComputePRFL(kx1_ptr, iSKEYID_e, kx0_ptr); //K1=prf(SKEYID_e,0) + key_len += kx1_ptr.Length(); + + while (key_len < total_key_len) + { + kx0_ptr.Set(&key[key_len - kx1_ptr.Length()], kx1_ptr.Length(), total_key_len); + kx1_ptr.Set(&key[key_len], 0, total_key_len); + ComputePRFL(kx1_ptr, iSKEYID_e, kx0_ptr); //Kx=prf(SKEYID_e,K) + key_len += kx1_ptr.Length(); + } + iSKEYID_e.Copy(key, total_key_len); + CleanupStack::PopAndDestroy(); //key + DEBUG_LOG(_L(" SKEYID_e (EXTENDED)")); + } + else + { + iSKEYID_e.SetLength(total_key_len); + DEBUG_LOG(_L(" SKEYID_e")); + } + + DEBUG_LOG(_L(" Init IV")); + + CleanupStack::PopAndDestroy(2); //prf_data and agreedKey + + return ETrue; +} + +//Computes the IPSEC keys needed for each IPSEC SA +//KEYMAT = prf(SKEY_ID, protocol | SPI | Ni_b | Nr_b) +//if PFS: +//KEYMAT = prf(SKEY_ID, g(qm)^xy | protocol | SPI | Ni_b | Nr_b) +void CIkev1Negotiation::ComputeKeys2L(const CProposal_II *aProp, TInt aKeyLen, TSPINode &aInboundSpiNode, TDes8& aOutboundKey_II, TDes8& aInboundKey_II) +{ + DEBUG_LOG(_L("Computing PHASE II keys ")); + + aOutboundKey_II.SetLength(0); + aInboundKey_II.SetLength(0); + DEBUG_LOG(_L("Total Computed Key Length=")); + DEBUG_LOG_NUM(aKeyLen); + + HBufC8* agreedKey = NULL; //g(qm)^xy + TInt prf_len = iSKEYID_d.Length() + iNONCE_I.Length() + iNONCE_R.Length() + 8; // 8 for protocol and SPI + + if (iPFS) + { + agreedKey = ComputeAgreedKeyL(iChosenProp_IIList->At(0)->iAttrList->At(0)->iGroupDesc, iPeerPublicKey, iOwnKeys); + if ( !agreedKey ) + User::Leave(KErrGeneral); + CleanupStack::PushL(agreedKey); + prf_len += agreedKey->Length(); + DEBUG_LOG(_L(" Agreed Key")); + } +#ifdef _DEBUG + else DEBUG_LOG(_L("(NO PFS)")); +#endif // _DEBUG + + DEBUG_LOG(_L("Protocol:")); + DEBUG_LOG_NUM(aProp->iProtocol); + + TUint32 in_spi = aInboundSpiNode.iSPI; //inbound spi in Network Order + DEBUG_LOG(_L("InSPI:")); + DEBUG_LOG_NUM(ByteOrder::Swap32(in_spi)); + TUint32 out_spi; + Mem::Copy((TUint8 *)&out_spi, aProp->iSPI.Ptr(), aProp->iSPI.Length()); + DEBUG_LOG1(_L("OutSPI: %x"), out_spi); + //Inbound and outbound calculations only differ in the SPI + //If the key is not long enough we need to extend it + TPtr8 key_ptr((TUint8 *)aOutboundKey_II.Ptr() + aOutboundKey_II.Length(), 0, aOutboundKey_II.MaxLength()); + + HBufC8* prf_data = HBufC8::NewLC((prf_len | 0x3) + 1); + + while ((aOutboundKey_II.Length() * 8) < aKeyLen) //include the key extension algorithm + { + prf_data->Des().Copy(key_ptr); + if (agreedKey)//Only used if PFS + { + prf_data->Des().Append(agreedKey->Des()); + } + prf_data->Des().Append(&aProp->iProtocol, sizeof(aProp->iProtocol)); + prf_data->Des().Append(aProp->iSPI.Ptr(),aProp->iSPI.Length()); + prf_data->Des().Append(iNONCE_I); + prf_data->Des().Append(iNONCE_R); + key_ptr.Set((TUint8 *)aOutboundKey_II.Ptr() + aOutboundKey_II.Length(), 0, aOutboundKey_II.MaxLength() - aOutboundKey_II.Length()); + ComputePRFL(key_ptr, iSKEYID_d, prf_data->Des()); + aOutboundKey_II.SetLength(aOutboundKey_II.Length() + key_ptr.Length()); + } + + key_ptr.Set((TUint8 *)aInboundKey_II.Ptr() + aInboundKey_II.Length(), 0, aOutboundKey_II.MaxLength()); + while ((aInboundKey_II.Length() * 8) < aKeyLen) //include the key extension algorithm + { + prf_data->Des().Copy(key_ptr); + if (agreedKey)//Only used if PFS + { + prf_data->Des().Append(agreedKey->Des()); + } + prf_data->Des().Append(&aProp->iProtocol,sizeof(aProp->iProtocol)); + prf_data->Des().Append((TUint8 *)&in_spi, sizeof(TUint32)); + prf_data->Des().Append(iNONCE_I); + prf_data->Des().Append(iNONCE_R); + + key_ptr.Set((TUint8 *)aInboundKey_II.Ptr() + aInboundKey_II.Length(), 0, aInboundKey_II.MaxLength() - aInboundKey_II.Length()); + ComputePRFL(key_ptr, iSKEYID_d, prf_data->Des()); + aInboundKey_II.SetLength(aInboundKey_II.Length() + key_ptr.Length()); + } + + if ( agreedKey ) + CleanupStack::PopAndDestroy(2); //prf_data and agreedKey + else CleanupStack::PopAndDestroy(); //prf_data + +} + + +/* This function is called by oakley module to do pseudo random computation for + given data */ +//IMPORTANT: If some func added or modified check MAX_PRF_LENGTH is correct in ike.h + +void CIkev1Negotiation::ComputePRFL(TDes8 &prf_output, const TDesC8 &prf_key, const TDesC8 &prf_data) +{ +// All actions taken are moved into the crypto module IKE_CRYPTO.CPP + + if ( iChosenProposal_I.iAttrList->iPRF == OAKLEY_PRF_3DES_CBC_MAC) + { + DEBUG_LOG(_L("PRF (3DES_CBC_MAC)")); + Hmac3DesCbcL(prf_data, prf_output, prf_key); + } + else + { + // Use HMAC version of the negotiated hash function as default PRF + if ( iChosenProposal_I.iAttrList->iHashAlg == HASH_MD5 ) { + DEBUG_LOG(_L("PRF (MD5)")); + MD5HmacL(prf_data, prf_output, prf_key); + } + else { + if ( iChosenProposal_I.iAttrList->iHashAlg == HASH_SHA1 ) { + DEBUG_LOG(_L("PRF (SHA1)")); + SHA1HmacL(prf_data, prf_output, prf_key); + } + } + } + +} + + +//NOTE: Must be called after ProcessCertificate() !!! +TBool CIkev1Negotiation::CertifyRemoteIdentityL(const TIdentISAKMP *aIdPayload) +{ + TBool Status = EFalse; + TInt id_len = aIdPayload->IDDataLen(); + + if ( id_len && iPkiService && iPeerX509Cert ) + { + TPtrC8 IdData((TUint8 *)aIdPayload->IDData(), id_len); + + // Leave is trapped and handled here because the event log is easily accessible + // and in the upper layers it would not be possible to identify the + // cause of the error based on the generic leave code. + TRAPD(err, Status = IkePkiUtils::CertifyIdentityL(iPeerX509Cert, IdData, (TInt)aIdPayload->GetIDType())); + + if( KErrNotSupported == err ) + { + LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError, + R_VPN_MSG_CERT_ERROR, + KErrNotSupported, + iPluginSession->VpnIapId(), + &iRemoteAddr ); + } + +#ifdef _DEBUG + if (Status) + DEBUG_LOG(_L("Remote identity has been certified")); +#endif // _DEBUG + } + + return Status; +} + + +//Digests aHash with the key in aCert and compares it to the stored value aSig +//Needs to be check after the Signature payload has been processed +TBool CIkev1Negotiation::VerifySignatureL(CX509Certificate *aCert,TUint8 *aHash, TInt aHashLength,TUint8 *aSig, TUint aSigLength) +{ + + TBool ret = EFalse; + if ( iPkiService ) + { + TPtrC8 Signature(aSig, aSigLength); + TPtrC8 RefHash(aHash, aHashLength); + ret = IkePkiUtils::VerifyIkev1SignatureL(Signature, RefHash, *aCert); + } + + return ret; + + +} + +//NOTE!!! The func sets iFinished to TRUE always so after detecting an error the communication finishes. +//If it doesn't have to iFinished should be set outside the function. +void CIkev1Negotiation::SendNotifyL(TUint16 aError) +{ + SetFinished(); //Ends the negotiation (error condition detected) If CONNECTED also should end + +#ifdef _DEBUG + TBuf<60> buf; + DEBUG_LOG(_L("SendNotifyL(), Reason: ")); + buf.Append(TextNotifyType(aError)); + DEBUG_LOG(buf); +#endif // _DEBUG + TUint8 protocol = PROTO_ISAKMP; + TUint8 tmp_exchange = iExchange; + TUint32 tmp_msg_id = iMessageId; + TIkev1IsakmpStream* msg = SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) ); + //If configured to send notification payloads for errors + if (iHostData->iNotify) + { + iExchange = ISAKMP_EXCHANGE_INFO; + iMessageId = RandomMessageId(); + msg->IsakmpInit(this); + + //HASH Payload only if payload protected with encyption + if (iFlags & ISAKMP_HDR_EFLAG) + msg->IsakmpHashL(); + + if (iPhase == PHASE_I) + protocol = iChosenProposal_I.iProtocol; + else + { + if (iChosenProp_IIList) //May be the begining of PHASE_II when still not decided + protocol = iChosenProp_IIList->At(0)->iProtocol; + } + msg->IsakmpNotification(aError, protocol); + + if (iFlags & ISAKMP_HDR_EFLAG) + { + msg->IsakmpHashContL(); + } + + iExchange = tmp_exchange; + iMessageId = tmp_msg_id; + + SendL(*msg); + + LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError, + R_VPN_MSG_SENT_ERROR_RESPONSE, + aError, + iPluginSession->VpnIapId(), + &iRemoteAddr ); + } + +} + + +//Hash function key length (in bytes) +TInt CIkev1Negotiation::HashLength() +{ + if (iChosenProposal_I.iAttrList->iPRF == OAKLEY_PRF_3DES_CBC_MAC) + return 24; + + //If no PRF hash alg used instead. + if (iChosenProposal_I.iAttrList->iPRF==0) + { + if (iChosenProposal_I.iAttrList->iHashAlg==HASH_MD5) + return HMAC_MD5_SIZE/8; //16 bytes + //return MD5_DIGEST_LENGTH; + else if (iChosenProposal_I.iAttrList->iHashAlg==HASH_SHA1) + return HMAC_SHA1_SIZE/8; + //return SHA_DIGEST_LENGTH; + } + + return 0; +} + + +//Could be done using directly iEncrAlg from the chosen transform (in bytes) +TUint32 CIkev1Negotiation::ISAKMPEncrKeyLength(TUint8 aAlgId) const +{ + TUint32 KeyLth = 0; + switch (aAlgId) { + case DES_CBC: + KeyLth = 8; + break; + case DES3_CBC: + KeyLth = 24; + break; + case AES_CBC: + if ( iChosenProposal_I.iAttrList->iKeyLength ) + KeyLth = (TUint32)(iChosenProposal_I.iAttrList->iKeyLength/8); + else KeyLth = 16; // default + break; + default: + break; + } + + return KeyLth; +} + +TIkev1IsakmpStream* CIkev1Negotiation::SaveIkeMsgBfr(TIkev1IsakmpStream* aMsg) +{ + delete iSavedIkeMsgBfr; + iSavedIkeMsgBfr = aMsg; + return aMsg; +} + +//Returns the key length (in bits) of an algorithm for iAuth (TAttrib_II) field when protocol is AH +TUint32 CIkev1Negotiation::HMAC_KeyLength(TUint8 aId) const +{ + if (aId == SADB_AALG_MD5HMAC) + return (HMAC_MD5_SIZE); + else if (aId == SADB_AALG_SHA1HMAC) + return (HMAC_SHA1_SIZE); + + return (0); // Error +} + +//Exchange Type +TPtrC CIkev1Negotiation::TextNotifyType(TUint16 aNotif) +{ +#ifndef _DEBUG + (void)aNotif; +#endif + +#ifdef _DEBUG + //TBuf<35> err; + switch(aNotif) + { + case INVALID_PAYLOAD_TYPE: + return _L("INVALID_PAYLOAD_TYPE"); + case DOI_NOT_SUPPORTED: + return _L("DOI_NOT_SUPPORTED"); + case SITUATION_NOT_SUPPORTED: + return _L("SITUATION_NOT_SUPPORTED"); + case INVALID_COOKIE: + return _L("INVALID_COOKIE"); + case INVALID_MAJOR_VERSION: + return _L("INVALID_MAJOR_VERSION"); + case INVALID_MINOR_VERSION: + return _L("INVALID_MINOR_VERSION"); + case INVALID_EXCHANGE_TYPE: + return _L("INVALID_EXCHANGE_TYPE"); + case INVALID_FLAGS: + return _L("INVALID_FLAGS"); + case INVALID_MESSAGE_ID: + return _L("INVALID_MESSAGE_ID"); + case INVALID_PROTOCOL_ID: + return _L("INVALID_PROTOCOL_ID"); + case INVALID_SPI: + return _L("INVALID_SPI"); + case INVALID_TRANSFORM_ID: + return _L("INVALID_TRANSFORM_ID"); + case ATTRIBUTES_NOT_SUPPORTED: + return _L("ATTRIBUTES_NOT_SUPPORTED"); + case NO_PROPOSAL_CHOSEN: + return _L("NO_PROPOSAL_CHOSEN"); + case BAD_PROPOSAL_SYNTAX: + return _L("BAD_PROPOSAL_SYNTAX"); + case PAYLOAD_MALFORMED: + return _L("PAYLOAD_MALFORMED"); + case INVALID_KEY_INFORMATION: + return _L("INVALID_KEY_INFORMATION"); + case INVALID_ID_INFORMATION: + return _L("INVALID_ID_INFORMATION"); + case INVALID_CERT_ENCODING: + return _L("INVALID_CERT_ENCODING"); + case INVALID_CERTIFICATE: + return _L("INVALID_CERTIFICATE"); + case CERT_TYPE_UNSUPPORTED: + return _L("CERT_TYPE_UNSUPPORTED"); + case INVALID_CERT_AUTHORITY: + return _L("INVALID_CERT_AUTHORITY"); + case INVALID_HASH_INFORMATION: + return _L("INVALID_HASH_INFORMATION"); + case AUTHENTICATION_FAILED: + return _L("AUTHENTICATION_FAILED"); + case INVALID_SIGNATURE: + return _L("INVALID_SIGNATURE"); + case ADDRESS_NOTIFICATION: + return _L("ADDRESS_NOTIFICATION"); + case NOTIFY_SA_LIFETIME: + return _L("NOTIFY_SA_LIFETIME"); + case CERTIFICATE_UNAVAILABLE: + return _L("CERTIFICATE_UNAVAILABLE"); + case UNSUPPORTED_EXCHANGE_TYPE: + return _L("UNSUPPORTED_EXCHANGE_TYPE"); + case UNEQUAL_PAYLOAD_LENGTHS: + return _L("UNEQUAL_PAYLOAD_LENGTHS"); + case CONNECTED: + return _L("CONNECTED"); + case DOI_RESPONDER_LIFETIME: + return _L("RESPONDER_LIFETIME"); + case DOI_REPLAY_STATUS: + return _L("REPLAY_STATUS"); + case DOI_INITIAL_CONTACT: + return _L("INITIAL_CONTACT"); + } + return _L("Unknown "); +#else + return NULL; +#endif +} + + +void CIkev1Negotiation::TextPayload(TDes &aBuf, TUint8 aPayload) +{ +#ifndef _DEBUG + (void)aBuf; + (void)aPayload; +#endif + +#ifdef _DEBUG + switch(aPayload) + { + case ISAKMP_PAYLOAD_NONE:// (Terminator) + aBuf = _L("ISAKMP_PAYLOAD_NONE"); + break; + case ISAKMP_PAYLOAD_SA:// Security Association + aBuf = _L("ISAKMP_PAYLOAD_SA"); + break; + case ISAKMP_PAYLOAD_P:// Proposal + aBuf = _L("ISAKMP_PAYLOAD_P"); + break; + case ISAKMP_PAYLOAD_T:// Transform + aBuf = _L("ISAKMP_PAYLOAD_T"); + break; + case ISAKMP_PAYLOAD_KE:// Key Exchange + aBuf = _L("ISAKMP_PAYLOAD_KE"); + break; + case ISAKMP_PAYLOAD_ID:// Identification + aBuf = _L("ISAKMP_PAYLOAD_ID"); + break; + case ISAKMP_PAYLOAD_CERT:// Certificate + aBuf = _L("ISAKMP_PAYLOAD_CERT"); + break; + case ISAKMP_PAYLOAD_CR:// Certificate Request + aBuf = _L("ISAKMP_PAYLOAD_CR"); + break; + case ISAKMP_PAYLOAD_HASH:// Hash + aBuf = _L("ISAKMP_PAYLOAD_HASH"); + break; + case ISAKMP_PAYLOAD_SIG:// Signature + aBuf = _L("ISAKMP_PAYLOAD_SIG"); + break; + case ISAKMP_PAYLOAD_NONCE:// Nonce + aBuf = _L("ISAKMP_PAYLOAD_NONCE"); + break; + case ISAKMP_PAYLOAD_NOTIF:// Notification + aBuf = _L("ISAKMP_PAYLOAD_NOTIF"); + break; + case ISAKMP_PAYLOAD_D:// Delete + aBuf = _L("ISAKMP_PAYLOAD_D"); + break; + case ISAKMP_PAYLOAD_VID:// Vendor ID + aBuf = _L("ISAKMP_PAYLOAD_VID"); + break; + case ISAKMP_PAYLOAD_PRIVATE:// Private use (up to 255) + aBuf = _L("ISAKMP_PAYLOAD_PRIVATE"); + break; + default: + aBuf.Format(_L("Unknown (%d) "),aPayload); + } +#endif +} + +//Sends the built message through the socket +void CIkev1Negotiation::SendL(TIkev1IsakmpStream &aMsg) +{ + if (aMsg.iError) + { + DEBUG_LOG(_L("Error Building message")); + return; + } + TBuf8 tmp_IV; + + ThdrISAKMP *hdr = (ThdrISAKMP *)aMsg.iBuf.Ptr(); + hdr->SetLength(aMsg.iBuf.Length()); + DEBUG_LOG(_L("Sending (clear)...")); + + TBool FloatedPort = EFalse; + if ( iNAT_D_Flags & (REMOTE_END_NAT + LOCAL_END_NAT) ) + FloatedPort = ETrue; + +#ifdef _DEBUG + const TPtrC8 ikeMsgPtr( aMsg.iBuf.Ptr(), aMsg.iBuf.Length() ); + TInetAddr localAddr; + iPluginSession->GetLocalAddress( localAddr ); + TInt port = ( FloatedPort ? IkeSocket::KIkePort4500 : IkeSocket::KIkePort500 ); + localAddr.SetPort( port ); + TRACE_MSG_IKEV1( ikeMsgPtr, localAddr, iLastRemoteAddr ); +#endif // _DEBUG + + TPtr8 lastMsg(iLastMsg->Des()); + + if (hdr->GetFlags() & ISAKMP_HDR_EFLAG) + { + DEBUG_LOG(_L("Encrypting...")); + + if (hdr->GetExchange()==ISAKMP_EXCHANGE_INFO || hdr->GetExchange()==ISAKMP_EXCHANGE_TRANSACT ) + { + if ( hdr->GetExchange()==ISAKMP_EXCHANGE_TRANSACT ) + { + // + // Get current IV via CTransNegotiation object linked into + // CIkev1Negotiation + // + if ( !iTransactionNeg || + !iTransactionNeg->GetIV(hdr->GetMessageId(), tmp_IV) ) + { + DEBUG_LOG(_L("Send error ! Cannot get Transaction IV !")); + return; + } + DEBUG_LOG(_L("Transaction IV")); + EncryptL(aMsg.iBuf, lastMsg, tmp_IV, iSKEYID_e, iChosenProposal_I.iAttrList->iEncrAlg); + iTransactionNeg->SetIV(hdr->GetMessageId(), tmp_IV); + } + else + { + if (iLastIV.Length() != 0) + tmp_IV.Copy(iLastIV); + else //iLastIV not yet computed so current iIV is used + tmp_IV.Copy(iIV); + ComputeIVL(tmp_IV, hdr->GetMessageId()); + DEBUG_LOG(_L("Notif IV")); + EncryptL(aMsg.iBuf, lastMsg, tmp_IV, iSKEYID_e, iChosenProposal_I.iAttrList->iEncrAlg); + } + + } + else //Normal exchange MAIN, AGGR or QUICK + { + DEBUG_LOG(_L("IV")); + EncryptL(aMsg.iBuf, lastMsg, iIV, iSKEYID_e, iChosenProposal_I.iAttrList->iEncrAlg); + DEBUG_LOG(_L("New IV (dec)")); + //Saves last iIV in Phase 1 + if (((iStage==6) && (iExchange == ISAKMP_EXCHANGE_ID)) || + ((iStage==3) && (iExchange == ISAKMP_EXCHANGE_AGGR))) + { + iLastIV.Copy(iIV); + DEBUG_LOG(_L("Last IV Saved!")); + } + } + + DEBUG_LOG(_L("Sending ...")); + DEBUG_LOG1(_L("EncrLen = %d"), lastMsg.Length()); + } + else + { + lastMsg.Copy(aMsg.iBuf); + } + + hdr = (ThdrISAKMP *)lastMsg.Ptr(); + hdr->SetLength(lastMsg.Length()); //Set the total length!!! + + if (hdr->GetExchange() == ISAKMP_EXCHANGE_INFO) + { + SendAndSaveIkeMsgL(lastMsg, iLastRemoteAddr, FloatedPort); //No timers! + } + else //Normal msg. + { + iTimer->Cancel(); //Cancel previous timer because reply received & processed + DEBUG_LOG(_L("Timer Cancelled!")); + iRetryNum = 0; + SendAndSaveIkeMsgL(lastMsg, iLastRemoteAddr, FloatedPort); + iTimer->IssueRequest(MAX_RETRANS_TIMER * 1000000); // 1000000 = 1 second + } + +} + + +void CIkev1Negotiation::ReSendL() +{ + //Will resend a packet in the interval (MAX_RETRANS_TIMER/2 , MAX_RETRANS_TIMER) + if ( iRetryNum < MAX_RETRANS_COUNT ) + { + DEBUG_LOG2(_L("---------- Phase %d - Stage %d ----------"),iPhase, iStage - 1); + DEBUG_LOG1(_L("ReSending(%d)..."), iRetryNum); + TBool FloatedPort = EFalse; + if ( iNAT_D_Flags & (REMOTE_END_NAT + LOCAL_END_NAT) ) + FloatedPort = ETrue; + TPtr8 lastMsg(iLastMsg->Des()); + iPluginSession->SendIkeMsgL(lastMsg, iLastRemoteAddr, FloatedPort); + //next retransmission between MAX_RETRANS_TIMER/2 and MAX_RETRANS_TIMER seconds + TTime tmp_time; + TReal secs = 0; + tmp_time.UniversalTime(); + TInt64 seed = tmp_time.Int64(); + TInt rand = Math::Rand(seed); + TInt err = Math::Round(secs, rand / (KMaxTInt / MAX_RETRANS_TIMER/2), 0); + secs = Math::Round(secs, secs + MAX_RETRANS_TIMER/2, 0); + if ((!secs) || (err != KErrNone)) + secs = MAX_RETRANS_TIMER/2; + iTimer->IssueRequest((TInt)secs * 1000000); // 1000000 = 1 second + iRetryNum++; + } + else + { + SendDeleteL(PROTO_ISAKMP); + if ( iPhase == PHASE_I ) + { + DEBUG_LOG(_L("Max num retries reached!!!")); + } + else + { + DEBUG_LOG(_L("Quick mode failed, Max num retries reached!!!")); + } + + if ( iPhase == PHASE_I && + iPluginSession->FindIkev1SA() == NULL ) + { + // Set error status in Phase 1, if there are no IKE SAs. + if ( GetNotifyStatus() ) + SetErrorStatus(KKmdIkeNoProposalErr); + else SetErrorStatus(KKmdIkeNoResponseErr); + } + + LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError, + R_VPN_MSG_VPN_GW_NO_RESP, + ErrorStatus(), + iPluginSession->VpnIapId(), + &iRemoteAddr ); + iPluginSession->DeleteNegotiation( this ); + } +} + +void CIkev1Negotiation::SendDeleteL(TUint8 aProtocol, TUint32 aIpsecSPI) +{ + TIkev1IsakmpStream* msg = SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) ); + + TBuf8 SPI; + + DEBUG_LOG(_L("Sending Delete payload...")); + + //Creates a DUMMY negotiation with the info to send the packet + TUint8 tmp_exchange = iExchange; + iExchange=ISAKMP_EXCHANGE_INFO; //Set the exchange type as info + + msg->IsakmpInit(this); + + //HASH Payload only if payload protected with encyption + if (iFlags & ISAKMP_HDR_EFLAG) + msg->IsakmpHashL(); + + if (aProtocol == PROTO_ISAKMP) //ISAKMP SPI are the cookies + { + SPI.Copy(iCookie_I); + SPI.Append(iCookie_R); + } + else //IPSECSPI + { + SPI.Copy((TUint8 *)&aIpsecSPI, sizeof(TUint32)); + } + msg->IsakmpDelete(SPI, aProtocol); + + if (iFlags & ISAKMP_HDR_EFLAG) + { + msg->IsakmpHashContL(); + } + DEBUG_LOG(_L("Sending Delete Payload...")); + SendL(*msg); + + iExchange = tmp_exchange; +} + +void CIkev1Negotiation::CheckSendResponderLifetime(TIkev1IsakmpStream &aMsg) +{ + TInt count = iChosenProp_IIList->Count(); + CProposal_II *prop; + TChosenAttrib_II *attr_II; + TSPINode inboundspi_node; + TInt j; + for (j = 0 ; j < count; j++) //Check all the chosen proposals (Probably one) + { + prop = iChosenProp_IIList->At(j); + inboundspi_node = iInboundSPIList->At(j); + attr_II = (TChosenAttrib_II *)prop->iAttrList->At(0); //only 1 transform is chosen no matter how many there are + + if ((attr_II->iReducedLifeSecs.Length() != 0) || (attr_II->iReducedLifeKBytes.Length() != 0)) //Any lifetime to update + aMsg.IsakmpResponderLifetime(prop->iProtocol, inboundspi_node.iSPI, attr_II->iReducedLifeSecs, attr_II->iReducedLifeKBytes); + + } +} + + +/**-------------------------------------------------------------------- + * + * The following methods are used to implement the Dead Peer Detection + * protocol defined in + * When timeout expires the R-U-THERE notify message is transmitted + * if there has not been any activity during the last timeout + * + *--------------------------------------------------------------------*/ +void CIkev1Negotiation::DpdNotifyMessageReceivedL(TIkev1SAData* aSa, TUint16 aMsgType, TUint32 aSequence) +{ + + if ( aMsgType == DPD_R_U_THERE ) + { + // + // -- Assure that sequence number in notify data is what expected + // -- If ok, transmit a R-U-THERE-ACK + // + DEBUG_LOG(_L("DPD R-U-THERE Notify received")); + if ( (aSa->iExpectedDPDSequence == aSequence) || (aSa->iExpectedDPDSequence == 0) ) + { + aSa->iExpectedDPDSequence = GetNextSequence(aSequence); + DEBUG_LOG(_L("Sending DPD R-U-THERE_ACK notify")); + SendDpdNotifyMessageL(DPD_R_U_THERE_ACK, aSequence); + iPluginSession->UpdateIkev1SAL(aSa->iSAId, EFalse, aSa); + } +#ifdef _DEBUG + else DEBUG_LOG(_L("Wrong sequence number in DPD notify message")); +#endif // _DEBUG + } + else if ( aMsgType == DPD_R_U_THERE_ACK ) + { + // + // -- Assure that sequence number in notify data is corresponds + // current pending sequence + // + DEBUG_LOG(_L("DPD R-U-THERE-ACK Notify received")); + if ( aSa->iPendingDPDSequence == aSequence ) + { + aSa->iPendingDPDSequence = 0; + aSa->iDPDRetry = 0; + iPluginSession->UpdateIkev1SAL(aSa->iSAId, EFalse, aSa); + } +#ifdef _DEBUG + else DEBUG_LOG(_L("Wrong sequence number in DPD notify ack message")); +#endif // _DEBUG + } +} + +void CIkev1Negotiation::SendKeepAliveMsgL(TIkev1SAData* aSa) +{ + if ( aSa->iDPDRetry > KMaxDpdRetryCount ) + { + // + // DPD Retry count exhausted, current IKE SA in interpreted to + // be closed + // + LOG_KMD_EVENT( MKmdEventLoggerIf::KLogError, + R_VPN_MSG_VPN_GW_NO_RESP, + KKmdIkeNoResponseErr, + iPluginSession->VpnIapId(), + &iRemoteAddr ); + + iPluginSession->DeleteIpsecSAs(aSa->iSAId); + iPluginSession->UpdateIkev1SAL(aSa->iSAId, ETrue); + } + else + { + // + // Send DPD R-U-THERE notify message + // + if ( aSa->iPendingDPDSequence == 0 ) + { + aSa->iPendingDPDSequence = aSa->iDPDSequence; + aSa->iDPDSequence = GetNextSequence(aSa->iDPDSequence); + } + else + { + aSa->iDPDRetry ++; + } + DEBUG_LOG(_L("Sending DPD R-U-THERE notify")); + SendDpdNotifyMessageL(DPD_R_U_THERE, aSa->iPendingDPDSequence); + } + SetFinished(); +} + +MKmdEventLoggerIf& CIkev1Negotiation::EventLogger() +{ + return iPluginSession->EventLogger(); +} + +void CIkev1Negotiation::IpsecSaSpiRetrieved(TUint32 aSpiRequestId, + TInt aStatus, + TUint32 aSpi) +{ + DEBUG_LOG3(_L("IPsec SA SPI retrieved, seq=%d, SPI=%d, status=%d"), + aSpiRequestId, aSpi, aStatus); + if ( aStatus == KErrNone ) + { + TRAP( aStatus, ReceiveSPIL( aSpi, aSpiRequestId ) ); + } + else + { + iPluginSession->HandleError( aStatus ); + } +} + +TBool CIkev1Negotiation::IsRekeyingIkeSa() +{ + return ( iSARekeyInfo != NULL ); +} + +void CIkev1Negotiation::PreparePhase2L(const TPfkeyMessage &aReq) +{ + DEBUG_LOG(_L("Prepare for Phase II")); + GetAcquireDataL(aReq); + iPhaseIIAfterIkeSaRekey = ETrue; +} + +TUint32 CIkev1Negotiation::GetNextSequence(TUint32 aSequence) +{ + aSequence ++; + if ( aSequence == 0 ) + aSequence = 1; + return aSequence; +} + +void CIkev1Negotiation::SendDpdNotifyMessageL(TUint16 aMsgType, TUint32 aSequence) +{ + iExchange = ISAKMP_EXCHANGE_INFO; + iMessageId = RandomMessageId(); + TIkev1IsakmpStream* Msg = SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) ); + Msg->IsakmpInit(this); + Msg->IsakmpHashL(); + TUint32 NotifData = ByteOrder::Swap32(aSequence); + Msg->IsakmpNotification(aMsgType, PROTO_ISAKMP, (TUint8*)&NotifData, sizeof(NotifData)); + Msg->IsakmpHashContL(); + SendL(*Msg); +} + +TInt CIkev1Negotiation::ErrorStatus() +{ + TInt ret( KErrNone ); + if ( iPluginSession ) + { + ret = iPluginSession->ErrorStatus(); + } + return ret; +} + +void CIkev1Negotiation::SetErrorStatus(TInt aStatus) +{ + SetFinished(); + iPluginSession->SetErrorStatus(aStatus); +} + +void CIkev1Negotiation::SendAndSaveIkeMsgL( const TDesC8& aIkeMsg, + TInetAddr& aDestAddr, + TBool aUseNatPort ) +{ + iPluginSession->SendIkeMsgL( aIkeMsg, aDestAddr, aUseNatPort ); + SaveLastMsgL(); +} + + +TBool CIkev1Negotiation::IsRetransmit(TLastIKEMsg& aRef) +{ + TBool isRetransmit(EFalse); + if (iLastIKEMsgInfo.IsUninitialized()) + { + TIkev1SAData* ikev1SAData = iPluginSession->FindIkev1SAData(iSAId); + if (ikev1SAData && ikev1SAData->iLastIKEMsgInfo.IsReTransmit(aRef)) + { + isRetransmit = ETrue; + } + } + else + { + isRetransmit = iLastIKEMsgInfo.IsReTransmit(aRef); + } + return isRetransmit; +} + +void CIkev1Negotiation::SaveRetransmitInfo(TLastIKEMsg& aRef) +{ + aRef.Store(iLastIKEMsgInfo); + TIkev1SAData* ikev1SAData = iPluginSession->FindIkev1SAData(iSAId); + if (ikev1SAData != NULL) + { + aRef.Store(ikev1SAData->iLastIKEMsgInfo); + } +} + +void CIkev1Negotiation::SaveLastMsgL() +{ + if ( iLastMsg != NULL ) + { + TIkev1SAData* ikev1SAData = iPluginSession->FindIkev1SAData(iSAId); + if ( ikev1SAData != NULL ) + { + delete ikev1SAData->iLastMsg; + ikev1SAData->iLastMsg = iLastMsg->AllocL(); + } + } +} + + + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1nokianattkeepalive.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1nokianattkeepalive.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,96 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Keepalive object for Nokia IPsec over NAT +* +*/ + + + +#include "ikedebug.h" +#include "ikev1pluginsession.h" +#include // TCommDbConnPref +#include "ikev1nokianattkeepalive.h" // CIkev1NokiaNattKeepAlive + +_LIT8(KMsgContent, "\xff"); + +CIkev1NokiaNattKeepAlive* CIkev1NokiaNattKeepAlive::NewL( CIkev1PluginSession& aPluginSession, + TInetAddr& aDestAddr, + TUint16 aPort, + TUint aInterval, + MIkeDebug& aDebug ) + { + CIkev1NokiaNattKeepAlive *self = new (ELeave) CIkev1NokiaNattKeepAlive( aPluginSession, + aDestAddr, + aPort, + aDebug ); + CleanupStack::PushL(self); + self->ConstructL(aInterval); + CleanupStack::Pop(self); + return self; + } + +CIkev1NokiaNattKeepAlive::~CIkev1NokiaNattKeepAlive() + { + if (iTimer) + { + iTimer->Cancel(); + delete iTimer; + iTimer = NULL; + } + + } + +CIkev1NokiaNattKeepAlive::CIkev1NokiaNattKeepAlive( CIkev1PluginSession& aPluginSession, + TInetAddr& aDestAddr, + TUint16 aPort, + MIkeDebug& aDebug ) +: iPluginSession(aPluginSession), + iDestAddr(aDestAddr), + iPort(aPort), + iMsg(KMsgContent), + iDebug(aDebug) + { + iDestAddr.SetPort(iPort); + } + + +void CIkev1NokiaNattKeepAlive::ConstructL(TUint aInterval) + { + /* + * Set up periodic timer + */ + + // Interval and initial delay + TTimeIntervalMicroSeconds32 interval(aInterval * 1000000); + + iTimer = CPeriodic::NewL(CActive::EPriorityStandard); + iTimer->Start(interval, interval, + TCallBack(CIkev1NokiaNattKeepAlive::PeriodicCallback, this)); + DEBUG_LOG(_L("CIkev1NokiaNattKeepAlive::ConstructL(aInterval) Constructed")); + } + +void CIkev1NokiaNattKeepAlive::Send() + { + TRAPD( err, iPluginSession.SendNokiaNatKeepAliveL( iDestAddr, iMsg, 0 ) ); + err = err; + DEBUG_LOG1(_L("CIkev1NokiaNattKeepAlive::Send() Request sending of keepalive packet, err=%d"), err); + } + +TInt CIkev1NokiaNattKeepAlive::PeriodicCallback(TAny *aPtr) + { + CIkev1NokiaNattKeepAlive *self = static_cast(aPtr); + self->Send(); + return KErrNone; + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1payload.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1payload.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,213 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: CIkev1payload class +* +*/ + +#include "ikev1payload.h" +#include "ikev1negotiation.h" +#include "ikedebug.h" + +// +// CIkePayloads +// + +CIkev1Payloads::CIkev1Payloads( CIkev1Negotiation& aNegotiation, + MIkeDebug& aDebug ) + : iNegotiation( aNegotiation ), + iDebug( aDebug ) +{ +} + + +CIkev1Payloads::~CIkev1Payloads() +{ + delete iIds; + delete iCerts; + delete iCertReqs; + delete iNotifs; + delete iDeletes; + delete iVids; + delete iNatDs; + delete iGenPlds; +} + + +CIkev1Payloads* CIkev1Payloads::NewL( const ThdrISAKMP& aHdr, + CIkev1Negotiation& aNegotiation, + MIkeDebug& aDebug ) +{ + CIkev1Payloads* Payloads = new (ELeave) CIkev1Payloads( aNegotiation, + aDebug ); + CleanupStack::PushL(Payloads); + + Payloads->iIds = new (ELeave) CArrayFixFlat(4); + Payloads->iCerts = new (ELeave) CArrayFixFlat(4); + Payloads->iCertReqs = new (ELeave) CArrayFixFlat(4); + Payloads->iNotifs = new (ELeave) CArrayFixFlat(4); + Payloads->iDeletes = new (ELeave) CArrayFixFlat(4); + Payloads->iVids = new (ELeave) CArrayFixFlat(4); + Payloads->iNatDs = new (ELeave) CArrayFixFlat(4); + Payloads->iGenPlds = new (ELeave) CArrayFixFlat(4); + + if ( !Payloads->ParsePayloadsL(aHdr) ) + { + CleanupStack::PopAndDestroy(); + Payloads = NULL; + } + else CleanupStack::Pop(); + + return Payloads; +} + +TBool CIkev1Payloads::ParsePayloadsL(const ThdrISAKMP &aHdr) +{ + + TBool Status = ETrue; + TUint16 ptype = aHdr.GetPayload(); + const TPayloadISAKMP* payload = (const TPayloadISAKMP*)aHdr.Next(); + iPadding = aHdr.GetLength() - sizeof(aHdr); + + while ( ptype != ISAKMP_PAYLOAD_NONE ) + { + + if (!iNegotiation.CheckGenericPayloadL(payload)) //Checks the generic payload is OK + { + Status = EFalse; + break; + } + + switch (ptype) + { + + case ISAKMP_PAYLOAD_SA: //also includes proposal and transform + DEBUG_LOG(_L("[SA]")); + if ( !iSa ) // Only one SA payload (The first) + iSa = TSAISAKMP::Ptr(payload); + break; + + case ISAKMP_PAYLOAD_KE: + DEBUG_LOG(_L("[KE]")); + if ( !iKe ) // Only one KE payload (The first) + iKe = TKeyISAKMP::Ptr(payload); + break; + + case ISAKMP_PAYLOAD_ID: + DEBUG_LOG(_L("[ID]")); + iIds->AppendL(TIdentISAKMP::Ptr(payload)); + break; + + case ISAKMP_PAYLOAD_CERT: + DEBUG_LOG(_L("[CERT]")); + iCerts->AppendL(TCertificateISAKMP::Ptr(payload)); + break; + + case ISAKMP_PAYLOAD_CR: + DEBUG_LOG(_L("[CR]")); + iCertReqs->AppendL(TCertificateReqISAKMP::Ptr(payload)); + break; + + case ISAKMP_PAYLOAD_HASH: + DEBUG_LOG(_L("[HASH]")); + if ( !iHash ) // Only one HASH payload (The first) + iHash = THashISAKMP::Ptr(payload); + break; + + case ISAKMP_PAYLOAD_SIG: + DEBUG_LOG(_L("[SIG]")); + if ( !iSign ) // Only one HASH payload (The first) + iSign = TSignatureISAKMP::Ptr(payload); + break; + + case ISAKMP_PAYLOAD_NONCE: + DEBUG_LOG(_L("[NONCE]")); + if ( !iNonce ) // Only one NONCE payload (The first) + iNonce = TNonceISAKMP::Ptr(payload); + break; + + case ISAKMP_PAYLOAD_NOTIF: + DEBUG_LOG(_L("[NOTIF]")); + iNotifs->AppendL(TNotificationISAKMP::Ptr(payload)); + break; + + case ISAKMP_PAYLOAD_D: + DEBUG_LOG(_L("[DELETE]")); + iDeletes->AppendL(TDeleteISAKMP::Ptr(payload)); + break; + + case ISAKMP_PAYLOAD_VID: + DEBUG_LOG(_L("[VID]")); + iVids->AppendL(TVendorISAKMP::Ptr(payload)); + break; + + // + // Extensions payloads + // + case ISAKMP_PAYLOAD_ATTRIBUTES: + DEBUG_LOG(_L("[ATTR]")); + if ( !iAttr ) // Only one ATTR payload (The first) + iAttr = TAttributeISAKMP::Ptr(payload); + break; + + case ISAKMP_PAYLOAD_CHRE: + DEBUG_LOG(_L("[CHRE]")); + if ( !iChre ) // Only one CHRE payload (The first) + iChre = TCHREISAKMP::Ptr(payload); + break; + + case ISAKMP_INT_NETWORK: + DEBUG_LOG(_L("[IA]")); + if ( !iIaddr ) // Only one IA payload (The first) + iIaddr = TINTNETISAKMP::Ptr(payload); + break; + + case IETF_NAT_DISCOVERY: + DEBUG_LOG(_L("[NAT-D]")); + iNatDs->AppendL(TNATDISAKMP::Ptr(payload)); + break; + + case IETF_RFC_NAT_DISCOVERY: + DEBUG_LOG(_L("[NAT-D]")); + iNatDs->AppendL(TNATDISAKMP::Ptr(payload)); + break; + + case IETF_NAT_ORIG_ADDR: + DEBUG_LOG(_L("[NAT-OA]")); + if ( !iNatOa ) // Only one NONCE payload (The first) + iNatOa = TNATOaISAKMP::Ptr(payload); + break; + + case IETF_RFC_NAT_ORIG_ADDR: + DEBUG_LOG(_L("[NAT-OA]")); + if ( !iNatOa ) // Only one NONCE payload (The first) + iNatOa = TNATOaISAKMP::Ptr(payload); + break; + // + // Unknown payloads are queued into iGenPlds array + // + default: + DEBUG_LOG1(_L("[PL TYPE (%d)]"),ptype); + iGenPlds->AppendL(payload); + break; + + } + + iPadding -= payload->GetLength(); + ptype = payload->GetPayload(); + payload = payload->Next(); + } + + return Status; +} + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1plugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1plugin.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,240 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv1 protocol plugin +* +*/ + +#include "ikedebug.h" +#include "ikeplugindefs.h" +#include "ikev1pluginsession.h" +#include "ikev1SAdata.h" +#include "ipsecpolicyutil.h" +#include "pfkeysocketif.h" + +// CLASS HEADER +#include "ikev1plugin.h" + +// ======== GLOBAL FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Creates IKEv1 plugin instance. +// --------------------------------------------------------------------------- +// +EXPORT_C MIkePluginIf* Ikev1PlugInL( MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ) + { + CIkev1Plugin* plugin = CIkev1Plugin::NewL( aEventLogger, aDebug ); + return plugin; + } + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CIkev1Plugin* CIkev1Plugin::NewL( MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ) + { + CIkev1Plugin* self = new ( ELeave ) CIkev1Plugin( aEventLogger, aDebug ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CIkev1Plugin::~CIkev1Plugin() + { + __ASSERT_DEBUG( iPluginSessions.Count() == 0, + User::Invariant() ); + iPluginSessions.Close(); + delete iPFKeySocket; + delete iIpsecPolicyUtil; + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CIkev1Plugin::CIkev1Plugin( MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ) + : iEventLogger( aEventLogger ), + iDebug( aDebug ) + { + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CIkev1Plugin::ConstructL() + { + iPFKeySocket = CPFKeySocketIf::NewL( this, + iDebug ); + + iIpsecPolicyUtil = CIpsecPolicyUtil::NewL(); + } + +// --------------------------------------------------------------------------- +// Removes IKE plugin session from array. +// --------------------------------------------------------------------------- +// +void CIkev1Plugin::IkePluginSessionDeleted( CIkev1PluginSession* aPluginSession ) + { + for ( TInt i=0; iGetIpseSaSpecListLC( aLocalAddr, aLocalMask, + aRemoteAddr, aRemoteMask, + aProtocol, aVpnNetId ); + } + +// Methods to build and send PFKEY API primitives to IPsec + +void CIkev1Plugin::AcquireSAError( TIpsecSAData& aSAData, + TInt aError ) + { + iPFKeySocket->AcquireSAError( aSAData, aError ); + } + +void CIkev1Plugin::UpdateSAL( TIpsecSAData& aSaData ) + { + iPFKeySocket->UpdateSAL( aSaData ); + } + +void CIkev1Plugin::AddSAL( TIpsecSAData& aSaData ) + { + iPFKeySocket->AddSAL( aSaData ); + } + +void CIkev1Plugin::DeleteIpsecSA( TIpsecSPI& aIpsecSpi ) + { + iPFKeySocket->DeleteSA( aIpsecSpi.iSPI, + aIpsecSpi.iSrcAddr, + aIpsecSpi.iDstAddr, + aIpsecSpi.iProtocol ); + } + +void CIkev1Plugin::DeleteIpsecSA( TUint32 aSPI, + TInetAddr& aSrc, + TInetAddr& aDst, + TUint8 aProtocol ) + { + iPFKeySocket->DeleteSA( aSPI, aSrc, aDst, aProtocol ); + } + +// --------------------------------------------------------------------------- +// Creates IKEv1 plugin session. +// --------------------------------------------------------------------------- +// +MIkePluginSessionIf* CIkev1Plugin::CreateSessionL( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + MIkeDataInterface& aDataInterface ) + { + CIkev1PluginSession* pluginSession = CIkev1PluginSession::NewL( aVpnIapId, + aVpnNetId, + aVpnInterfaceIndex, + aDataInterface, + *this, + *iPFKeySocket, + iDebug ); + TInt err = iPluginSessions.Append( pluginSession ); + + if ( err != KErrNone ) + { + delete pluginSession; + pluginSession = NULL; + User::Leave( err ); + } + + return pluginSession; + } + +// --------------------------------------------------------------------------- +// Handles PFKEY message. +// --------------------------------------------------------------------------- +// +void CIkev1Plugin::PfkeyMessageReceived( const TPfkeyMessage& aPfkeyMessage ) + { + switch ( aPfkeyMessage.iBase.iMsg->sadb_msg_type ) + { + case SADB_ACQUIRE: + { + for ( TInt i=0; i< iPluginSessions.Count(); i++ ) + { + if ( iPluginSessions[i]->MatchDestinationAddress( aPfkeyMessage.iDstAddr.Address() ) ) + { + iPluginSessions[i]->PfkeyMessageReceived( aPfkeyMessage ); + break; + } + } + break; + } + + case SADB_EXPIRE: + { + for ( TInt i=0; i< iPluginSessions.Count(); i++ ) + { + if ( iPluginSessions[i]->MatchDestinationAddress( aPfkeyMessage.iSrcAddr.Address() ) ) + { + iPluginSessions[i]->PfkeyMessageReceived( aPfkeyMessage ); + break; + } + } + break; + } + default: + break; + } + } + + +// --------------------------------------------------------------------------- +// Returns UID. +// --------------------------------------------------------------------------- +// +TUint32 CIkev1Plugin::Uid() + { + return KIkeV1PluginUid3.iUid; + } + +// --------------------------------------------------------------------------- +// Returns event logger interface. +// --------------------------------------------------------------------------- +// +MKmdEventLoggerIf& CIkev1Plugin::EventLogger() + { + return iEventLogger; + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1pluginsession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1pluginsession.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,1924 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv1 plugin session +* +*/ + + +#include +#include +#include "ikev1plugin.h" +#include "ikedebug.h" +#include "ikev1negotiation.h" +#include "ikev1isakmpstream.h" +#include "pfkeymsg.h" +#include "ikepolparser.h" +#include "kmdapi.h" +#include "ikev1crack.h" +#include "ikev1infonegotiation.h" +#include "ikev1SA.h" +#include "ikev1sender.h" +#include "ikesocketdefs.h" +#include "ikedatainterface.h" +#include "vpnaddrinfo.h" +#include "ipsecsaspiretriever.h" + +// CLASS HEADER +#include "ikev1pluginsession.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CIkev1PluginSession* CIkev1PluginSession::NewL( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + MIkeDataInterface& aDataInterface, + CIkev1Plugin& aPlugin, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug ) + { + CIkev1PluginSession* self = new ( ELeave ) CIkev1PluginSession( aVpnIapId, + aVpnNetId, + aVpnInterfaceIndex, + aDataInterface, + aPlugin, + aPFKeySocketIf, + aDebug ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CIkev1PluginSession::~CIkev1PluginSession() + { + // Cancel client's requests. + DoCompleteNegotiateWithHost( KErrCancel ); + DoCompleteDeleteSession( KErrCancel ); + DoCompleteNotifyError( KErrCancel ); + DoCompleteInternalAddressChanged( KErrCancel ); + + if ( iDialogWaitQueue ) + { + CIkev1Dialog::PurgeDialogQueue( iDialogWaitQueue ); + } + + CIkev1Negotiation* negotiation; + while ( iFirstNegotiation ) + { + negotiation = iFirstNegotiation; + delete negotiation; // destructor removes object from queue, too + } + + DoEmptySendQueue(); + iSendQueue.Close(); + + while ( iIkev1SAs.Count() ) + { + CIkev1SA* ikev1SA = iIkev1SAs[0]; + iIkev1SAs.Remove(0); + delete ikev1SA; + } + iIkev1SAs.Close(); + + delete iReceiver; + delete iSender; + delete iIkeData; + delete iInternalAddress; + + iPlugin.IkePluginSessionDeleted( this ); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CIkev1PluginSession::CIkev1PluginSession( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + MIkeDataInterface& aDataInterface, + CIkev1Plugin& aPlugin, + CPFKeySocketIf& aPFKeySocketIf, + MIkeDebug& aDebug ) +: iVpnIapId( aVpnIapId ), + iVpnNetId( aVpnNetId ), + iVpnInterfaceIndex( aVpnInterfaceIndex ), + iDataInterface( aDataInterface ), + iPlugin( aPlugin ), + iPFKeySocketIf( aPFKeySocketIf ), + iDebug( aDebug ) + { + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::ConstructL() + { + TPtr8 ptr( (TUint8*)&iSAIdSeed, sizeof(iSAIdSeed) ); + ptr.SetLength( sizeof(iSAIdSeed) ); + TRandom::RandomL( ptr ); + iSAIdSeed &= 0x7fffffff; // Reset the most significant bit + + iReceiver = CIkev1Receiver::NewL( iDataInterface, + *this ); + iSender = CIkev1Sender::NewL( iDataInterface, + *this, + iDebug ); + + DEBUG_LOG1( _L("CIkev1PluginSession::ConstructL, SAId seed: %d"), + iSAIdSeed ); + } + +// --------------------------------------------------------------------------- +// Handles IKE SA deletion request. +// --------------------------------------------------------------------------- +// +TBool CIkev1PluginSession::DeleteIkeSA( TIkev1SAData* aIkev1SaData, + TBool aSilentClose ) + { + // + // An IKE SA delete request received + // Check first does there exists an ongoing negotiation on this IKE + // SA deleted and delete this block. + // Allocate a new negotiation with TIkev1SAData and initiate IKE SA + // deletion request + // + DEBUG_LOG1( _L("Deleting IKEv1 SA SAID = %d"), + aIkev1SaData->iSAId ); + + CIkev1Negotiation* negotiation = FindNegotiation( aIkev1SaData->iSAId ); + while ( negotiation ) + { + delete negotiation; // destructor removes object from queue, too + negotiation = FindNegotiation( aIkev1SaData->iSAId ); + } + + TBool started( EFalse ); + + if ( !aSilentClose ) + { + DeleteIpsecSAs( aIkev1SaData->iSAId ); + + TRAPD( err, + { + // Trap the SendDeleteL -- it can fail, but the failure won't be fatal + // (delete payload just won't be sent) + negotiation = CIkev1Negotiation::NewL( this, + iPFKeySocketIf, + iDebug, + aIkev1SaData, + RESPONDER ); // Nevermind INITIATOR or RESPONDER + negotiation->SendDeleteL( PROTO_ISAKMP ); + } ); + + delete negotiation; + negotiation = NULL; + + if ( err == KErrNone ) + { + // DELETE payload sent succesfully. + DEBUG_LOG( _L("CIkev1PluginSession::DeleteIkeSAL() IKEv1 delete send OK") ); + started = ETrue; + } + else + { + DEBUG_LOG1( _L("CIkev1PluginSession::DeleteIkeSAL() IKEv1 delete send failed, err=%d"), err ); + } + } +#ifdef _DEBUG + else + { + DEBUG_LOG( _L("Forced close, no delete payload(s) sent")); + } +#endif + ExpireIkev1SA( aIkev1SaData->iSAId ); // Set expired to delete IKE SA + + if ( FindIkev1SA() == NULL && + FirstNegotiation() == NULL ) + { + // Set error status, when expired IKE SA was the only IKE SA and there + // is no ongoing negotiation. + iErrorStatus = KKmdIkeNegotFailed; + } + + return started; + } + +// --------------------------------------------------------------------------- +// Handles IKE SA rekeying request. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::RekeyIkeSAL( TIkev1SAData* aIkev1SaData, + CSARekeyInfo* aSaRekeyInfo ) + { + CIkev1Negotiation* negotiation = CIkev1Negotiation::NewL( this, + iPFKeySocketIf, + iDebug, + aIkev1SaData->iRemoteAddr, + EFalse ); + CleanupStack::PushL( negotiation ); + negotiation->SetRekeyInfo( aSaRekeyInfo ); + negotiation->InitNegotiationL(); + if ( negotiation->Finished() ) + { + CleanupStack::PopAndDestroy( negotiation ); + } + else + { + CleanupStack::Pop( negotiation ); + } + } + +// --------------------------------------------------------------------------- +// Handles IKE SA keepalive request. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::KeepAliveIkeSAL( TIkev1SAData* aIkev1SaData ) + { + CIkev1Negotiation* negotiation = CIkev1Negotiation::NewL( this, + iPFKeySocketIf, + iDebug, + aIkev1SaData, + RESPONDER ); + CleanupStack::PushL( negotiation ); + negotiation->SendKeepAliveMsgL( aIkev1SaData ); + if ( negotiation->Finished() ) + { + CleanupStack::PopAndDestroy( negotiation ); + } + else + { + CleanupStack::Pop( negotiation ); + } + } + +// --------------------------------------------------------------------------- +// Creates IKE SA. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::CreateIkev1SAL( TIkev1SAData& aIkev1SaData, + CSARekeyInfo* aSaRekey ) + { + CIkev1SA* ikev1SA = CIkev1SA::NewL( *this, + aIkev1SaData, + aSaRekey, + iDebug ); + + if ( !aIkev1SaData.iInitiator ) + { + // Move SPI list from previous IKE SA to new IKE SA + for ( TInt i=0;iiSPIList != NULL ) + { + DEBUG_LOG(_L("Move SPI list to new IKE SA")); + delete ikev1SA->iSPIList; + ikev1SA->iSPIList = previousSA->iSPIList; + previousSA->iSPIList = new (ELeave) CIpsecSPIList(1); // Dummy; + break; + } + } + } + + // Cancel IKE SA rekeying from other IKE SAs. + for ( TInt i=0;iCancelRekey(); + } + + CleanupStack::PushL( ikev1SA ); + iIkev1SAs.AppendL( ikev1SA ); + CleanupStack::Pop( ikev1SA ); + } + +// --------------------------------------------------------------------------- +// Updates IKE SA. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::UpdateIkev1SAL( TUint32 aSaId, + TBool aExpired, + TIkev1SAData* aIkev1SaData ) + { + if ( !aExpired ) + { + CIkev1SA* Ikev1SA = FindIkev1SAWithId( aSaId ); + if ( Ikev1SA ) + { + Ikev1SA->UpdateSAL( aExpired, aIkev1SaData ); + } + } + else + { + ExpireIkev1SA( aSaId ); + } + } + +// --------------------------------------------------------------------------- +// Expires IKE SA. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::ExpireIkev1SA( TUint32 aSaId ) + { + CIkev1SA* ikev1SA = FindIkev1SAWithId( aSaId ); + if ( ikev1SA ) + { + ikev1SA->ExpireSA(); + } + } + +// --------------------------------------------------------------------------- +// Removes IKE SA. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::RemoveIkeSA( CIkev1SA* aIkev1Sa, + TInt aStatus ) + { + TInt dpdRetryCount( 0 ); + + for ( TInt i=0;iiHdr.iDPDRetry; + iIkev1SAs.Remove(i); + delete sa; + break; + } + } + + if ( (iErrorStatus == KErrNone) && + (dpdRetryCount > KMaxDpdRetryCount) && + (FindIkev1SA() == NULL) ) + { + // If DPD retry count was reached for only IKE SA, set error status. + iErrorStatus = KKmdIkeNoResponseErr; + } + + // If session deletion has been requested, complete session deletion + // request. + DoCompleteDeleteSession( aStatus ); + + // If fatal error has occured, complete error notification. + if ( iErrorStatus != KErrNone ) + { + DoHandleError( iErrorStatus ); + } + } + +// IKE SA find methods. + +CIkev1SA* CIkev1PluginSession::FindIkev1SA() + { + for ( TInt i=0;iIsExpired()) ) + { + return sa; + } + } + return NULL; + } + +CIkev1SA* CIkev1PluginSession::FindIkev1SA( const TCookie& aCookie_I, + const TCookie& aCookie_R ) + { + for ( TInt i=0;iiHdr.iCookie_I == aCookie_I) && + (sa->iHdr.iCookie_R == aCookie_R) && + (!sa->IsExpired()) ) + { + return sa; + } + } + return NULL; + } + +CIkev1SA* CIkev1PluginSession::FindIkev1SAWithId( TUint32 aSaId ) + { + for ( TInt i=0;iiHdr.iSAId == aSaId) && + (!sa->IsExpired()) ) + { + return sa; + } + } + return NULL; + } + +CIkev1SA* CIkev1PluginSession::FindIkev1SA( const TInetAddr& aAddr ) + { + for ( TInt i=0;iiHdr.iRemoteAddr.Match(aAddr) && + (!sa->IsExpired()) ) + { + return sa; + } + } + return NULL; + } + +CIkev1SA* CIkev1PluginSession::FindIkev1SA( const TInetAddr& aAddr, + TUint32 aInboundSpi ) + { + for ( TInt i=0;iiHdr.iRemoteAddr.Match(aAddr) && + (!sa->IsExpired()) ) + { + if ( sa->FindIpsecSPI(aInboundSpi, ETrue) ) + { + return sa; + } + } + } + return NULL; + } + +TIkev1SAData* CIkev1PluginSession::FindIkev1SAData() + { + TIkev1SAData* saData = NULL; + CIkev1SA* ikev1SA = FindIkev1SA(); + if ( ikev1SA ) + { + saData = (TIkev1SAData*)&ikev1SA->iHdr; + } + return saData; + } + +TIkev1SAData* CIkev1PluginSession::FindIkev1SAData( const TCookie& aCookie_I, + const TCookie& aCookie_R ) + { + TIkev1SAData* saData = NULL; + CIkev1SA* ikev1SA = FindIkev1SA( aCookie_I, aCookie_R ); + if ( ikev1SA ) + { + saData = (TIkev1SAData*)&ikev1SA->iHdr; + } + return saData; + } + +TIkev1SAData* CIkev1PluginSession::FindIkev1SAData( TUint32 aSaId ) + { + TIkev1SAData* saData = NULL; + CIkev1SA* ikev1SA = FindIkev1SAWithId( aSaId ); + if ( ikev1SA ) + { + saData = (TIkev1SAData*)&ikev1SA->iHdr; + } + return saData; + } + +TIkev1SAData* CIkev1PluginSession::FindIkev1SAData( const TInetAddr& aAddr, + TUint32 aInboundSpi ) + { + TIkev1SAData* saData = NULL; + CIkev1SA* ikev1SA = FindIkev1SA( aAddr, aInboundSpi ); + if ( ikev1SA ) + { + saData = (TIkev1SAData*)&ikev1SA->iHdr; + } + return saData; + } + +TIkev1SAData* CIkev1PluginSession::FindIkev1SADataWithAddr( const TInetAddr& aAddr ) + { + TIkev1SAData* saData = NULL; + CIkev1SA* ikev1SA = FindIkev1SA( aAddr ); + if ( ikev1SA ) + { + saData = (TIkev1SAData*)&ikev1SA->iHdr; + } + return saData; + } + +// --------------------------------------------------------------------------- +// Handles IPsec SA deletion request. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::DeleteIpsecSAL( TIkev1SAData* aIkev1SaData, + TIpsecSPI* aIpsecSpi ) + { + // + // Send a delete payload for specified IPSec SA + // + CIkev1Negotiation* negotiation = CIkev1Negotiation::NewL( this, + iPFKeySocketIf, + iDebug, + aIkev1SaData, + RESPONDER ); + CleanupStack::PushL( negotiation ); + negotiation->SendDeleteL( aIpsecSpi->iProtocol, + aIpsecSpi->iSPI ); + CleanupStack::PopAndDestroy( negotiation ); + } + +// --------------------------------------------------------------------------- +// Deletes IPsec SAs. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::DeleteIpsecSAs( TUint32 aSaId ) + { + CIkev1SA* ikev1SA = FindIkev1SAWithId( aSaId ); + if ( ikev1SA ) + { + ikev1SA->DeleteIpsecSAs(); + } + } + +// --------------------------------------------------------------------------- +// Deletes IPsec SPI. +// --------------------------------------------------------------------------- +// +TBool CIkev1PluginSession::DeleteIpsecSpi( TUint32 aSaId, + TUint32 aSpi, + TBool aInbound ) + { + TBool status = EFalse; + CIkev1SA* ikev1SA = FindIkev1SAWithId( aSaId ); + if ( ikev1SA ) + { + status = ikev1SA->DeleteIpsecSPI( aSpi, aInbound ); + } + return status; + } + +// --------------------------------------------------------------------------- +// Adds IPsec SPI to IKE SA. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::AddIpsecSPIToSAL( TUint32 aSaId, + TIpsecSPI& aIpsecSpi ) + { + CIkev1SA* ikev1SA = FindIkev1SAWithId( aSaId ); + if ( ikev1SA ) + { + ikev1SA->AddIpsecSPIL( aIpsecSpi ); + } + } + +// --------------------------------------------------------------------------- +// Returns dialog anchor. +// --------------------------------------------------------------------------- +// +CIkev1Dialog** CIkev1PluginSession::DialogAnchor() + { + return &iDialogWaitQueue; + } + +// --------------------------------------------------------------------------- +// Returns debug trace interface. +// --------------------------------------------------------------------------- +// +MIkeDebug& CIkev1PluginSession::Debug() + { + return iDebug; + } + +// --------------------------------------------------------------------------- +// Gets SA id. +// --------------------------------------------------------------------------- +// +TUint32 CIkev1PluginSession::GetSAId() + { + iSAIdSeed++; + return iSAIdSeed; + } + +// --------------------------------------------------------------------------- +// Deletes ISAKMP SAs. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::DeleteISAKMPSAsL( TDeleteISAKMP* aDeletePayload, + const CIkev1Negotiation& aInfoNegotiation ) + { + TCookie cookie_I, cookie_R; + + // It should always be only one. + for ( TInt i=0; i < aDeletePayload->NumSPI(); i++ ) + { + if ( aDeletePayload->SPISize() < 2 * ISAKMP_COOKIE_SIZE ) //The ISAKMPSA SPI is the union of both cookies + { + DEBUG_LOG( _L("Bad SPI Size for a ISAKMP SA. (SA Not deleted)") ); + return; + } + cookie_I.Copy( aDeletePayload->SPI(i), ISAKMP_COOKIE_SIZE ); + cookie_R.Copy( aDeletePayload->SPI(i) + ISAKMP_COOKIE_SIZE, + ISAKMP_COOKIE_SIZE); + + CIkev1Negotiation* neg = iFirstNegotiation; + while ( neg ) + { + CIkev1Negotiation* current = neg; + neg = neg->iNext; + + // Delete any active negotiations with the same cookies. + // Currently used negotiation is not deleted. + if ( ( current != &aInfoNegotiation ) && + ( current->iCookie_I == cookie_I ) && + ( current->iCookie_R == cookie_R ) ) + { + DEBUG_LOG( _L("Active negotiation deleted.") ); + delete current; + current = NULL; + } + } + + // Expire IKE SA. + TIkev1SAData* sa = FindIkev1SAData( cookie_I, cookie_R ); + if ( sa ) + { + UpdateIkev1SAL( sa->iSAId, ETrue ); + } + } + } + +// --------------------------------------------------------------------------- +// Gets local IP address. +// --------------------------------------------------------------------------- +// +TInt CIkev1PluginSession::GetLocalAddress( TInetAddr& aAddr ) + { + TInt err( KErrNone ); + if ( iLocalAddr.IsUnspecified() ) + { + err = iDataInterface.GetLocalAddress( iLocalAddr ); + } + + aAddr = iLocalAddr; + return err; + } + +// --------------------------------------------------------------------------- +// Sends IKE message. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::SendIkeMsgL( const TDesC8& aIkeMsg, + TInetAddr& aDestAddr, + TBool aUseNatPort ) + { + // Construct buffer for storing IKE message data. + TInt localPort = ( aUseNatPort ? + IkeSocket::KIkePort4500 : + IkeSocket::KIkePort500 ); + TInt length = aIkeMsg.Length(); + if ( localPort == IkeSocket::KIkePort4500 ) + { + // Reserve space for . + length += NON_ESP_MARKER_SIZE; + } + HBufC8* ikeMsg = HBufC8::NewL( length ); + TPtr8 ptr = ikeMsg->Des(); + if ( localPort == IkeSocket::KIkePort4500 ) + { + // Append to the beginning of IKE message. + TUint32 nonEspMarker = NON_ESP_MARKER; + TUint8* nonEspPtr = (TUint8*)&nonEspMarker; + ptr.Append( nonEspPtr, NON_ESP_MARKER_SIZE ); + } + // Append IKE message data to descriptor. + ptr.Append( aIkeMsg ); + + DoSendUdpDataL( ikeMsg, // Ownership transferred. + aDestAddr, + localPort, + 0 ); + } + +// --------------------------------------------------------------------------- +// Sends NAT keep-alive packet. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::SendNatKeepAliveL( TInetAddr& aDestAddr, + const TDesC8& aData, + TUint8 aDscp ) + { + DEBUG_LOG(_L("CIkev1PluginSession::SendNatKeepAliveL")); + HBufC8* udpData = HBufC8::NewL( aData.Length() ); + *udpData = aData; + TInt localPort = aDestAddr.Port(); + DoSendUdpDataL( udpData, // Ownership transferred. + aDestAddr, + localPort, + aDscp ); + } + +// --------------------------------------------------------------------------- +// Sends Nokia NAT keep-alive packet. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::SendNokiaNatKeepAliveL( TInetAddr& aDestAddr, + const TDesC8& aData, + TUint8 aDscp ) + { + DEBUG_LOG(_L("CIkev1PluginSession::SendNokiaNatKeepAliveL")); + SendNatKeepAliveL( aDestAddr, + aData, + aDscp ); + } + +// --------------------------------------------------------------------------- +// Handles completion of IKE SA establishment. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::IkeSaCompleted( TInt aStatus, + CInternalAddress* aInternalAddress ) + { + delete iInternalAddress; + iInternalAddress = aInternalAddress; + + DoCompleteNegotiateWithHost( aStatus ); + } + +// --------------------------------------------------------------------------- +// Deletes negotiation object. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::DeleteNegotiation( CIkev1Negotiation* aNegotiation ) + { + TInt err = ErrorStatus(); + delete aNegotiation; + + if ( err == KErrNone && + (iClientStatusNegotiate != NULL || + iClientStatusDelete != NULL) && + (FindIkev1SA() == NULL) ) + { + // If negotiate or delete session request has been issued, and + // there are no IKE SAs, client is completed with error. + err = KKmdIkeNegotFailed; + } + + DEBUG_LOG1(_L("IKEv1 negotiation deleted, status=%d"), + err ); + + if ( err != KErrNone ) + { + // + // IKE negotiation failed. + // + DoHandleError( err ); + } + } + +// Negotiation linking and find methods. + +void CIkev1PluginSession::LinkNegotiation( CIkev1Negotiation* aNegotiation ) + { + aNegotiation->iNext = iFirstNegotiation; + iFirstNegotiation = aNegotiation; + } + +CIkev1Negotiation* CIkev1PluginSession::FirstNegotiation() + { + return iFirstNegotiation; + } + +CIkev1Negotiation* CIkev1PluginSession::FindNegotiation( TCookie aInit, + TCookie aResp, + TUint8 aExchange, + TUint32 aMsgId ) + { + CIkev1Negotiation* negotiation; + TCookie NULL_COOKIE; + NULL_COOKIE.FillZ(ISAKMP_COOKIE_SIZE); + + if ( aExchange == ISAKMP_EXCHANGE_INFO ) + { + for ( negotiation = iFirstNegotiation; + negotiation; + negotiation = negotiation->iNext ) + { + if ( (negotiation->iCookie_I.Compare(aInit) == 0 ) && + ((negotiation->iCookie_R.Compare(aResp) == 0 ) || + (negotiation->iCookie_R.Compare(NULL_COOKIE) == 0)) ) + { + return negotiation; + } + } + + } + else + { + for ( negotiation = iFirstNegotiation; + negotiation; + negotiation = negotiation->iNext ) + { + if ( negotiation->iCookie_I.Compare(aInit) == 0 ) + { + if ( (negotiation->iMessageId == aMsgId) || + (negotiation->iMessageId == 0) ) + { + if ( (negotiation->iCookie_R.Compare(aResp) == 0 ) || + (negotiation->iCookie_R.Compare(NULL_COOKIE) == 0) || + (aResp.Compare(NULL_COOKIE) == 0) ) + { + return negotiation; + } + } + } + } + } + + return NULL; // Not found + } + +CIkev1Negotiation* CIkev1PluginSession::FindNegotiation( TUint32 aSaId ) + { + // + // Find IKEv1 negotiation object using SA id as search argument + // + CIkev1Negotiation* negotiation = iFirstNegotiation; + while ( negotiation ) + { + if ( negotiation->SAId() == aSaId ) + { + break; + } + + negotiation = negotiation->iNext; + } + return negotiation; + } + +void CIkev1PluginSession::RemoveNegotiation( CIkev1Negotiation* aNegotiation ) + { + CIkev1Negotiation* prev = NULL; + CIkev1Negotiation* negotiation = iFirstNegotiation; + + while ( negotiation ) + { + if ( negotiation == aNegotiation ) + { + if ( prev ) + { + prev->iNext = negotiation->iNext; + } + else + { + iFirstNegotiation = negotiation->iNext; + } + break; + } + prev = negotiation; + negotiation = negotiation->iNext; + } + } + +// --------------------------------------------------------------------------- +// Handles completion of authentication dialog processing. +// --------------------------------------------------------------------------- +// +TInt CIkev1PluginSession::AuthDialogCompletedL( CAuthDialogInfo* aUserInfo ) + { + CIkev1Negotiation* negotiation = FindNegotiation( aUserInfo->SAId() ); + if ( negotiation ) + { + DEBUG_LOG1( _L("Dialog completed for SAID: %d"), + aUserInfo->SAId() ); + + negotiation->AuthDialogCompletedL(aUserInfo); + if ( negotiation->Finished() ) + { + DeleteNegotiation( negotiation ); + } + return KErrNone; + } + DEBUG_LOG1( _L("Dialog completed, no negotiation found for SAID: %d"), + aUserInfo->SAId() ); + return KErrNotFound; + } + + +// --------------------------------------------------------------------------- +// Handles change of internal address. +// --------------------------------------------------------------------------- +// +TBool CIkev1PluginSession::InternalAddressChangedL( const CInternalAddress& aInternalAddr ) + { + TBool internalAddressChanged( ETrue ); + + if ( iInternalAddress ) + { + if ( iInternalAddress->iClientIntAddr.Match(aInternalAddr.iClientIntAddr) ) + { + internalAddressChanged = EFalse; + } + } + + delete iInternalAddress; + iInternalAddress = NULL; + iInternalAddress = CInternalAddress::NewL( aInternalAddr ); + + if ( internalAddressChanged ) + { + DoCompleteInternalAddressChanged( KErrNone ); + } + + return internalAddressChanged; + } + +// --------------------------------------------------------------------------- +// Gets acceptable IPsec policies for specified selectors. +// --------------------------------------------------------------------------- +// +CIpsecSaSpecList* CIkev1PluginSession::GetIpseSaSpecListLC( const TInetAddr& aLocalAddr, const TInetAddr& aLocalMask, + const TInetAddr& aRemoteAddr, const TInetAddr& aRemoteMask, + TInt aProtocol ) + + { + return iPlugin.GetIpseSaSpecListLC( aLocalAddr, aLocalMask, + aRemoteAddr, aRemoteMask, + aProtocol, iVpnNetId ); + } + +// --------------------------------------------------------------------------- +// Matches destination address to remote address in IKE policy data. +// --------------------------------------------------------------------------- +// +TBool CIkev1PluginSession::MatchDestinationAddress( const TInetAddr& aDestAddr ) + { + TBool match( EFalse ); + + if ( iIkeData ) + { + match = iIkeData->iAddr.Match( aDestAddr ); + } + return match; + } + +// --------------------------------------------------------------------------- +// Handles fatal error. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::HandleError( TInt aStatus ) + { + DoHandleError( aStatus ); + } + +// --------------------------------------------------------------------------- +// Returns error status. +// --------------------------------------------------------------------------- +// +TInt CIkev1PluginSession::ErrorStatus() + { + return iErrorStatus; + } + +// --------------------------------------------------------------------------- +// Sets error status. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::SetErrorStatus( TInt aStatus ) + { + if ( iErrorStatus == KErrNone ) + { + iErrorStatus = aStatus; + } + } + +// --------------------------------------------------------------------------- +// Returns VPN IAP id. +// --------------------------------------------------------------------------- +// +TUint32 CIkev1PluginSession::VpnIapId() + { + return iVpnIapId; + } + +// --------------------------------------------------------------------------- +// Returns VPN interface index. +// --------------------------------------------------------------------------- +// +TUint32 CIkev1PluginSession::VpnInterfaceIndex() + { + return iVpnInterfaceIndex; + } + +// --------------------------------------------------------------------------- +// Returns IKE policy data. +// --------------------------------------------------------------------------- +// +CIkeData& CIkev1PluginSession::IkeData() + { + __ASSERT_DEBUG( iIkeData != NULL, + User::Invariant() ); + return *iIkeData; + } + +// --------------------------------------------------------------------------- +// Returns UID. +// --------------------------------------------------------------------------- +// +TUint32 CIkev1PluginSession::Uid() + { + return iPlugin.Uid(); + } + +// --------------------------------------------------------------------------- +// Returns event logger interface. +// --------------------------------------------------------------------------- +// +MKmdEventLoggerIf& CIkev1PluginSession::EventLogger() + { + return iPlugin.EventLogger(); + } + +// --------------------------------------------------------------------------- +// Returns internal address (NULL if does not exist). +// --------------------------------------------------------------------------- +// +CInternalAddress* CIkev1PluginSession::InternalAddressL() + { + DEBUG_LOG(_L("CIkev1PluginSession::InternalAddressL")); + + CInternalAddress* internalAddress = NULL; + if ( iInternalAddress != NULL ) + { + internalAddress = CInternalAddress::NewL( *iInternalAddress ); + } + return internalAddress; + } + +// --------------------------------------------------------------------------- +// From class MIkev1SenderCallback +// Handles completion of sending. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::SendUdpDataCompleted( TInt aStatus ) + { + if ( iSendQueue.Count() != 0 ) + { + // Send queue is not empty. + // Send next item from queue. + TIkeSendQueueItem item = iSendQueue[0]; + HBufC8* udpData = item.UdpData(); + TInetAddr destAddr = item.DestAddr(); + TInt localPort = item.LocalPort(); + TUint8 dscp = item.Dscp(); + iSendQueue.Remove(0); + DoSendUdpData( udpData, + destAddr, + localPort, + dscp ); + + } + else + { + // IKE message send queue is empty. + // If session deletion has been requested, complete request. + DoCompleteDeleteSession( aStatus ); + } + } + +// --------------------------------------------------------------------------- +// Handles PFKEY message. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::PfkeyMessageReceived( const TPfkeyMessage& aPfkeyMessage ) + { + TRAPD( err, DoPfkeyMessageReceivedL( aPfkeyMessage) ); + err = err; + DEBUG_LOG1(_L("CIkev1PluginSession::PfkeyMessageReceivedL, err=%d"), err); + } + +// Methods to build and send PFKEY API primitives to IPsec + +void CIkev1PluginSession::AcquireSAError( TIpsecSAData& aSAData, + TInt aError ) + { + iPlugin.AcquireSAError( aSAData, aError ); + } + +void CIkev1PluginSession::UpdateSAL( TIpsecSAData& aSaData ) + { + iPlugin.UpdateSAL( aSaData ); + } + +void CIkev1PluginSession::AddSAL( TIpsecSAData& aSaData ) + { + iPlugin.AddSAL( aSaData ); + } + +void CIkev1PluginSession::DeleteIpsecSA( TIpsecSPI& aIpsecSpi ) + { + iPlugin.DeleteIpsecSA( aIpsecSpi ); + } + +void CIkev1PluginSession::DeleteIpsecSA( TUint32 aSPI, + TInetAddr& aSrc, + TInetAddr& aDst, + TUint8 aProtocol ) + { + iPlugin.DeleteIpsecSA( aSPI, aSrc, aDst, aProtocol ); + } + +// --------------------------------------------------------------------------- +// From class MIkePluginSessionIf +// Starts negotiation with a peer. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::NegotiateWithHost( const CIkeData& aIkeData, + TVPNAddress& aInternalAddress, + TRequestStatus& aStatus ) + { + DEBUG_LOG(_L("CIkev1PluginSession::NegotiateWithHost")); + __ASSERT_DEBUG( iClientStatusNegotiate == NULL, + User::Invariant() ); + + // Store client's request status and internal address. + iClientStatusNegotiate = &aStatus; + *iClientStatusNegotiate = KRequestPending; + iClientIaNegotiate = &aInternalAddress; + + TRAPD( err, DoNegotiateWithHostL( aIkeData ) ); + + if ( err != KErrNone ) + { + DoCompleteNegotiateWithHost( err ); + } + } + +// --------------------------------------------------------------------------- +// From class MIkePluginSessionIf +// Cancels negotiate request. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::CancelNegotiateWithHost() + { + DEBUG_LOG(_L("CIkev1PluginSession::CancelNegotiateWithHost")); + + if ( iClientStatusNegotiate != NULL ) + { + // Completion is enough as deletion of session is requested after + // cancellation. + DoCompleteNegotiateWithHost( KErrCancel ); + } + } + +// --------------------------------------------------------------------------- +// From class MIkePluginSessionIf +// Deletes session. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::DeleteSession( const TBool aSilentClose, + TRequestStatus& aStatus ) + { + DEBUG_LOG1(_L("CIkev1PluginSession::DeleteSession, silent=%d"), + aSilentClose); + + iClientStatusDelete = &aStatus; + *iClientStatusDelete = KRequestPending; + + TBool deactivatingStarted = DeleteSAsWithHost( aSilentClose ); + if ( !deactivatingStarted ) + { + DoCompleteDeleteSession( KErrNone ); + } + } + +// --------------------------------------------------------------------------- +// From class MIkePluginSessionIf +// Cancels deletion requests. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::CancelDeleteSession() + { + DEBUG_LOG(_L("CIkev1PluginSession::CancelDeleteSession")); + + if ( iClientStatusDelete != NULL ) + { + // Delete SAs silently. + DeleteSAsWithHost( ETrue ); + + DoCancelDataTransfer(); + + User::RequestComplete( iClientStatusDelete, KErrCancel ); + iClientStatusDelete = NULL; + } + } + +// --------------------------------------------------------------------------- +// From class MIkePluginSessionIf +// Requests notification about error condition. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::NotifyError( TRequestStatus& aStatus ) + { + DEBUG_LOG(_L("CIkev1PluginSession::NotifyError")); + + iClientStatusNotifyError = &aStatus; + *iClientStatusNotifyError = KRequestPending; + } + +// --------------------------------------------------------------------------- +// From class MIkePluginSessionIf +// Cancels error notification request. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::CancelNotifyError() + { + DEBUG_LOG(_L("CIkev1PluginSession::CancelNotifyError")); + + if ( iClientStatusNotifyError != NULL ) + { + User::RequestComplete( iClientStatusNotifyError, KErrCancel ); + iClientStatusNotifyError = NULL; + } + } + +// --------------------------------------------------------------------------- +// From class MIkePluginSessionIf +// Requests notification about change of internal address. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::NotifyInternalAddressChanged( TVPNAddress& aInternalAddress, + TRequestStatus& aStatus ) + { + DEBUG_LOG(_L("CIkev1PluginSession::NotifyInternalAddressChanged")); + __ASSERT_DEBUG( iClientStatusNotifyIaChange == NULL, + User::Invariant() ); + + iClientStatusNotifyIaChange = &aStatus; + *iClientStatusNotifyIaChange = KRequestPending; + iClientIaNotify = &aInternalAddress; + } + +// --------------------------------------------------------------------------- +// From class MIkePluginSessionIf +// Cancels internal address change notification request. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::CancelNotifyInternalAddressChanged() + { + DEBUG_LOG(_L("CIkev1PluginSession::CancelNotifyInternalAddressChanged")); + + if ( iClientStatusNotifyIaChange != NULL ) + { + DoCompleteInternalAddressChanged( KErrCancel ); + } + } + +// --------------------------------------------------------------------------- +// From class MIkev1ReceiverCallback +// Handles notification about received IKE message. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::IkeMsgReceivedL( const ThdrISAKMP& aIkeMsg, + const TInetAddr& aSrcAddr, + TInt aLocalPort ) + { + CIkev1Negotiation* negotiation = NULL; + TIkev1SAData* sa = NULL; + + TUint8 exchange = aIkeMsg.GetExchange(); + negotiation = FindNegotiation( aIkeMsg.GetCookieI(), + aIkeMsg.GetCookieR(), + exchange, + aIkeMsg.GetMessageId() ); + + if ( exchange == ISAKMP_EXCHANGE_INFO || exchange == ISAKMP_EXCHANGE_TRANSACT ) + { +#ifdef _DEBUG + if ( exchange == ISAKMP_EXCHANGE_INFO ) + { + DEBUG_LOG( _L("---ISAKMP_EXCHANGE_INFO message received---") ); + } + else + { + DEBUG_LOG( _L("---ISAKMP_EXCHANGE_TRANSACTION message received---") ); + } +#endif + TBool inactive = EFalse; + if ( !negotiation ) + { + if ( exchange == ISAKMP_EXCHANGE_INFO ) + { + sa = FindIkev1SAData( aIkeMsg.GetCookieI(), + aIkeMsg.GetCookieR() ); + if ( sa ) + { + negotiation = CIkev1Negotiation::NewL( this, + iPFKeySocketIf, + iDebug, + sa, + RESPONDER ); + } + } + if ( !negotiation ) + { + DEBUG_LOG( _L("Cannot find a matching negotiation") ); +#ifdef _DEBUG + const TPtrC8 ikeMsgPtr( (TUint8 *)&aIkeMsg, (TUint16)aIkeMsg.GetLength() ); + TInetAddr dstAddr; + GetLocalAddress( dstAddr ); + dstAddr.SetPort( aLocalPort ); + TRACE_MSG_IKEV1( ikeMsgPtr, aSrcAddr, dstAddr ); +#endif // _DEBUG + return; //Not found + } + CleanupStack::PushL( negotiation ); + inactive = ETrue; //Not enqueued because not active. Only used to process the packet + } + + if ( exchange == ISAKMP_EXCHANGE_INFO ) + { + CIkev1InfoNegotiation* info_neg = new (ELeave) CIkev1InfoNegotiation( *this, + *negotiation, + iDebug ); + CleanupStack::PushL( info_neg ); + // Update the negotiation state + info_neg->ExecuteL( aIkeMsg, + aSrcAddr, + aLocalPort ); + CleanupStack::PopAndDestroy( info_neg ); + + if ( inactive ) + { + CleanupStack::PopAndDestroy( negotiation ); + } + else + { + if ( negotiation->Finished() ) + { + DeleteNegotiation( negotiation ); + } + } + } + else + { + // + // An ISAKMP transaction exchange message received + // The handling of this requires that there exists a + // CTransNegotiation object pointer linked into current + // CIkev1Negotiation object + // + if ( negotiation ) + { + if ( negotiation->ExecuteTransactionL( aIkeMsg, + aSrcAddr, + aLocalPort ) ) + { + if ( negotiation->Finished() ) + { + DeleteNegotiation( negotiation ); + } + } + else + { + DEBUG_LOG( _L("Unexpected Transaction excange message") ); +#ifdef _DEBUG + const TPtrC8 ikeMsgPtr( (TUint8 *)&aIkeMsg, (TUint16)aIkeMsg.GetLength() ); + TInetAddr dstAddr; + GetLocalAddress( dstAddr ); + dstAddr.SetPort( aLocalPort ); + TRACE_MSG_IKEV1( ikeMsgPtr, aSrcAddr, dstAddr ); +#endif // _DEBUG + } + } + } + return; + } + + // + // IKE Main, Aggressive and Quick mode exchanges + // + if ( negotiation ) + { + negotiation->ExecuteL( aIkeMsg, aSrcAddr, aLocalPort ); + if ( negotiation->Finished() ) + { + DeleteNegotiation( negotiation ); + } + return; + } + DEBUG_LOG( _L("No active negotiation found...Searching existing PHASE_II") ); + + TBool status; + sa = FindIkev1SAData( aIkeMsg.GetCookieI(), + aIkeMsg.GetCookieR() ); + if ( sa ) + { + DEBUG_LOG( _L("Creating a NEW IKE Phase 2 Negotiation") ); + + TRAPD( err, negotiation = CIkev1Negotiation::NewL( this, + iPFKeySocketIf, + iDebug, + sa, + RESPONDER ) ); + if ( err == KErrNone ) + { + CleanupStack::PushL( negotiation ); + status = negotiation->ExecutePhase2L( aIkeMsg, aSrcAddr, aLocalPort ); + if ( status && !negotiation->Finished() ) + { + //Negotiation OK + CleanupStack::Pop(); //negotiation safe + return; + } + CleanupStack::PopAndDestroy(); + } + return; + } + else + { + TCookie NULL_COOKIE; + NULL_COOKIE.FillZ(ISAKMP_COOKIE_SIZE); + if ( aIkeMsg.GetCookieR() == NULL_COOKIE ) + { + // + // This is the initial opening message from a remote host + // Start a new negotiation + // + DEBUG_LOG( _L("Creating a NEW IKE Phase 1 Negotiation") ); + TRAPD( err, negotiation = CIkev1Negotiation::NewL( this, + iPFKeySocketIf, + iDebug, + aSrcAddr, + aIkeMsg.GetCookieI(), + EFalse ) ); + + if ( err == KErrNone ) + { + CleanupStack::PushL( negotiation ); + status = negotiation->ExecuteL( aIkeMsg, aSrcAddr, aLocalPort ); + if ( status && !negotiation->Finished() ) + { + //Negotiation OK + CleanupStack::Pop(); //negotiation safe + return; + } + CleanupStack::PopAndDestroy( negotiation ); + } + return; + } + } + + if ( !negotiation ) + { + DEBUG_LOG( _L("Cannot find a matching negotiation") ); +#ifdef _DEBUG + const TPtrC8 ikeMsgPtr((TUint8 *)&aIkeMsg, (TUint16)aIkeMsg.GetLength()); + TInetAddr dstAddr; + GetLocalAddress( dstAddr ); + dstAddr.SetPort( aLocalPort ); + TRACE_MSG_IKEV1( ikeMsgPtr, aSrcAddr, dstAddr ); +#endif // _DEBUG + return; + } + } + +// --------------------------------------------------------------------------- +// From class MIkev1ReceiverCallback +// Handles notification about receive error. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::ReceiveError( TInt aError ) + { + HandleError( aError ); + } + +// --------------------------------------------------------------------------- +// Requests sending of UDP data. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::DoSendUdpDataL( HBufC8* aUdpData, + const TInetAddr& aDestAddr, + TInt aLocalPort, + TUint8 aDscp ) + { + if ( !iSender->IsActive() && + iSendQueue.Count() == 0 ) + { + // Sending is not in progress and send queue is empty. + // Start sending UDP data. + DoSendUdpData( aUdpData, + aDestAddr, + aLocalPort, + aDscp ); + } + else + { + // Store buffer into send queue for later sending. + TIkeSendQueueItem item = TIkeSendQueueItem( aUdpData, + aDestAddr, + aLocalPort, + aDscp ); + iSendQueue.Append( item ); + } + } + +// --------------------------------------------------------------------------- +// Sends UDP data. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::DoSendUdpData( HBufC8* aUdpData, + const TInetAddr& aDestAddr, + TInt aLocalPort, + TUint8 aDscp ) + { + __ASSERT_DEBUG( aUdpData != NULL, + User::Invariant() ); + + iSender->SendUdpData( aUdpData, aDestAddr, aLocalPort, aDscp ); + } + +// --------------------------------------------------------------------------- +// Handles PFKEY message. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::DoPfkeyMessageReceivedL( const TPfkeyMessage& aPfkeyMessage ) + { + // + // Process received PFKEY message according to message type + // +#ifdef _DEBUG + TBuf<40> txt_addr; +#endif + + TIkev1SAData* ikev1SAdata = NULL; + CIkev1Negotiation* negotiation = NULL; + + switch ( aPfkeyMessage.iBase.iMsg->sadb_msg_type ) + { + case SADB_ACQUIRE: + // + // A request to negotiate an IPSEC SA received + // Try to find an existing IKE SA with remote address + // +#ifdef _DEBUG + aPfkeyMessage.iDstAddr.Address().OutputWithScope( txt_addr ); +#endif + ikev1SAdata = FindIkev1SADataWithAddr( aPfkeyMessage.iDstAddr.Address() ); + if ( ikev1SAdata ) + { + // + // An IKE SA found for Acquire. Get a negotiation + // object for IKE Quick mode SA exchange + // + negotiation = CIkev1Negotiation::NewL( this, + iPFKeySocketIf, + iDebug, + ikev1SAdata, + INITIATOR, + &aPfkeyMessage ); + CleanupStack::PushL( negotiation ); + negotiation->InitPhase2L(); //Because is initiator + DEBUG_LOG1( _L("IKEv1 SA found for Acquire IP: %S"), &txt_addr ); + CleanupStack::Pop(); + } + else + { + // + // No IKE SA found for Acquire. + // + // If rekeying is in progress, IKE Quick mode SA exchange + // is started after Phase I has completed. + // + CIkev1Negotiation* negotiation = iFirstNegotiation; + while ( negotiation != NULL ) + { + if ( negotiation->IsRekeyingIkeSa() ) + { + break; + } + negotiation = negotiation->iNext; + } + if ( negotiation != NULL ) + { + negotiation->PreparePhase2L( aPfkeyMessage ); + DEBUG_LOG1( _L("Negotiation found for Acquire IP: %S"), &txt_addr ); + break; + } + + // + // Otherwise we shall start a new IKE SA negotiation to + // defined destination address. + // + negotiation = CIkev1Negotiation::NewL( this, + iPFKeySocketIf, + iDebug, + (TInetAddr&)aPfkeyMessage.iDstAddr.Address(), + aPfkeyMessage ); + CleanupStack::PushL( negotiation ); + negotiation->InitNegotiationL(); + if ( negotiation->Finished() ) + { + CleanupStack::PopAndDestroy(); + } + else + { + CleanupStack::Pop(); + } + DEBUG_LOG1( _L("Negotiate a new IKE SA for Acquire IP: %S"), &txt_addr ); + } + break; + + case SADB_EXPIRE: + // + // An IPSEC SA has been expired. + // Try to find an existing IKE SA with source address + // (= inbound SA destination address) + // +#ifdef _DEBUG + aPfkeyMessage.iDstAddr.Address().OutputWithScope( txt_addr ); +#endif + ikev1SAdata = FindIkev1SAData( aPfkeyMessage.iSrcAddr.Address(), + aPfkeyMessage.iSa.iExt->sadb_sa_spi ); + if ( ikev1SAdata ) + { + // + // An IKE SA found for Expire. Get a negotiation + // object for IKE Informational exchange + // + if ( DeleteIpsecSpi(ikev1SAdata->iSAId, + aPfkeyMessage.iSa.iExt->sadb_sa_spi, + ETrue) ) + { + negotiation = CIkev1Negotiation::NewL( this, + iPFKeySocketIf, + iDebug, + ikev1SAdata, + RESPONDER ); + CleanupStack::PushL( negotiation ); + negotiation->SendDeleteL( aPfkeyMessage.iBase.iMsg->sadb_msg_satype, + aPfkeyMessage.iSa.iExt->sadb_sa_spi ); + CleanupStack::PopAndDestroy(); + DEBUG_LOG3(_L("Notifying SGW, IPsec SA Expiration (addr = %S, spi = %x , proto = %d)"), &txt_addr, + ByteOrder::Swap32(aPfkeyMessage.iSa.iExt->sadb_sa_spi), aPfkeyMessage.iDstAddr.iExt->sadb_address_proto); + } + } + else + { + DEBUG_LOG1( _L("No IKE SA found Expire IP: %S"), &txt_addr ); + } + break; + + default: + break; + + } + } + +// --------------------------------------------------------------------------- +// Deletes IKE SAs. +// --------------------------------------------------------------------------- +// +TBool CIkev1PluginSession::DeleteSAsWithHost( TBool aSilentClose ) + { + DEBUG_LOG( _L("Deactivating IKEv1 SA:s") ); + + // + // For sure check if there is any ongoing negotiations for this + // and delete these negotiations immediatelly. + // + while ( iFirstNegotiation ) + { + CIkev1Negotiation* negotiation = iFirstNegotiation; + iFirstNegotiation = negotiation->iNext; + delete negotiation; + } + + TInt deactivatingStarted( EFalse ); + for ( TInt i=0;iIsExpired() ) + { + TIkev1SAData& ikeSaData = sa->iHdr; + deactivatingStarted = DeleteIkeSA( &ikeSaData, aSilentClose ); + } + } + + return deactivatingStarted; + } + +// --------------------------------------------------------------------------- +// Handles starting of negotiation with a peer. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::DoNegotiateWithHostL( const CIkeData& aIkeData ) + { + __ASSERT_DEBUG( iIkeData == NULL, + User::Invariant() ); + + iIkeData = CIkeData::NewL( &aIkeData ); + + // Start ISAKMP Phase 1 negotiation to the specified gateway immediately + // if the Internal VPN address feature is enabled in policy (= IA payload + // or CONFIG-MODE). Otherwise postpone negotiation. + if ( !aIkeData.iUseInternalAddr && + !aIkeData.iUseCfgMode ) + { + DEBUG_LOG(_L("Negotiation postponed.")); + User::RequestComplete( iClientStatusNegotiate, KErrNone ); + iClientStatusNegotiate = NULL; + return; + } + + CIkev1Negotiation* negotiation = CIkev1Negotiation::NewL( this, + iPFKeySocketIf, + iDebug, + iIkeData->iAddr, + ETrue ); + CleanupStack::PushL( negotiation ); + negotiation->InitNegotiationL(); + if ( negotiation->Finished() ) + { + CleanupStack::PopAndDestroy( negotiation ); + User::Leave( KKmdIkeNegotFailed ); + } + else + { + CleanupStack::Pop( negotiation ); + } + } + +// --------------------------------------------------------------------------- +// Handles fatal error. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::DoHandleError( TInt aError ) + { + DEBUG_LOG1(_L("CIkev1PluginSession::DoHandleError, err=%d"), aError); + + while ( iFirstNegotiation ) + { + CIkev1Negotiation* negotiation = iFirstNegotiation; + iFirstNegotiation = negotiation->iNext; + delete negotiation; + } + + while ( iIkev1SAs.Count() ) + { + CIkev1SA* ikev1SA = iIkev1SAs[0]; + iIkev1SAs.Remove(0); + delete ikev1SA; + } + + // Complete client's requests. + DoCompleteNegotiateWithHost( aError ); + DoCompleteDeleteSession( aError ); + DoCompleteNotifyError( aError ); + } + +// --------------------------------------------------------------------------- +// Handles completion of client's negotiate request. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::DoCompleteNegotiateWithHost( TInt aStatus ) + { + if ( iClientStatusNegotiate != NULL ) + { + if ( aStatus == KErrNone ) + { + if ( iInternalAddress != NULL ) + { + __ASSERT_DEBUG( iIkeData != NULL, + User::Invariant() ); + // Build internal address for client. + VPNAddrInfo::BuildVPNAddrInfo( iInternalAddress, + iIkeData->iDnsServer, + *iClientIaNegotiate, + iDebug ); + } + } + + // Complete client's request. + DEBUG_LOG1(_L("CIkev1PluginSession::DoCompleteNegotiateWithHost, aStatus=%d"), + aStatus); + User::RequestComplete( iClientStatusNegotiate, aStatus ); + iClientStatusNegotiate = NULL; + iClientIaNegotiate = NULL; + } + } + +// --------------------------------------------------------------------------- +// Handles completion of client's delete session request. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::DoCompleteDeleteSession( TInt aStatus ) + { + if ( iClientStatusDelete != NULL ) + { + DoCancelDataTransfer(); + + DEBUG_LOG1(_L("CIkev1PluginSession::DoCompleteDeleteSession, aStatus=%d"), + aStatus); + User::RequestComplete( iClientStatusDelete, aStatus ); + iClientStatusDelete = NULL; + } + } + +// --------------------------------------------------------------------------- +// Handles completion of client's notify error request. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::DoCompleteNotifyError( TInt aStatus ) + { + if ( iClientStatusNotifyError != NULL ) + { + DoCancelDataTransfer(); + + DEBUG_LOG1(_L("CIkev1PluginSession::DoCompleteNotifyError, aStatus=%d"), + aStatus); + User::RequestComplete( iClientStatusNotifyError, aStatus ); + iClientStatusNotifyError = NULL; + } + } + +// --------------------------------------------------------------------------- +// Handles completion of client's notify internal address change request. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::DoCompleteInternalAddressChanged( TInt aStatus ) + { + if ( iClientStatusNotifyIaChange != NULL ) + { + DEBUG_LOG1(_L("CIkev1PluginSession::DoCompleteInternalAddressChange, aStatus=%d"), + aStatus); + + if ( aStatus == KErrNone ) + { + if ( iInternalAddress != NULL ) + { + // Build internal address for client. + VPNAddrInfo::BuildVPNAddrInfo( iInternalAddress, + iIkeData->iDnsServer, + *iClientIaNotify, + iDebug ); + } + } + + if ( aStatus != KErrNone && + aStatus != KErrCancel ) + { + HandleError( aStatus); + return; + } + + User::RequestComplete( iClientStatusNotifyIaChange, aStatus ); + iClientStatusNotifyIaChange = NULL; + iClientIaNotify = NULL; + } + } + +// --------------------------------------------------------------------------- +// Cancels data transfer. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::DoCancelDataTransfer() + { + iReceiver->Cancel(); + iDataInterface.StopReceive(); + DoEmptySendQueue(); + iSender->Cancel(); + } + +// --------------------------------------------------------------------------- +// Empties send queue. +// --------------------------------------------------------------------------- +// +void CIkev1PluginSession::DoEmptySendQueue() + { + while ( iSendQueue.Count() ) + { + TIkeSendQueueItem item = iSendQueue[0]; + HBufC8* udpData = item.UdpData(); + iSendQueue.Remove(0); + delete udpData; + udpData = NULL; + } + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1private.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1private.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,550 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This module contains the private vendor specific extension of IKE. +* All of the current private extensions are related to Nokia VPN gateway +* and shall be used ONLY when the EPOC IKE is acting as a Nokia VPN remote +* access client. +* The following private extension are implemented: +* +* 1) Internal Address payload usage +* Internal address payload is used to the deliver a secure network +* adderess and secure network DNS address(es) from VPN gateway to a client. +* The Internal address payloads are used in the last two IKE main mode +* messages as follows: +* +* Client (initiator) Gateway (responder) +* .. SA, KE ... ---> +* <--- ..SA, KE ... +* HDR*, INT_ADDR ---> +* <--- HDR*, INT_ADDR +* +* Client sends an INT_ADDR payload with PRI_INTERNAL_ADDRESS attribute +* Attribute value is 0.0.0.0. +* +* Gateway responds with an INT_ADDR payload with PRI_INTERNAL_ADDRESS +* attribute containing client internal address x.y.z.w +* Gateway INT_ADDR payload may also contain attributes PRI_INTERNAL_DNS and +* PRI_INTERNAL_WINS. PRI_INTERNAL_DNS contains a list of DNS IP addresses and +* PRI_INTERNAL_WINS a list of WINS IP addresses. +* +* +* 2) The NAT Traversal probing +* The expanded Vendor-Id payload usage for the NAT Traversal probing. +* The expanded Vendor-Id payloads contains the following information: +* +* Client (initiator) Gateway (responder) +* VID(hash, ip_addr, port) ---> +* <--- VID(hash, detected_ip_addr, +* detected_port) +* +* Client sends a expanded Vendor-Id payload containing the following information: +* hash = Nokia VPN vendor specific hash data (used to recognize peer) +* ip_addr = Client IKE own IP address +* port = Client IKE own port (=500) +* +* Gateway responds with expanded Vendor-Id payload containing the following information: +* hash = Nokia VPN vendor specific hash data (used to recognize peer) +* detected_ip_addr = Client IP address as detected in received IKE message +* IP header (=source IP address) +* detected_port = Client port as detected in received IKE message +* UDP header (=source port) +* +* Both client and gateway do the following examination +* if ( ip_addr != detected_ip_addr ) || ( port != detected_port ) +* then NAT Traversal shall be used IPSEC ESP traffic between +* the client and gateway +* +* Nokia VPN specific NAT Traversal means that IPSEC ESP traffic shall be +* capsulated with UDP header. +* The used UDP port for that purpose is 9872 +* +*/ + +#include "ikev1private.h" +#include "ikev1dialog.h" +#include "ikev1negotiation.h" +#include "ikev1isakmpstream.h" + +#include "ikepolparser.h" + +const TUint8 BASE_VID_DATA[16] = {0x06, 0x3d, 0xf4, 0x13, 0x91, 0xa9, 0x19, 0xa2, + 0x5a, 0x61, 0xa8, 0x7c, 0x45, 0x02, 0x5f, 0xaf}; + +const TUint8 DPD_VID_DATA[16] = {0xAF, 0xCA, 0xD7, 0x13, 0x68, 0xA1, 0xF1, 0xC9, + 0x6B, 0x86, 0x96, 0xFC, 0x77, 0x57, 0x01, 0x00}; + +TInt BuildVendorIdHash(TUint8 *aICOOKIE, TUint8 *aRCOOKIE, TUint8 *hash_data) +{ +/*-------------------------------------------------------------------------------- + * + * Build Vendor Id hash data + * + *------------------------------------------------------------------------*/ +// +// base = MD5("Network Alchemy, Inc., Version 1.0"); /* ASCII-Z end null included) +// +TInt i; + + Mem::Copy(hash_data, &BASE_VID_DATA[0], 16); /* Hash base (MD5) */ + + for ( i = 0; i < (ISAKMP_COOKIE_SIZE * 2); i++ ) { + + if ( i < ISAKMP_COOKIE_SIZE ) + *(hash_data + i) ^= *(aICOOKIE + i); + else *(hash_data + i) ^= *(aRCOOKIE + (i - ISAKMP_COOKIE_SIZE)); + + } + + return 16; +} + + +TInt ConstructVendorId(TBool aNATProbe, + TUint8 *aICOOKIE, + TUint8 *aRCOOKIE, + TInetAddr &aLocalAddr, + TVendorISAKMP *aVendorPayload) +{ +/*------------------------------------------------------------------------ + * + * This method constructs a Vendor ID payload. If aNATProbe is TRUE + * an expanded format Vendor ID is constructed. + * Both Vendor ID formats contains a Nokia VPN vendor specific hash data + * which constructed as follows: + * base = MD5("Network Alchemy, Inc., Version 1.0"); ASCII-Z end null included) + * base = BASE_VID_DATA; + * Then the Vendor ID hash is consructed xor:ing ISAKMP cookies to hash as follows: + * + * for ( i = 0; i < (ISAKMP_COOKIE_SIZE * 2); i++ ) { + * if ( i < ISAKMP_COOKIE_SIZE ) + * base[i] ^= ICOOKIE[i]; + * else base[i] ^= RCOOKIE[i - ISAKMP_COOKIE_SIZE]; + * } + * + * The expanded vendor ID payload looks like so: + * + * General payload header (next payload is "real" next payload) + * General payload header (next payload is "VENDOR_OPTION_NAT_TRAVERSAL") + * option hash + * General payload header (next payload is "VENDOR_OPTION_VERSION") + * option VENDOR_OPTION_NAT_TRAVERSAL + * General payload header (next payload is "NULL") + * option VENDOR_OPTION_VERSION + * + * Expanded vendor id format is format is as follows: + * + * 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! Next Payload ! RESERVED ! Payload Length = 44 ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! OPTION_NAT_T ! RESERVED ! Hash_lth + 4 = 20 ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! Nokia VPN Vendor specific hash ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! OPTION_VERSION! RESERVED ! OPTION_NAT_T_LTH + 4 = 20 ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! sin_lth ! sin_family ! sin_port ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! sin_addr ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! ! + * . Zero * 2(?) . + * ! ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! 0 ! RESERVED ! OPTION_VERSION + 4 = 8 ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! MAJOR VERSION ! MINOR VERSION ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * + *------------------------------------------------------------------------*/ + TVendorISAKMP *nat_vendor_id; + TVendorISAKMP *ver_vendor_id; + TNATTOption *nat_t_option; + TVersionOption *version_option; + TUint8 *next_payload; + TUint32 vid_lth; + TInetAddr own_addr = aLocalAddr; + + next_payload = (TUint8 *)aVendorPayload; + *next_payload = ISAKMP_PAYLOAD_NONE; /* zeroe next payload field for sure */ + + if ( aNATProbe ) { + /*------------------------------------------------------------ + * + * Build expanded Vendor Id payload + * Build first VENDOR_OPTION_NAT_TRAVERSAL payload + * + *-----------------------------------------------------------*/ + nat_vendor_id = (TVendorISAKMP*)((TUint8*)aVendorPayload + + sizeof(TPayloadISAKMP) + + sizeof(TPayloadISAKMP) + 16); //bypass hash + next_payload = (TUint8 *)nat_vendor_id; + *next_payload = VENDOR_OPTION_VERSION; + nat_vendor_id->SetReserved(0); + nat_vendor_id->SetLength(sizeof(TPayloadISAKMP) + SIN_LTH); + nat_t_option = (TNATTOption*)nat_vendor_id->VIDData(); + nat_t_option->InitOption(); + nat_t_option->SetPort(500); + if ( own_addr.IsV4Mapped() ) + own_addr.ConvertToV4(); + nat_t_option->SetAddress(own_addr.Address()); + /*------------------------------------------------------------ + * + * Build next VENDOR_OPTION_VERSION payload + * Set major version X and minor Y. + * + *-----------------------------------------------------------*/ + ver_vendor_id = (TVendorISAKMP*)((TUint8*)nat_vendor_id + + sizeof(TPayloadISAKMP) + SIN_LTH); //bypass NAT-T + next_payload = (TUint8 *)ver_vendor_id; + *next_payload = ISAKMP_PAYLOAD_NONE; + ver_vendor_id->SetReserved(0); + ver_vendor_id->SetLength(sizeof(TPayloadISAKMP) + VERSION_LTH); + version_option = (TVersionOption*)ver_vendor_id->VIDData(); + version_option->SetVersion(MAJOR_VERSION, MINOR_VERSION); + + /*------------------------------------------------------------ + * + * Build "upper" Vendor Id payload general header + * + *-----------------------------------------------------------*/ + vid_lth = sizeof(TPayloadISAKMP) + /* "outer" Vendor ID payload */ + sizeof(TPayloadISAKMP) + 16 + /* VENDOR_OPTION_HASH */ + sizeof(TPayloadISAKMP) + SIN_LTH + /* VENDOR_OPTION_NAT_TRAVERSAL */ + sizeof(TPayloadISAKMP) + VERSION_LTH;/* VENDOR_OPTION_VERSION */ + aVendorPayload->SetLength((TUint16)vid_lth); + aVendorPayload->SetReserved(0); + + aVendorPayload = (TVendorISAKMP*)((TUint8*)aVendorPayload + sizeof(TPayloadISAKMP)); + next_payload = (TUint8 *)aVendorPayload; + *next_payload = VENDOR_OPTION_NAT_TRAVERSAL; + } + else { + vid_lth = sizeof(TPayloadISAKMP) + 16; + } + /*------------------------------------------------------------ + * + * Store Hash data into Vendor Id payload + * + *-----------------------------------------------------------*/ + aVendorPayload->SetReserved(0); + aVendorPayload->SetLength((TUint16)sizeof(TPayloadISAKMP) + 16); + + BuildVendorIdHash(aICOOKIE, aRCOOKIE, + aVendorPayload->VIDData()); + + return vid_lth; + +} + + +TBool ProcessVendorId(TBool *aFamiliarPeer, + TUint8 *aICOOKIE, + TUint8 *aRCOOKIE, + TInetAddr &aLocalAddr, + TVendorISAKMP *aVendorPayload) +{ +/*------------------------------------------------------------------------- + * + * Process Vendor Id payload received from peer. + * The following actions taken: + * -- Check if a Nokia VPN implementation i peer (recognize hash in Vendor Id) + * -- If Nokia VPN implementation detected process possible + * VENDOR_OPTION_NAT_TRAVERSAL in expanded Vendor Id payload + * + *------------------------------------------------------------------------*/ + TBool nokia_vpn_peer = EFalse; + TBool nat_t_required = EFalse; + TVendorISAKMP *option_payload; + TNATTOption *nat_t_option; + TInt vid_lth; + TInt tmp_lth; + TInt hash_lth; + TUint16 ptype; + TUint16 detected_port; + TUint8 ref_hash[20]; + TInetAddr detected_addr; + TInetAddr reference_addr = aLocalAddr; + + vid_lth = aVendorPayload->GetLength() - sizeof(TPayloadISAKMP); + if ( vid_lth > 15 ) { + /*------------------------------------------------------- + * + * Check if expanded Vendor Id format + * + *-------------------------------------------------------*/ + tmp_lth = vid_lth; + ptype = ISAKMP_PAYLOAD_NONE; + hash_lth = BuildVendorIdHash(aICOOKIE, aRCOOKIE, ref_hash); + option_payload = aVendorPayload; + if ( vid_lth > hash_lth ) { + /*--------------------------------------------------------------------- + * + * An expanded format Vendor Id, bypass "outer" payload general header + * And do sanity check for VENDOR_OPTION_HASH option payload + * + *--------------------------------------------------------------------*/ + option_payload = (TVendorISAKMP*)((TUint8*)option_payload + sizeof(TPayloadISAKMP)); + ptype = option_payload->GetPayload(); + tmp_lth = option_payload->GetLength(); + if ( tmp_lth == (sizeof(TPayloadISAKMP) + 16 ) ) +// && +// ( option_payload->GetReserved() == 0 ) ) { //Must be always 0 + tmp_lth -= sizeof(TPayloadISAKMP); + else tmp_lth = 0; + } + + if ( tmp_lth == hash_lth ) { + /*--------------------------------------------- + * + * Check that Vendor Id hash match + * + *---------------------------------------------*/ + if ( Mem::Compare(option_payload->VIDData(), tmp_lth, ref_hash, hash_lth) == 0 ) { + /*----------------------------------------------------------- + * + * Process other Vendor Id option payload(s) + * In this phase only VENDOR_OPTION_NAT_TRAVERSAL is processed + * other options are ignored + * + *-----------------------------------------------------------*/ + nokia_vpn_peer = ETrue; + tmp_lth += sizeof(TPayloadISAKMP); + option_payload = (TVendorISAKMP*)((TUint8*)option_payload + tmp_lth); + + while ( ptype != ISAKMP_PAYLOAD_NONE ) { + + if ( vid_lth <= tmp_lth ) { + break; + } + hash_lth = option_payload->GetLength(); + tmp_lth += hash_lth; + if ( ( hash_lth < (MIN_ISAKMP_PAYLOAD_SIZE + SIN_LTH) ) ) { +// && +// ( option_payload->GetReserved() != 0 ) ) } //Must be always 0 + break; + } + if ( ptype == VENDOR_OPTION_NAT_TRAVERSAL ) { + if ( reference_addr.IsV4Mapped() ) + reference_addr.ConvertToV4(); + hash_lth -= sizeof(TPayloadISAKMP); /* option data length */ + nat_t_option = (TNATTOption*)((TUint8*)option_payload + sizeof(TPayloadISAKMP)); + detected_port = nat_t_option->GetPort(); + detected_addr.SetAddress(nat_t_option->GetAddress()); + if ( (detected_port != 500) /* Port changed */ + || + !(detected_addr.Match(reference_addr))) { /* address changed */ + nat_t_required = ETrue; + } + break; + } + + ptype = option_payload->GetPayload(); //Next payload + option_payload = (TVendorISAKMP*)((TUint8*)option_payload + hash_lth); + + } + } + } + + } + + if ( aFamiliarPeer ) + *aFamiliarPeer = nokia_vpn_peer; + + return nat_t_required; + +} + +/**------------------------------------------------------------------- + * + * Function BuildDPDVendorId() + * This method builds a Dead Peer Detection (DPD) related Vendor ID + * payload and adds it into the IKE message. The vendor id is + * specified in the draft and its + * content is the following: + * 1 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! !M!M! + * ! HASHED_VENDOR_ID !J!N! + * ! !R!R! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Hash data is, + * {0xAF, 0xCA, 0xD7, 0x13, 0x68, 0xA1, 0xF1, 0xC9, 0x6B, 0x86, 0x96, + * 0xFC, 0x77, 0x57}, and MJR and MNR + * MJR = 1 and MNR = 0 + * + *--------------------------------------------------------------------*/ +void BuildDPDVendorId(TIkev1IsakmpStream &aMsg) +{ + TInetAddr DummyAddr; + + aMsg.IsakmpVendorId(IETF_NATT_VENDOR_ID, + NULL, NULL, DummyAddr, // These parameters has no relevance with IETF_NATT_VID_DATA + (TUint8*)DPD_VID_DATA, + sizeof(DPD_VID_DATA)); +} + +TBool CheckDPDVendorId(const TVendorISAKMP *aVendorPayload) +{ +/**--------------------------------------------------------------------------------------- + * + * This method checks does the remote end support DPD draft + * + *---------------------------------------------------------------------------------------*/ + TInt vid_lth = aVendorPayload->GetLength() - sizeof(TPayloadISAKMP); + if ( vid_lth == sizeof(DPD_VID_DATA) ) + { + if ( Mem::Compare(aVendorPayload->VIDData(), vid_lth, (TUint8*)DPD_VID_DATA, vid_lth) == 0 ) + return ETrue; // Remote end supports DPD draft + } + return EFalse; +} + +TInt CheckCredentials(CIkeData *aHostData ) +{ +/*------------------------------------------------------------------------- + * + * This function is called by CNegotiation::InitNegotiationL() method + * when the current IKE proposal defines aggresssive mode exchange with + * pre-shared key authentication. + * The following special actions are taken: + * -- If no pre-shared key data is defined, launch a dialog where + * user name and password information is asked from the user. + * -- User name information is store to current CIkeData iFQDN field + * (represent IKE identification) + * -- Password data shall be stored to current CIkeData iPresharedKey field + * + * This functionality is related to Checkpoint gateway. + * To use Aggressive mode exchange and pre-shared key authentication like + * this implement kind of "legacy authentication method" for IKE where + * client (=initiator) authentication is based on user name/password pair. + * User name is sent from initiator (=client) to responder (=Checkpoint GW) + * in the IKE ID payload. However, the password data is NOT transmitted in + * any payload, but it is used as pre-shared key in both ends. + * (= Checkpoint gateway shall use user name data received in IKE ID payload + * as a reference to the correct pre-shared key) + * + *------------------------------------------------------------------------*/ + if ( !aHostData || aHostData->iPresharedKey.iKey.Length() ) + return KErrNone; + + aHostData->iPresharedKey.iFormat = STRING_KEY; + aHostData->iFQDN.SetLength(0); // Override FQDN in host data with user name + + return CIkev1Dialog::GetSyncUNPWDialog(aHostData->iFQDN, aHostData->iPresharedKey.iKey); +} + + +CInternalAddress* ProcessIntNetL(TINTNETISAKMP *aIntNetpayload) +{ +/*------------------------------------------------------------------------- + * + * Process Internal address payload received (sanity check already done) + * Process payload attributes as follows: + * -- Parse PRI_INTERNAL_ADDRESS attribute and store value to aInternalAddr + * -- Parse PRI_INTERNAL_DNS attributes and build list of DNS addresses + * There exists an own attribute for all DNS addresses + * -- Ignore other attributes (=PRI_INTERNAL_WINS) + * + * In this phase only IPv4 Internal addresses are supported by the + * Nokia VPN gateway + * + *------------------------------------------------------------------------*/ + TInt length = (TInt)aIntNetpayload->GetLength(); + if ( STATIC_CAST(TUint, length) < sizeof(TINTNETISAKMP) ) { + return NULL; + } + + length -= sizeof(TINTNETISAKMP); /* Attribute data lengt in payload */ + + TUint32 ipv4_addr; + TBool internal_address = EFalse; + TInetAddr *dns_addr; + CInternalAddress *InternalAddr = new (ELeave)CInternalAddress(1); + CleanupStack::PushL(InternalAddr); + TDataISAKMP *attr = aIntNetpayload->INTNETAttrib(); + + while ( length > 0 ) { + + length = length - attr->Size(); + if ( length < 0 ) { + CleanupStack::PopAndDestroy(); /* delete InternalAddr */ + return NULL; + } + switch ( attr->Type() ) { + + case PRI_INTERNAL_ADDRESS: + /*----------------------------------------------------------- + * Internal address received from gateway. If several + * Internal address attributes detected use the first address + *------------------------------------------------------------*/ + if ( attr->IsBasic() || ( attr->Length() != 4) ) { + CleanupStack::PopAndDestroy(); /* delete InternalAddr */ + return NULL; + } + if ( !internal_address ) { + internal_address = ETrue; + ipv4_addr = GET32(attr->VarValue()); + ipv4_addr = ByteOrder::Swap32(ipv4_addr); //NOT IN NETWORK ORDER !!!! + InternalAddr->iClientIntAddr.SetAddress(ipv4_addr); + } + break; + + case PRI_INTERNAL_DNS: + /*----------------------------------------------------------- + * Internal DNS address received from gateway + *------------------------------------------------------------*/ + if ( attr->IsBasic() || ( attr->Length() != 4 ) ) { + CleanupStack::PopAndDestroy(); /* delete InternalAddr */ + return NULL; + } + ipv4_addr = GET32(attr->VarValue()); + ipv4_addr = ByteOrder::Swap32(ipv4_addr); //NOT IN NETWORK ORDER !!!! + dns_addr = new(ELeave)TInetAddr; + CleanupStack::PushL(dns_addr); + dns_addr->SetAddress(ipv4_addr); + InternalAddr->AppendL(dns_addr); + CleanupStack::Pop(); /* delete dns_addr */ + break; + + default: + /*----------------------------------------------------------- + * Other attributes (WINS address) are ignored + *------------------------------------------------------------*/ + break; + } + + attr = attr->Next(); + } + + if ( !internal_address ) { + /*----------------------------------------------------- + * No client internal address defined. + * Internal address negotiation failed + *----------------------------------------------------*/ + delete InternalAddr; + InternalAddr = NULL; + } + + CleanupStack::Pop(); // Remove InternalAddr from cleanup stack + + return InternalAddr; +} + + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1receiver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1receiver.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,165 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Receiver of UDP datagrams +* +*/ + + +#include + +#include "ikedatainterface.h" +#include "ikemsgheader.h" + +// CLASS HEADER +#include "ikev1receiver.h" + + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CIkev1Receiver* CIkev1Receiver::NewL( MIkeDataInterface& aDataInterface, + MIkev1ReceiverCallback& aCallback ) + { + CIkev1Receiver* self = new (ELeave) CIkev1Receiver( aDataInterface, + aCallback ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CIkev1Receiver::~CIkev1Receiver() + { + Cancel(); + + delete iUdpData; + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CIkev1Receiver::CIkev1Receiver( MIkeDataInterface& aDataInterface, + MIkev1ReceiverCallback& aCallback ) + : CActive( EPriorityStandard ), + iUdpData( NULL ), + iDataInterface( aDataInterface ), + iCallback( aCallback ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CIkev1Receiver::ConstructL() + { + StartReceive(); + } + +// --------------------------------------------------------------------------- +// Starts receive. +// --------------------------------------------------------------------------- +// +void CIkev1Receiver::StartReceive() + { + DoReceive(); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles completion of receive. +// --------------------------------------------------------------------------- +// +void CIkev1Receiver::RunL() + { + if ( iStatus.Int() == KErrNone ) + { + __ASSERT_DEBUG( iUdpData != NULL, + User::Invariant() ); + + const ThdrISAKMP* ikeHdr = ThdrISAKMP::Ptr( iUdpData->Des() ); + TInt msgLth = iUdpData->Length(); + + // Ignore possible in the beginning of IKE message. + TUint32 ikeMsgHdrOctets = GET32( ikeHdr ); + if ( ikeMsgHdrOctets == NON_ESP_MARKER ) + { + ikeHdr = ikeHdr->GotoOffset( NON_ESP_MARKER_SIZE ); + msgLth -= NON_ESP_MARKER_SIZE; + } + + iCallback.IkeMsgReceivedL( *ikeHdr, iSrcAddr, iLocalPort ); + } + else + { + iCallback.ReceiveError( iStatus.Int() ); + } + + delete iUdpData; + iUdpData = NULL; + + if ( iStatus.Int() == KErrNone ) + { + // Continue receiving. + DoReceive(); + } + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles cancellation of receive. +// --------------------------------------------------------------------------- +// +void CIkev1Receiver::DoCancel() + { + iDataInterface.CancelReceive(); + + delete iUdpData; + iUdpData = NULL; + } + +// --------------------------------------------------------------------------- +// Handles a leave occurring in RunL(). +// Handles cancellation of receive. +// --------------------------------------------------------------------------- +// +TInt CIkev1Receiver::RunError( TInt aError ) + { + delete iUdpData; + iUdpData = NULL; + + iCallback.ReceiveError( aError ); + return KErrNone; + } + +// --------------------------------------------------------------------------- +// Receives UDP data. +// --------------------------------------------------------------------------- +// +void CIkev1Receiver::DoReceive() + { + iDataInterface.ReceiveUdpData( iUdpData, iSrcAddr, iLocalPort, iStatus ); + SetActive(); + } + + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1sa.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1sa.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,471 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv1 SA +* +*/ + + +#include "ikedebug.h" +#include "ikev1SA.h" +#include "ikev1SAdata.h" +#include "ikev1keepalive.h" +#include "ikev1nokianattkeepalive.h" // CIkev1NokiaNattKeepAlive +#include "ikepolparser.h" +#include "ikesocketdefs.h" +#include "ikev1pluginsession.h" + +CIkev1SA* CIkev1SA::NewL( CIkev1PluginSession& aPluginSession, + TIkev1SAData& aIkev1SAdata, + CSARekeyInfo* aSaRekey, + MIkeDebug& aDebug ) +{ + CIkev1SA *sa = new (ELeave) CIkev1SA( aPluginSession, aDebug ); + sa->ConstructL( aIkev1SAdata, aSaRekey ); + return sa; +} + + +//Constructor +CIkev1SA::CIkev1SA( CIkev1PluginSession& aPluginSession, + MIkeDebug& aDebug ) + : CTimer( EPriorityStandard ), + iPluginSession( aPluginSession ), + iDebug( aDebug ) +{ + CActiveScheduler::Add(this); +} + +void CIkev1SA::ConstructL(TIkev1SAData& aIkev1SAdata, CSARekeyInfo* aSaRekey) +{ + CTimer::ConstructL(); + iHdr.CopyL(aIkev1SAdata); + + if ( aSaRekey ) + { + // + // Rekeyed IKE SA. Try to find "original" IKE SA and move IPSEC + // SPI list from that SA to the new rekeyed one. + // If "original" IKE SA is found, (re)start expiration timer + // with rekey "left over" time. + // + iRekeyed = ETrue; + CIkev1SA *OrigSA = iPluginSession.FindIkev1SA(aSaRekey->GetCookieI(), aSaRekey->GetCookieR()); + if ( OrigSA ) + { + DEBUG_LOG(_L("ISAKMP SA Rekeyed, SPI list moved from original SA")); + iSPIList = OrigSA->iSPIList; + OrigSA->iSPIList = NULL; + OrigSA->iSPIList = new (ELeave) CIpsecSPIList(1); // Dummy + if ( OrigSA->IsActive() ) + { + OrigSA->Cancel(); + OrigSA->iRemainingTime = 0; + OrigSA->iLeftOverTime = 0; + DEBUG_LOG1(_L("Rekeyed SA expiration time set to %u"),OrigSA->iRemainingTime); + OrigSA->StartTimer(); + } + } + } + + if ( !iSPIList ) + iSPIList = new (ELeave) CIpsecSPIList(4); + + TInt DPDHeartbeat; + + if ( iHdr.iDPDSupported && iHdr.iIkeData->iDPDHeartBeat ) + DPDHeartbeat = iHdr.iIkeData->iDPDHeartBeat; + else DPDHeartbeat = 0; + + TInt KeepAliveTimeout = 0; + TInt port = IkeSocket::KIkePort500; + TUint32 NATKeepAlive = (iHdr.iNAT_D_Flags & LOCAL_END_NAT); + if ( NATKeepAlive || iHdr.iNAT_T_Required ) + { + KeepAliveTimeout = (TInt)iHdr.iIkeData->iNatKeepAlive; + if ( NATKeepAlive ) + { + port = IkeSocket::KIkePort4500; + if ( KeepAliveTimeout == 0 ) + KeepAliveTimeout = 120; // If not configured use 2 minutes + } + } + + if ( DPDHeartbeat || KeepAliveTimeout ) + { + iIkeKeepAlive = CIkeV1KeepAlive::NewL( iPluginSession, + port, + (TInetAddr&)iHdr.iDestinAddr, + KeepAliveTimeout, + DPDHeartbeat, + (MDpdHeartBeatEventHandler*)this ); + } + + // Nokia NAT-T needed + if (!NATKeepAlive && + iHdr.iNAT_T_Required && + (KeepAliveTimeout > 0) ) + { + // Start Nokia IPsec over NAT keepalive handler + TInetAddr addr = (TInetAddr)iHdr.iDestinAddr; + + // NAT-T default ESP UDP port + TInt port(KNokiaNattDefaultPort); + if (iHdr.iIkeData->iEspUdpPort) + port = iHdr.iIkeData->iEspUdpPort; + + iNokiaNatt = CIkev1NokiaNattKeepAlive::NewL( iPluginSession, + addr, + port, + KeepAliveTimeout, + iDebug ); + } + + if ( !iHdr.iVirtualIp && aSaRekey ) + { + // + // Rekeyed IKE SA. No virtual IP address received in IKE SA + // negotiation. Get "old" virtual IP address saved into + // CSARekeyInfo object (if any). + // + iHdr.StoreVirtualIp(aSaRekey->GetInternalAddr()); + } + + + //Lifetime in seconds + iRemainingTime = iHdr.iLifeTimeSecs; + if ( iRemainingTime == 0 ) + iRemainingTime = DEFAULT_MAX_ISAKMP_LIFETIME; + + // + // Check if IKE SA rekeying threshold value (per cent) defined + // If it is (value is between 70 - 95), use that per cent value + // as IKE SA timeout (Rekey for a new IKE SA is started then) + // "Left over" time is the expiration timeout for rekeyed IKE SA + // value which is used when rekey negotiation is started. + // The minimum value for that is set to 30 seconds + // + TInt RekeyThreshold = iHdr.iIkeData->iRekeyingThreshold; + if ( RekeyThreshold != 0 ) + { + if ( RekeyThreshold < 70 ) + RekeyThreshold = 70; + else if ( RekeyThreshold > 95 ) + RekeyThreshold = 95; + DEBUG_LOG1(_L("Negotiated ISAKMP Lifetime set to %u"),iRemainingTime); + iLeftOverTime = iRemainingTime - ((iRemainingTime/100.0) * RekeyThreshold); + iRemainingTime -= iLeftOverTime; + if ( iLeftOverTime < 30 ) + iLeftOverTime = 30; + } + + DEBUG_LOG1(_L("ISAKMP Lifetime set to %u"),iRemainingTime); + + //Lifetime in Kb + iRemainingKB = iHdr.iLifeTimeKB; + DEBUG_LOG1(_L("ISAKMP KB Lifetime set to %u"),iRemainingKB); + + StartTimer(); + +} + +//Destructor +CIkev1SA::~CIkev1SA() +{ + Cancel(); + + //Delete the IPSEC SAs as well if desired + if ( iHdr.iIkeData && iSPIList) + { + for (TInt i = 0; i < iSPIList->Count(); i++) + { + TIpsecSPI* spi_node = iSPIList->At(i); + iPluginSession.DeleteIpsecSA( spi_node->iSPI, + spi_node->iSrcAddr, + spi_node->iDstAddr, + spi_node->iProtocol ); + } + } + + iHdr.CleanUp(); + //Deletes the SPI List + delete iSPIList; + delete iIkeKeepAlive; + delete iNokiaNatt; +} + + +void CIkev1SA::SetExpired() +{ + DEBUG_LOG(_L("CIkev1SA::SetExpired")); + + if ( !iExpired ) //If already expired do nothing to avoid renewing the expiration timer. + { + DEBUG_LOG(_L("SA is still active. Expiring it...")); + + iExpired = ETrue; + //if ( iHdr.iIkeData->iIpsecExpires ) + //{ + //DEB(iEngine->PrintText(_L("iIpsecExpires is ETrue\n"));) + for (TInt i = 0; i < iSPIList->Count(); i++) + { + DEBUG_LOG(_L("Deleting IPsec SA")); + TIpsecSPI* spi_node = iSPIList->At(i); + iPluginSession.DeleteIpsecSA( spi_node->iSPI, + spi_node->iSrcAddr, + spi_node->iDstAddr, + spi_node->iProtocol ); + } + //} + Cancel(); //Cancel the current timer + After(ISAKMP_DELETE_TIME); + } +} + +void CIkev1SA::UpdateSAL(TBool aExpired, TIkev1SAData* aIkev1SAdata) +{ + DEBUG_LOG(_L("CIkev1SA::UpdateSAL")); + + if ( aExpired ) + { + ExpireSA(); + } + else + { + DEBUG_LOG(_L("Not expiring SA")); + if ( aIkev1SAdata ) + { + iHdr.CopyL(*aIkev1SAdata); + } + } +} + +void CIkev1SA::ExpireSA() + { + DEBUG_LOG(_L("Expiring SA")); + SetExpired(); + } + +void CIkev1SA::DoCancel() +{ + CTimer::DoCancel(); +} + +void CIkev1SA::RunL() +{ + + DEBUG_LOG(_L("CIkev1SA::RunL")); + if (!iExpired) //Still alive so that's a normal Lifetime Expiration + { + DEBUG_LOG(_L("Sa is not expired")); + + if (iRemainingTime > 0) //Timer still no finished + { + StartTimer(); + return; + } + + if ( iLeftOverTime ) + { + // + // Start IKE phase 1 rekey operation + // + iRemainingTime = iLeftOverTime; + iLeftOverTime = 0; + CSARekeyInfo* SARekeyInfo = CSARekeyInfo::NewL(iHdr.iCookie_I, iHdr.iCookie_R, iHdr.iVirtualIp); + + iHdr.iVirtualIp = NULL; //Exclusive ownership of the object moved to TSARekeyInfo + DEBUG_LOG(_L("Starting ISAKMP SA rekeying ")); + CleanupStack::PushL(SARekeyInfo); + iPluginSession.RekeyIkeSAL(&iHdr, SARekeyInfo); + CleanupStack::Pop(SARekeyInfo); + StartTimer(); + } + else + { + DEBUG_LOG(_L("**\n---ISAKMP SA Deleted---- Lifetime expired**")); + iPluginSession.DeleteIkeSA(&iHdr, EFalse); // "Normal" close + SetExpired(); + } + } + else + { //Expired must be erased Completely after the default waiting time + + DEBUG_LOG(_L("Deleting IKE Sa")); + iPluginSession.RemoveIkeSA( this, iStatus.Int() ); + } + +} + +TInt CIkev1SA::RunError(TInt aError) + { + DEBUG_LOG1(_L("CIkev1SA::RunError, err=%d"), aError); + iPluginSession.HandleError(aError); + return KErrNone; + } + +void CIkev1SA::StartTimer() +{ + if (iRemainingTime > KMaxTInt/SECOND) //To avoid overflowing the Timer + { + iRemainingTime -= KMaxTInt/SECOND; + After(KMaxTInt); + } + else //No overflow + { + After(iRemainingTime*SECOND); + iRemainingTime = 0; + } +} + +//Adds a new node to the List of SPIs to know the direction if it has to be deleted. +void CIkev1SA::AddIpsecSPIL(TIpsecSPI& aIpsecSpi) +{ + TIpsecSPI* spi_node = new (ELeave) TIpsecSPI; + CleanupStack::PushL(spi_node); + iSPIList->AppendL(spi_node); + CleanupStack::Pop(); + spi_node->iSrcAddr = aIpsecSpi.iSrcAddr; + spi_node->iDstAddr = aIpsecSpi.iDstAddr; + spi_node->iSPI = aIpsecSpi.iSPI; + spi_node->iProtocol = aIpsecSpi.iProtocol; + spi_node->iInbound = aIpsecSpi.iInbound; +} + +TBool CIkev1SA::FindIpsecSPI(TUint32 aSPI, TBool aInbound) +{ + TIpsecSPI *spi_node; + for (TInt i = 0; i < iSPIList->Count(); i++) + { + spi_node = iSPIList->At(i); + if ( (spi_node->iSPI == aSPI) && (spi_node->iInbound == aInbound) ) + { + return ETrue; + } + } + + return EFalse; +} + +// +//Deletes a TIpsecSPI matching aSPI +// +TBool CIkev1SA::DeleteIpsecSPI(TUint32 aSPI, TBool aInbound) +{ + TIpsecSPI *spi_node; + for (TInt i = 0; i < iSPIList->Count(); i++) + { + spi_node = iSPIList->At(i); + if ( (spi_node->iSPI == aSPI) && (spi_node->iInbound == aInbound) ) + { + delete spi_node; + iSPIList->Delete(i); + return ETrue; + } + } + + return EFalse; +} + +// +// Flush all Ipsec SA:s bound to this IKE SA from SADB and send Delete +// payload for all inbound SAs +// +void CIkev1SA::DeleteIpsecSAs() +{ + TIpsecSPI* spi_node; + TInt c = iSPIList->Count(); + for (TInt i = 0; i < c; i++) + { + spi_node = iSPIList->At(i); + if ( spi_node->iInbound ) + { + //Only the inbound ones notified to avoid receiving packets using an expired SA + //The opposite if receiving a Delete + DEBUG_LOG1(_L("Sending ISAKMP Delete payload for IPSec SPI %x"), + (int)ByteOrder::Swap32(spi_node->iSPI)); + + // Call to delete may fail (delete sends DELETE payloads, and the data connection + // may not be open anymore). This is non-fatal, however. + TRAPD(err, iPluginSession.DeleteIpsecSAL(&iHdr, spi_node)); + if (err == KErrNone) + { + // DELETE sent successfully + DEBUG_LOG(_L("CIkev1SA::DeleteIpsecSAsL() IPsec SA delete OK")); + } + else if (err == KErrNotFound) + { + // Non-fatal leave occured (couldn't send DELETE due to invalid connection) + // We can still continue purging IPSEC SAs. + DEBUG_LOG(_L("CIkev1SA::DeleteIpsecSAsL() IPsec SA delete failed due non-existing connection. Non-fatal, continuing")); + } + else + { + // Fatal leave (e.g. out of memory etc) + DEBUG_LOG(_L("CIkev1SA::DeleteIpsecSAsL() IPsec SA deletion error. Fatal.")); + iPluginSession.HandleError(err); + return; + } + } + iPluginSession.DeleteIpsecSA(spi_node->iSPI, spi_node->iSrcAddr, spi_node->iDstAddr, spi_node->iProtocol); + delete spi_node; + } + iSPIList->Reset(); //Empties the full list at once +} + +// +// void CIkev1SA::DeleteIpsecSAsForced() +// +void CIkev1SA::DeleteIpsecSAsForced() +{ + TIpsecSPI* spi_node; + TInt c = iSPIList->Count(); + for (TInt i = 0; i < c; i++) + { + spi_node = iSPIList->At(i); + iPluginSession.DeleteIpsecSA( spi_node->iSPI, + spi_node->iSrcAddr, + spi_node->iDstAddr, + spi_node->iProtocol ); + delete spi_node; + } + iSPIList->Reset(); +} + +void CIkev1SA::EventHandlerL() +{ + // + // The implementation for class MDpdHeartBeatEventHandler virtual function + // This method is called by an CIkeKeepAlive object instance when + // DPD heartbeat timeout has elapsed. + // + if ( !iExpired && iSPIList->Count() ) + iPluginSession.KeepAliveIkeSAL(&iHdr); +} + +void CIkev1SA::CancelRekey() + { + if ( iLeftOverTime != 0 ) + { + DEBUG_LOG1(_L("CIkev1SA::CancelRekey, remaining time=%d"), iLeftOverTime ); + iRemainingTime = iLeftOverTime; + iLeftOverTime = 0; + } + } + +// +//class CIpsecSPIList : public CArrayPtr +// +CIpsecSPIList::CIpsecSPIList(TInt aGranularity) : CArrayPtrFlat(aGranularity){} +CIpsecSPIList::~CIpsecSPIList() {ResetAndDestroy();} + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1sender.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1sender.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,139 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Sender of UDP datagrams +* +*/ + + +#include + +#include "ikedatainterface.h" +#include "ikedebug.h" +#include "ikesocketdefs.h" +#include "ikemsgheader.h" + +// CLASS HEADER +#include "ikev1sender.h" + + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CIkev1Sender* CIkev1Sender::NewL( MIkeDataInterface& aDataInterface, + MIkev1SenderCallback& aCallback, + MIkeDebug& aDebug ) + { + CIkev1Sender* self = new (ELeave) CIkev1Sender( aDataInterface, + aCallback, + aDebug ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CIkev1Sender::~CIkev1Sender() + { + HBufC8* udpData = iUdpData; + iUdpData = NULL; + + // Sending is not completed via callback interface. + Cancel(); + + delete udpData; + udpData = NULL; + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CIkev1Sender::CIkev1Sender( MIkeDataInterface& aDataInterface, + MIkev1SenderCallback& aCallback, + MIkeDebug& aDebug ) + : CActive( EPriorityStandard ), + iUdpData( NULL ), + iDataInterface( aDataInterface ), + iCallback( aCallback ), + iDebug( aDebug ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------------------------- +// Sends IKE message. +// --------------------------------------------------------------------------- +// +void CIkev1Sender::SendUdpData( HBufC8* aUdpData, + const TInetAddr& aDestAddr, + TInt aLocalPort, + TUint8 aDscp ) + { + __ASSERT_DEBUG( iUdpData == NULL, + User::Invariant() ); + + Cancel(); + + iUdpData = aUdpData; + + // Send IKE message. + DEBUG_LOG( _L("CIkev1Sender::SendUdpData, sending...")); + iDataInterface.SendUdpData( aLocalPort, + aDestAddr, + *aUdpData, + aDscp, + iStatus ); + SetActive(); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles completion of sending. +// --------------------------------------------------------------------------- +// +void CIkev1Sender::RunL() + { + DEBUG_LOG1( _L("CIkev1Sender::RunL, status=%d"), + iStatus.Int() ); + + if ( iUdpData != NULL ) + { + delete iUdpData; + iUdpData = NULL; + + iCallback.SendUdpDataCompleted( iStatus.Int() ); + } + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles cancellation of sending. +// --------------------------------------------------------------------------- +// +void CIkev1Sender::DoCancel() + { + DEBUG_LOG( _L("CIkev1Sender::DoCancel")); + + iDataInterface.CancelSend(); + if ( iUdpData != NULL ) + { + delete iUdpData; + iUdpData = NULL; + } + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1timeout.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1timeout.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Source for timer class used by IKEv1 +* +*/ + +#include "ikev1timeout.h" +#include "ikev1negotiation.h" + + +CIkev1Timeout* CIkev1Timeout::NewL(CIkev1Negotiation& aNegotiation) + { + CIkev1Timeout* self = new (ELeave) CIkev1Timeout(aNegotiation); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + + return self; + } + + +CIkev1Timeout::CIkev1Timeout(CIkev1Negotiation& aNegotiation) + : CTimer(EPriorityStandard), + iNegotiation(aNegotiation) + { + CActiveScheduler::Add(this); //Adds itself to the scheduler only the first time + } + + +CIkev1Timeout::~CIkev1Timeout() + { + if (IsActive()) + Cancel(); + } + + +//Issues next RunL execution +void CIkev1Timeout::IssueRequest(TTimeIntervalMicroSeconds32 anInterval) + { + After(anInterval); //Also sets the object as Active + } + + +// CPacketTimeout +// will send all the packets. One packet each Time +void CIkev1Timeout::RunL() + { + iNegotiation.ReSendL(); + } + + + + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev1lib/src/ikev1trans.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev1lib/src/ikev1trans.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,1148 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE transaction exchange implementation. +* +*/ + +/**------------------------------------------------------------------- + * + * Class CTransNegotiation + * This class is used to handle ISAKMP Transaction exchange messages. + * Transaction exchange has been defined in the IETF draft which specifies + * The ISAKMP Configuration Method . + * This same two message configuration transaction is also used in IETF draft + * Extended Authentication within IKE (XAUTH) . + * CTransNegotiation class implements these IETF drafts, too. + * + *--------------------------------------------------------------------*/ + +#include "ikev1trans.h" +#include "ikedebug.h" +#include "ikev1pluginsession.h" +#include "ikev1negotiation.h" +#include "ikev1payload.h" +#include "ikev1timeout.h" +#include "ikev1crack.h" +#include "ikev1isakmpstream.h" +#include "ikev1crypto.h" + +const TUint8 XAUTH_VID_DATA[8] = {0x09, 0x00, 0x26, 0x89, 0xdf, 0xd6, 0xb7, 0x12}; +const TUint8 CISCO_UNITY_VID_DATA[16] = {0x12, 0xf5, 0xf2, 0x8c, 0x45, 0x71, 0x68, 0xa9, + 0x70, 0x2d, 0x9f, 0xe2, 0x74, 0xcc, 0x01, 0x00}; + + +CTransNegotiation::CTransNegotiation( TInt aGranularity, + TBool aUseXauth, + TBool aUseCfgMode, + CIkev1PluginSession* aPluginSession, + CIkev1Negotiation* aNegotiation, + MIkeDebug& aDebug ) + :CArrayFixFlat(aGranularity), + iPluginSession(aPluginSession), + iNegotiation(aNegotiation), + iUseXauth(aUseXauth), + iUseCfgMode(aUseCfgMode), + iDebug(aDebug) +{ +} + + +/**------------------------------------------------------------------- + * + * Method New() + * Creates an instance of CTransNegotiation class if either + * usage of XAUTH or CFG-MODE has been requested. + * + *--------------------------------------------------------------------*/ +CTransNegotiation* CTransNegotiation::NewL(TBool aUseXauth, TBool aUseCfgMode, + CIkev1PluginSession* aPluginSession, + CIkev1Negotiation* aNegotiation, + MIkeDebug& aDebug ) +{ + CTransNegotiation* Neg = new (ELeave) CTransNegotiation( 1, + aUseXauth, + aUseCfgMode, + aPluginSession, + aNegotiation, + aDebug ); + CleanupStack::PushL(Neg); + Neg->ConstructL(); + CleanupStack::Pop(Neg); + return Neg; +} +/**------------------------------------------------------------------- + * + * Deconstruct method + * + *--------------------------------------------------------------------*/ +CTransNegotiation::~CTransNegotiation() +{ + DEBUG_LOG(_L("Transaction exchange object deleted")); + + delete iInternalAddr; + delete iDialog; + delete iDialogInfo; + delete iUserName; + + for ( TInt i = 0; i < Count(); i++ ) + { + delete At(i); + } +} + +/**------------------------------------------------------------------- + * + * Method ConstructL() + * -- Links CKmdEngine- and CNegotiation object pointers to CTransNegotiation + * -- If only CONFIG-MODE requested, start corresponding transaction exchange. + * + *--------------------------------------------------------------------*/ +void CTransNegotiation::ConstructL() +{ + if ( !iPluginSession || !iNegotiation || (!iUseXauth && !iUseCfgMode)) + { + User::Leave(KErrArgument); + } + + DEBUG_LOG(_L("Transaction exchange object constructed")); + if ( !iUseXauth ) + { + iXauthCompleted = ETrue; + iNegotiation->iTimer->Cancel(); // Stop retransmission timer + } + else + { + if ( !iUseCfgMode ) + iCfgModeCompleted = ETrue; + DEBUG_LOG(_L("Starting to Wait XAUTH request")); + } +} + +/**------------------------------------------------------------------- + * + * Method GetAuthMethod() + * This static method converts the authentication method value from + * "normal" IKE attribute value (specified in RFC2409) to the attribute + * value indicate XAUTH usage after IKE phase 1. This conversion is done + * into the opposite direction when call parameter (aAuthMethod) have + * already value indicating Xauth usage. + * + *--------------------------------------------------------------------*/ +TUint16 CTransNegotiation::GetAuthMethod(TUint16 aAuthMethod, TBool aXauthUsed, TInt aRole) +{ + if ( aXauthUsed ) { + if ( aAuthMethod >= XAUTHInitPreShared && aAuthMethod <= XAUTHRespRSARevisedEncr) { + aAuthMethod -= XAUTHMethodBase; + aAuthMethod = (TUint16)((aAuthMethod >> XAUTHScaler) | XAUTHScaler); + } + else { + if ( aAuthMethod >= PRE_SHARED && aAuthMethod <= RSA_REV_ENCR ) { + aAuthMethod = (TUint16)((aAuthMethod << XAUTHScaler) + XAUTHMethodBase); + if ( aRole == INITIATOR ) + aAuthMethod -= XAUTHScaler; + } + } + } + return aAuthMethod; +} + +/**------------------------------------------------------------------- + * + * Method BuildXauthVendorId() + * This method builds a XAUTH related Vendor ID payload and adds it into + * the IKE message. The vendor id is specified in the draft + * and its content is the following: + * ["0x09002689DFD6B712"]) + * Both ISAKMP mode-cfg and extended authentication (XAUTH) can be + * implemented in some VPN SGWs according to the older mode-cfg and + * xauth drafts: + * and + * + * + *--------------------------------------------------------------------*/ +void CTransNegotiation::BuildXauthVendorId(TIkev1IsakmpStream &aMsg) +{ + TInetAddr DummyAddr; + + aMsg.IsakmpVendorId(IETF_NATT_VENDOR_ID, + NULL, NULL, DummyAddr, // These parameters has no relevance with IETF_NATT_VID_DATA + (TUint8*)XAUTH_VID_DATA, sizeof(XAUTH_VID_DATA)); + + aMsg.IsakmpVendorId(IETF_NATT_VENDOR_ID, + NULL, NULL, DummyAddr, // These parameters has no relevance with IETF_NATT_VID_DATA + (TUint8*)CISCO_UNITY_VID_DATA, + sizeof(CISCO_UNITY_VID_DATA)); +} + +/**------------------------------------------------------------------- + * + * Method GetIV() + * Get IV for transaction exchange specified with message id parameter: + * Find corresponding exchange structure and copy IV to caller + * If no exchange found, return EFALSE status to indicate error. + * + *--------------------------------------------------------------------*/ +TBool CTransNegotiation::GetIV(TUint32 aMsgId, TDes8& aIV) +{ + TBool status = ETrue; + TTransExchange *exchange = FindExchange(aMsgId); + if ( exchange ) + aIV.Copy(exchange->iIV); + else status = EFalse; + + return status; +} + +/**------------------------------------------------------------------- + * + * Method SetIV() + * Set IV for transaction exchange specified with message id parameter: + * Find corresponding exchange structure and store specified IV to + * exchange structure + * If no exchange found, return EFALSE status to indicate error. + * + *--------------------------------------------------------------------*/ +TBool CTransNegotiation::SetIV(TUint32 aMsgId, TDes8& aIV) +{ + TBool status = ETrue; + TTransExchange *exchange = FindExchange(aMsgId); + if ( exchange ) + exchange->iIV.Copy(aIV); + else status = EFalse; + + return status; +} + +/**------------------------------------------------------------------- + * + * Method ProcessUserResponseL() + * ProcessUserResponseL() builds a XAUTH reply message from authentication + * credentials linked into the current CAuthDialogInfo object. + * + *--------------------------------------------------------------------*/ +TInt CTransNegotiation::ProcessUserResponseL(CAuthDialogInfo *aDialogInfo ) +{ + // + // Find a transaction exchange structure for current message + // + TInt lth = 0; + iCurrExchange = FindExchange(aDialogInfo->GetMsgId()); + + if ( iCurrExchange && iRequestFlags ) { + // + // Allocate a buffer for Attribute payload. + // Calculate first required buffer length + // + if ( aDialogInfo->iUsername ) + lth += (aDialogInfo->iUsername->Length() + 4); + if ( aDialogInfo->iSecret ) + lth += (aDialogInfo->iSecret->Length() + 4); + + HBufC8 *attributes = HBufC8::NewL(lth + 4); + CleanupStack::PushL(attributes); + TPtr8 attr_ptr(attributes->Des()); + TUint16 AttrType; + + if ( iRequestFlags & (1 << (ATTR_PASSWORD - ATTR_XAUTH_TYPE)) ) { + // + // Add Xauth type attribute. Value is taken from current exchange structure + // + if ( iUseOlderPIXXauth ) + AttrType = ATTR_PIX_XAUTH_TYPE; + else AttrType = ATTR_XAUTH_TYPE; + AddAttributeData(attr_ptr, AttrType, 2, (TUint8*)&iCurrExchange->iXauthType); + } + + if ( aDialogInfo->iUsername ) { + // + // Add user name attribute. + // + if ( iUseOlderPIXXauth ) + AttrType = ATTR_PIX_USER_NAME; + else AttrType = ATTR_USER_NAME; + + AddAttributeData(attr_ptr, AttrType, aDialogInfo->iUsername->Length(), + (TUint8*)aDialogInfo->iUsername->Ptr()); + // + // Take a copy of user name buffer in dialog info. This user name + // is cached into user name file if current CRACK negotiation is + // succeeded + // + delete iUserName; // Delete old user name buffer for sure + iUserName = HBufC8::New(aDialogInfo->iUsername->Length() + 16); // 16 bytes space for padding + if ( iUserName ) { + iUserName->Des().Copy(aDialogInfo->iUsername->Des()); + } + } + + if ( aDialogInfo->iSecret ) { + // + // Add either password, passcode or next pin attribute. + // Check from iRequestFlags which one was requested by the gateway + // + if ( iUseOlderPIXXauth ) + AttrType = ATTR_PIX_PASSWORD; // default; + else AttrType = ATTR_PASSWORD; // default + + switch ( iRequestFlags ) { + + case (1 << (ATTR_PASSCODE - ATTR_XAUTH_TYPE)): + if ( iUseOlderPIXXauth ) + AttrType = ATTR_PIX_PASSCODE; + else AttrType = ATTR_PASSCODE; + break; + + case (1 << (ATTR_NEXT_PIN - ATTR_XAUTH_TYPE)): + AttrType = ATTR_NEXT_PIN; + break; + + default: + break; + + } + AddAttributeData(attr_ptr, AttrType, aDialogInfo->iSecret->Length(), + (TUint8*)aDialogInfo->iSecret->Ptr()); + } + + BuildAndSendMessageL(attr_ptr, ISAKMP_CFG_REPLY); + + CleanupStack::PopAndDestroy(); //attributes + + iRequestFlags = 0; + + } + + delete iDialog; // delete dialog object + delete aDialogInfo; // release dialog info object + iDialog = NULL; + iDialogInfo = NULL; + + return TRANSACTION_CONTINUE; +} + +/**------------------------------------------------------------------- + * + * Method TransactionFailedL() + * TransactionFailedL() is called when a notificatio/delete payload + * has been received in the middle of a transaction exchange. + * + *--------------------------------------------------------------------*/ +TInt CTransNegotiation::TransactionFailedL(const TNotificationISAKMP *aNotifPayload) +{ + + (void)aNotifPayload; + iNegotiation->iTimer->Cancel(); //Cancel timer because authentication failed + DEBUG_LOG(_L("Transaction exchange stopped by the gateway!")); + // + // Dialog object shall be delete in Dialog->RunL when dialog completed + // + CIkev1Dialog* Dialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); + Dialog->ShowErrorDialogL(TVpnNoteDialog::EKmdAuthenticationFailed, NULL, NULL); + + return TRANSACTION_FAILED; +} + +/**------------------------------------------------------------------- + * + * Method ExecuteL() + * Processes a received ISAKMP transaction exchange message. + * The received message MUST be an encrypted transaction exchange message + * otherwise it is silently discarded. + * Current TTransExchange structure is found, IV value calculated and + * ISAKMP message decrypted. + * TransactionExchangeL() method returns to the caller the following status codes: + * (Corresponding CRACK status codes defined in ike_crack.h) + * -- TRANSACTION_SUCCESS (0) = + * Transaction exchange(s) has been succesfully completed. + * Normal operation can continue and CTransNegotiation object can be deleted. + * -- TRANSACTION_CONTINUE (1) = + * Received message succesfully processed. + * Transaction exchange(s) shall still continue. + * -- TRANSACTION_IGNORE (2) = + * Received message ignored. Transaction exchange(s) shall still continue. + * -- TRANSACTION_FAILED (4) = + * Transaction exchange(s) has been failed (either CONFIG-MODE or XAUTH). + * Current CNegotiation object as well as CTransNegotiation object can + * be deleted. (= corresponding ISAKMP phase 1 negotiation shall be deleted). + * + *--------------------------------------------------------------------*/ +#ifdef _DEBUG +TInt CTransNegotiation::ExecuteL( const ThdrISAKMP& aHdr, + const TInetAddr& aSrcAddr, + TInt aLocalPort ) +#else +TInt CTransNegotiation::ExecuteL( const ThdrISAKMP& aHdr, + const TInetAddr& /*aSrcAddr*/, + TInt /*aLocalPort*/ ) +#endif +{ + DEBUG_LOG(_L("Received message (encr).")); + + TLastIKEMsg msg_info(aHdr); //For retransmitted IKE msg detection + if ( iLastTransMsgInfo.IsReTransmit(msg_info) ) { + DEBUG_LOG(_L("Retransmitted Transaction message received, silently discarded !")); + return TRANSACTION_IGNORE; + } + TUint32 status = TRANSACTION_IGNORE; // default + TUint32 msg_id; + TBuf8 tmp_IV; //Temporal IV. Used to update the real one if the msg OK + const ThdrISAKMP *hdr = NULL; + TUint8 *msg = NULL; + msg_id = aHdr.GetMessageId(); //Saves the ID to compute IV and hash + + if (aHdr.GetFlags() & ISAKMP_HDR_EFLAG) //if encrypted + { + msg = new (ELeave) TUint8[aHdr.GetLength()]; //to place the new msg + CleanupStack::PushL(msg); + + Mem::Copy(msg, (TUint8 *)&aHdr, sizeof(aHdr)); //The header is not encrypted + +#ifdef _DEBUG + DEBUG_LOG(_L("Message ID recv:")); + TUint32 swap_id = ByteOrder::Swap32(msg_id); + DEBUG_LOG_ARRAY((TUint8 *)&swap_id, sizeof(msg_id)); + DEBUG_LOG(_L("Transaction IV:")); +#endif // _DEBUG + // + // Find a transaction exchange structure for current message + // + iCurrExchange = FindExchange(msg_id); + if ( !iCurrExchange ) + iCurrExchange = AddExchangeL(msg_id, RESPONDER); // Add a new transaction exchange + // + // Adjust IV value for transaction exchange. + // There is now two situations: + // 1) There already exists an IV in exchange structure + // (received message is a reply for an earlier sent request) + // 2) There is no IV in exchange structure + // (received message is a new request/set message from peer) + // A new IV is built from CNegotiation.iLastIV and current message ID + // + if ( iCurrExchange->iIV.Length() == 0 ) { + iCurrExchange->iIV.Copy(iNegotiation->iLastIV); + iNegotiation->ComputeIVL(iCurrExchange->iIV, msg_id); + } + tmp_IV.Copy(iCurrExchange->iIV); // Make a copy of current IV + + DEBUG_LOG(_L("Decrypting...")); + + DecryptL((TUint8 *)aHdr.Next(),&msg[sizeof(aHdr)], (aHdr.GetLength()-sizeof(aHdr)), + iCurrExchange->iIV, iNegotiation->iSKEYID_e, + iNegotiation->iChosenProposal_I.iAttrList->iEncrAlg); + hdr = (ThdrISAKMP *)msg; //decrypted msg + +#ifdef _DEBUG + const TPtrC8 ikeMsgPtr( (TUint8*)hdr,(TUint16)hdr->GetLength() ); + TInetAddr dstAddr; + iPluginSession->GetLocalAddress( dstAddr ); + dstAddr.SetPort( aLocalPort ); + TRACE_MSG_IKEV1( ikeMsgPtr, aSrcAddr, dstAddr ); +#endif // _DEBUG + + status = TransactionExchangeL(*hdr); + + if ( status == TRANSACTION_IGNORE ) { + // + // Current message ignored, restore saved IV to exchange structure + // + iCurrExchange->iIV.Copy(tmp_IV); + } + } + else + hdr = &aHdr; + + if (msg) //If used erase it (when encryption) + CleanupStack::PopAndDestroy(); + + if ( status == TRANSACTION_CONTINUE ) + msg_info.Store(iLastTransMsgInfo); // store new last received IKE message info + + return status; +} + +/**------------------------------------------------------------------- + * + * Method TransactionExchangeL() + * The ISAKMP transaction exchange message MUST be the following format: + * HDR*, HASH, ATTR + * Where the HASH payload contains the prf output, using SKEYID_a as + * the key, and the M-ID (ISAKMP header Message ID) unique to this + * exchange concatenated with all of the payloads after the HASH + * payload. In other words, the hash for the above exchange is: + * HASH = prf( SKEYID_a, M-ID | ATTR ) + * Multiple ATTR payloads MAY NOT be present in the Transaction Exchange. + * + *--------------------------------------------------------------------*/ +TInt CTransNegotiation::TransactionExchangeL(const ThdrISAKMP &aHdr) +{ + TUint32 status; + iNegotiation->iLengthLeft = aHdr.GetLength(); //Used to check the size in the payload are OK + + CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *iNegotiation, iDebug); + if (!payload) + { + return TRANSACTION_FAILED; + } + CleanupStack::PushL(payload); + + if ( payload->iHash && payload->iAttr ) + { + // + // Check if the hash value is OK. + // + if (!iNegotiation->VerifyInformationalHashL(payload->iHash, payload->iAttr, + iCurrExchange->iMessageId)) + { + DEBUG_LOG(_L("AUTHENTICATION_FAILED (Transaction hash)")); + CleanupStack::PopAndDestroy(); //payload + return TRANSACTION_FAILED; + } + status = ProcessAttributesL(payload->iAttr); + CleanupStack::PopAndDestroy(); //payload + return status; + } + CleanupStack::PopAndDestroy(); //payload + DEBUG_LOG(_L("Erroneous Transaction Exchange message received")); + return TRANSACTION_FAILED; +} + +/**------------------------------------------------------------------- + * + * Method ProcessAttributesL() + * ProcessAttributesL() method parses the data attributes in received + * attribute payload. If the iRole data member of current exchange structure + * contains value INITIATOR, attribute payload is a CONFIG-MODE Reply + * which should contain CONFIG-MODE attributes. + * If the iRole data member of current exchange structure + * contains value RESPONDER, attribute payload is either a XAUTH Request or Set. + * These primitives should contain XAUTH attributes. + * + *--------------------------------------------------------------------*/ +TInt CTransNegotiation::ProcessAttributesL(const TAttributeISAKMP *aAttr) +{ + TInt length = (TInt)aAttr->GetLength(); + if ( STATIC_CAST(TUint, length) < sizeof(TAttributeISAKMP) ) { + return TRANSACTION_FAILED; + } + + TInt status; + TUint8 cfg_msg_type = aAttr->CfgMsgType(); + TUint16 identifier = aAttr->Identifier(); + + if ( iCurrExchange->iRole == INITIATOR ) { + // + // Config mode transaction. The current message should be a reply. + // Identifier value must also match to value in current exchange structure. + // + if ( cfg_msg_type != ISAKMP_CFG_REPLY ) { +// || +// ( iCurrExchange->iIdentifier != identifier ) ) { + return TRANSACTION_FAILED; + } + status = ProcessCfgModeAttrsL(aAttr->AttrData(), aAttr->AttrDataLen()); + } + else { + // + // XAUTH mode transaction. The current message should be either request + // or set. + // + if ( (cfg_msg_type != ISAKMP_CFG_REQUEST) && (cfg_msg_type != ISAKMP_CFG_SET) ) { + return TRANSACTION_FAILED; + } + iCurrExchange->iIdentifier = identifier; + if ( cfg_msg_type == ISAKMP_CFG_REQUEST ) + status = ProcessXauthRequestL(aAttr->AttrData(), aAttr->AttrDataLen()); + else status = ProcessXauthStatusL(aAttr->AttrData(), aAttr->AttrDataLen()); + } + + return CheckTransactionStatusL(status); + +} + +/**------------------------------------------------------------------- + * + * Method ProcessCfgModeAttrs() + * ProcessCfgModeAttrs parses CONFIG-MODE reply message attributes + * received from gateway. In this phase the following attributes are used: + * -- INTERNAL_IP4_ADDRESS = Client virtual IPv4 address in secure network + * -- INTERNAL_IP6_ADDRESS = Client virtual IPv6 address in secure network + * -- INTERNAL_IP4_DNS = DNS address(es) in secure network + * + * All other attributes are silently discarded + * + *--------------------------------------------------------------------*/ +TInt CTransNegotiation::ProcessCfgModeAttrsL(TDataISAKMP* aAttr, TInt aLth) +{ + + TBool ia_received = EFalse; + TUint32 ipv4_addr; + TIp6Addr ipv6_addr; //IPV6 raw address + TInetAddr *dns_addr; + + delete iInternalAddr; // delete old CInternalAddress for sure + iInternalAddr = NULL; + CInternalAddress *InternalAddr = new (ELeave)CInternalAddress(1); + CleanupStack::PushL(InternalAddr); + + while ( aLth > 0 ) { + + aLth = aLth - aAttr->Size(); + if ( aLth < 0 ) { + DEBUG_LOG(_L("CONFIG-MODE REPLY ERROR (Length mismatch in the attibutes)")); + CleanupStack::PopAndDestroy(); // InternalAddr + return TRANSACTION_FAILED; + } + switch ( aAttr->Type() ) { + + case ATTR_INTERNAL_IP4_ADDR: + // + // A Virtual IPv4 address received. + // Store value to CInternalAddress object + // + if ( !aAttr->IsBasic() && (aAttr->Length() == 4) ) { + if ( !ia_received ) { + ia_received = ETrue; + ipv4_addr = GET32(aAttr->VarValue()); + InternalAddr->iClientIntAddr.SetAddress(ipv4_addr); + } + } + break; + + case ATTR_INTERNAL_IP6_ADDR: + // + // A Virtual IPv6 address received. + // Store value to CInternalAddress object + // + if ( !aAttr->IsBasic() && (aAttr->Length() == 16) ) { + if ( !ia_received ) { + ia_received = ETrue; + Mem::Copy(&ipv6_addr.u.iAddr8, aAttr->VarValue(), sizeof(ipv6_addr.u.iAddr8)); + InternalAddr->iClientIntAddr.SetAddress(ipv6_addr); + } + } + break; + + case ATTR_INTERNAL_IP4_DNS: + // + // Internal DNS address received. + // Add value to CInternalAddress object + // + if ( !aAttr->IsBasic() && (aAttr->Length() == 4) ) { + ipv4_addr = GET32(aAttr->VarValue()); + dns_addr = new(ELeave)TInetAddr; + CleanupStack::PushL(dns_addr); + dns_addr->SetAddress(ipv4_addr); + InternalAddr->AppendL(dns_addr); + CleanupStack::Pop(); // dns_addr + } + break; + + default: + break; + } + + aAttr = aAttr->Next(); + } + + CleanupStack::Pop(); // InternalAddr + iInternalAddr = InternalAddr; + + iCfgModeCompleted = ETrue; + + DEBUG_LOG(_L("CONFIG-MODE completed, reply received!")); + + return TRANSACTION_SUCCESS; +} + +/**------------------------------------------------------------------- + * + * Method ProcessXauthRequest() + * ProcessXauthRequest parses XAUTH request message attributes + * received from gateway. + * + *--------------------------------------------------------------------*/ +TInt CTransNegotiation::ProcessXauthRequestL(TDataISAKMP* aAttr, TInt aLth) +{ + TInt status = TRANSACTION_CONTINUE; + TUint16 xauth_type = ATTR_XAUTH_GENERIC; + TUint32 request_flags = 0; + TPtr8 challenge(NULL, 0); + TUint16 attr_type; + + while ( aLth > 0 ) { + + aLth = aLth - aAttr->Size(); + if ( aLth < 0 ) { + DEBUG_LOG(_L("XAUTH REQUEST ERROR (Length mismatch in the attibutes)")); + return TRANSACTION_FAILED; + } + attr_type = aAttr->Type(); + // + // Check does the VPN gateway support older XAUTH draft version + // draft-ietf-ipsec-isakmp-xauth-04.txt. + // The check is based on attribute type values. In the older + // draft attribute values are defined in range (13-20) and in the newer + // "de-facto" draft-beaulieu-ike-xauth-02.txt the same + // attribute values are in "private use" range (16520-16529) + // + if ( attr_type < ATTR_XAUTH_TYPE ) + iUseOlderPIXXauth = ETrue; + + switch ( attr_type ) { + + case ATTR_XAUTH_TYPE: + case ATTR_PIX_XAUTH_TYPE: + // + // Extended authentication type requested + // + if ( aAttr->IsBasic() ) { // Basic attribute + request_flags |= (1 << (ATTR_XAUTH_TYPE - ATTR_XAUTH_TYPE)); + iCurrExchange->iXauthType = aAttr->Value(); + } + break; + + case ATTR_USER_NAME: + case ATTR_PASSWORD: + case ATTR_PASSCODE: + case ATTR_PIX_USER_NAME: + case ATTR_PIX_PASSWORD: + case ATTR_PIX_PASSCODE: + // + // Handles the following attribute values: + // -- User name + // -- Password + // -- Passcode + // Set a corresponding bit request flags. Parameter contents has + // no meaning in request + // + if ( !aAttr->IsBasic() ) { // Variable length + if ( attr_type < ATTR_USER_NAME ) + request_flags |= (1 << (attr_type - ATTR_PIX_XAUTH_TYPE)); + else request_flags |= (1 << (attr_type - ATTR_XAUTH_TYPE)); + } + break; + + case ATTR_MESSAGE: + case ATTR_PIX_MESSAGE: + // + // Message data attribute (NOT USED IN THIS PHASE) + // + break; + + case ATTR_CHALLENGE: + case ATTR_PIX_CHALLENGE: + // + // Challenge data attribute + // + if ( !aAttr->IsBasic() && aAttr->Length() ) { + request_flags |= (1 << (ATTR_CHALLENGE - ATTR_XAUTH_TYPE)); + challenge.Set(aAttr->VarValue(), aAttr->Length(), aAttr->Length()); + } + break; + + case ATTR_DOMAIN: + case ATTR_STATUS: + case ATTR_PIX_DOMAIN: + case ATTR_PIX_STATUS: + // + // Domain and status attributes (NOT USED IN THIS PHASE) + // + break; + + case ATTR_NEXT_PIN: + if ( !aAttr->IsBasic() ) { // Variable length + request_flags |= (1 << (ATTR_NEXT_PIN - ATTR_XAUTH_TYPE)); + } + break; + + case ATTR_ANSWER: + // + // Answer data attribute (NOT USED IN THIS PHASE) + // + break; + + default: + break; + } + + aAttr = aAttr->Next(); + } + + // + // Check if there already exist a authentication credentials request active + // (= iRequestFlags are not zero). If there is ignore current message. + // + if ( iRequestFlags == 0 ) { + iRequestFlags = request_flags; + } + else { + request_flags = 0; + status = TRANSACTION_IGNORE; + } + // + // Examine request_flags and show appropriate dialog to get requested + // authentication credentials from user + // + switch ( request_flags & ~(1 << (ATTR_XAUTH_TYPE - ATTR_XAUTH_TYPE)) ) { + + case ( (1 << (ATTR_USER_NAME - ATTR_XAUTH_TYPE)) | (1 << (ATTR_PASSWORD - ATTR_XAUTH_TYPE))): + // + // User name/Password authentication required + // + iDialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); + iDialogInfo = new(ELeave) CAuthDialogInfo(iPluginSession, XAUTH_DIALOG_ID, iNegotiation->SAId(), iCurrExchange->iMessageId); + iDialog->GetAsyncUNPWDialogL(iDialogInfo, (MIkeDialogComplete*)this); + break; + + case ( (1 << (ATTR_USER_NAME - ATTR_XAUTH_TYPE)) | (1 << (ATTR_PASSCODE - ATTR_XAUTH_TYPE))): + // + // User name/Secure ID authentication required + // + iDialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); + iDialogInfo = new(ELeave) CAuthDialogInfo(iPluginSession, XAUTH_DIALOG_ID, iNegotiation->SAId(), iCurrExchange->iMessageId); + iDialog->GetAsyncSecureidDialogL(iDialogInfo, (MIkeDialogComplete*)this); + break; + + case ( (1 << (ATTR_USER_NAME - ATTR_XAUTH_TYPE)) | (1 << (ATTR_NEXT_PIN - ATTR_XAUTH_TYPE))): + // + // User name/Secure ID next pin required + // + iDialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); + iDialogInfo = new(ELeave) CAuthDialogInfo(iPluginSession, XAUTH_DIALOG_ID, iNegotiation->SAId(), iCurrExchange->iMessageId); + iDialog->GetAsyncSecureNextPinDialogL(iDialogInfo, (MIkeDialogComplete*)this); + break; + + case ( (1 << (ATTR_CHALLENGE - ATTR_XAUTH_TYPE)) ): + // + // User Challenge response dialog + // + if ( xauth_type == ATTR_XAUTH_RADIUS_CHAP ) + { + iDialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); + iDialogInfo = new(ELeave) CAuthDialogInfo(iPluginSession, XAUTH_DIALOG_ID, iNegotiation->SAId(), iCurrExchange->iMessageId); + iDialog->GetAsyncRespDialog(challenge, iDialogInfo, (MIkeDialogComplete*)this); + } + break; + + default: + break; + + } + + return status; + +} + +/**------------------------------------------------------------------- + * + * Method ProcessXauthStatus() + * ProcessXauthStatus parses XAUTH Set message attributes received from gateway. + * Only Status attribute has any relevance in Set message. + * + *--------------------------------------------------------------------*/ +TInt CTransNegotiation::ProcessXauthStatusL(TDataISAKMP* aAttr, TInt aLth) +{ + TBuf8<16> attributes; + TInt status = TRANSACTION_CONTINUE; + TInt16 attr_status; + + while ( aLth > 0 ) { + + aLth = aLth - aAttr->Size(); + if ( aLth < 0 ) { + DEBUG_LOG(_L("XAUTH SET ERROR (Length mismatch in the attibutes)")); + return TRANSACTION_FAILED; + } + + switch ( aAttr->Type() ) { + + case ATTR_STATUS: + case ATTR_PIX_STATUS: + // + // Status code from gateway + // + if ( aAttr->IsBasic() ) { // Basic attribute + attr_status = aAttr->Value(); + if ( attr_status == ATTR_STATUS_OK ) + status = TRANSACTION_SUCCESS; + else status = TRANSACTION_FAILED; + } + break; + + default: + break; + } + + aAttr = aAttr->Next(); + } + + if ( status != TRANSACTION_CONTINUE ) { + // + // Send Transaction exchange ACK + // + TUint16 AttrType; + if ( iUseOlderPIXXauth ) + AttrType = ATTR_PIX_STATUS; + else AttrType = ATTR_STATUS; + + AddAttributeData(attributes, AttrType, 2, (TUint8*)&attr_status); + BuildAndSendMessageL(attributes, ISAKMP_CFG_ACK); + if ( status == TRANSACTION_SUCCESS ) { + DEBUG_LOG(_L("XAUTH authentication succeeded!")); + iXauthCompleted = ETrue; + if ( iUserName ) { + // + // Cache user name into user name file + // + CIkev1Dialog* Dialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); + CleanupStack::PushL(Dialog); + TInt err(KErrNone); + TRAP(err, Dialog->StoreUserNameL(iUserName->Des())); +#ifdef _DEBUG + if (err == KErrNone) + DEBUG_LOG(_L("User Name caching succeeded")); + else DEBUG_LOG(_L("User Name caching failed")); +#endif // _DEBUG + CleanupStack::PopAndDestroy(); + } + } + else { + DEBUG_LOG(_L("XAUTH authentication failed!")); + // Dialog object shall be delete in Dialog->RunL when dialog completed + CIkev1Dialog* Dialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug); + Dialog->ShowErrorDialogL(TVpnNoteDialog::EKmdAuthenticationFailed, NULL, NULL); + } + } + + return status; +} + +/**-------------------------------------------------------------------------------- + * + * Method CheckTransactionStatusL() + * CheckTransactionStatus is after an incoming ISAKMP transaction exchange message + * has been processed. This method decides the actions shall be taken next: + * -- If current status (= call parameter) is continue, ignore or failed + * ==> Same status is returned + * -- If current status is success and XAUTH completed. + * ==> CONFIG MODE actions are started (= Config mode request is transmitted) + * -- If current status is success and CONFIG MODE completed. + * ==> XAUTH actions are started. (= We shall just wait for XAUTH request) + * -- If current status is success and both CONFIG-MODE and XAUTH completed + * ==> TRANSACTION_SUCCESS status is returned + * + *--------------------------------------------------------------------*/ +TInt CTransNegotiation::CheckTransactionStatusL(TInt aStatus) +{ + if ( aStatus == TRANSACTION_SUCCESS || aStatus == TRANSACTION_CONTINUE ) { + // + // Stop retransmission timer + // + iNegotiation->iTimer->Cancel(); + + if ( aStatus == TRANSACTION_SUCCESS ) { + if ( iXauthCompleted ) { + if ( !iCfgModeCompleted ) { + aStatus = BuildConfigRequestL(); + } + } + else { + if ( !iXauthCompleted ) { + aStatus = TRANSACTION_CONTINUE; + } + } + } + } + + return aStatus; +} + +/**------------------------------------------------------------------- + * + * Method BuildConfigRequestL() + * BuildConfigRequestL() builds the CONFIG-MODE request message. + * In this phase requests the following parameters from gateway: + * -- Client virtual IP in secure network = INTERNAL_IP4_ADDRESS, INTERNAL_IP4_NETMASK + * (INTERNAL_IP6_ADDRESS, INTERNAL_IP6_NETMASK) + * -- DNS address(es) in secure network = INTERNAL_IP4_DNS + * + *--------------------------------------------------------------------*/ +TInt CTransNegotiation::BuildConfigRequestL() +{ + + TBuf8<16> attributes; + + TUint32 message_id = iNegotiation->RandomMessageId(); + + iCurrExchange = AddExchangeL(message_id, INITIATOR); //Add a new transaction exchange + iCurrExchange->iIdentifier = GetIdentifier(); + + iCurrExchange->iIV.Copy(iNegotiation->iLastIV); // Calculate base IV for .. + iNegotiation->ComputeIVL(iCurrExchange->iIV, message_id); // transaction message + + AddAttributeData(attributes, ATTR_INTERNAL_IP4_ADDR, 0, NULL); + AddAttributeData(attributes, ATTR_INTERNAL_IP4_DNS, 0, NULL); + + BuildAndSendMessageL(attributes, ISAKMP_CFG_REQUEST); + DEBUG_LOG(_L("CONFIG-MODE started, request xmitted!")); + + return TRANSACTION_CONTINUE; + + +} + +/**------------------------------------------------------------------- + * + * Method AddAttributeData() + * AddAttributeData() method adds one attribute data to an attribute buffer + * + *--------------------------------------------------------------------*/ +void CTransNegotiation::AddAttributeData(TDes8& aAttrBfr, TInt aType, TInt aLth, TUint8* aData) +{ + TDataISAKMP attr; + if ( aType == ATTR_STATUS || aType == ATTR_XAUTH_TYPE || + aType == ATTR_PIX_STATUS || aType == ATTR_PIX_XAUTH_TYPE) { + // + // Add a basic length attribute + // + attr.SetBasic(ETrue); + attr.SetType((TUint16)aType); + if ( aData ) + attr.SetValue(*(TUint16*)aData); + aAttrBfr.Append((TUint8 *)&attr, sizeof(attr)); + } + else { + // + // Add a variable length attribute + // + attr.SetBasic(EFalse); + attr.SetType((TUint16)aType); + attr.SetLength((TUint16)(aLth)); + aAttrBfr.Append((TUint8 *)&attr, sizeof(attr)); + if ( aLth ) + aAttrBfr.Append(aData, aLth); + } +} + +/**------------------------------------------------------------------- + * + * Method BuildAndSendMessageL() + * BuildAndSendMessage() method builds ISAKMP transaction exchange message + * and transmits it using CNegotiation class send() method. + * The payload format of a transaction exchange message is the following: + * HDR*, HASH, ATTR + * Where the HASH payload contains the prf output, using SKEYID_a as + * the key, and the M-ID (ISAKMP header Message ID) unique to this + * exchange concatenated with all of the payloads after the HASH + * payload. In other words, the hash for the above exchange is: + * HASH = prf( SKEYID_a, M-ID | ATTR ) + * + *--------------------------------------------------------------------*/ +void CTransNegotiation::BuildAndSendMessageL(TDesC8& aAttrBfr, TUint8 aMsgType) +{ + TIkev1IsakmpStream* msg = iNegotiation->SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) ); + + TUint32 saved_msg_id = iNegotiation->iMessageId; + TUint8 saved_exchange = iNegotiation->iExchange; + iNegotiation->iMessageId = iCurrExchange->iMessageId; // used in method Isakmp_INIT() + iNegotiation->iExchange = ISAKMP_EXCHANGE_TRANSACT; // used in method Isakmp_INIT() + + msg->IsakmpInit(iNegotiation); + msg->IsakmpHashL(); + msg->IsakmpAttributes(aMsgType, iCurrExchange->iIdentifier, aAttrBfr); + msg->IsakmpHashContL(); + + iNegotiation->SendL(*msg); + + iNegotiation->iMessageId = saved_msg_id; + iNegotiation->iExchange = saved_exchange; + +} + +/**------------------------------------------------------------------- + * + * Method FindExchange() + * FindExchange() method finds a exchange strcuture for a specified message id + * + *--------------------------------------------------------------------*/ +TTransExchange* CTransNegotiation::FindExchange(TUint32 aMsgId) +{ + TTransExchange *exchange; + TInt i = 0; + + while ( i < Count() ) + { + exchange = At(i); + if ( exchange->iMessageId == aMsgId ) + return exchange; + i ++; + } + + return NULL; +} + +/**------------------------------------------------------------------- + * + * Method AddExchangeL() + * AddExchangeL() method allocates a new exchange structure and adds it + * to exchange array. + * + *--------------------------------------------------------------------*/ +TTransExchange* CTransNegotiation::AddExchangeL(TUint32 aMsgId, TUint8 aRole ) +{ + + TTransExchange *exchange = new(ELeave)TTransExchange; + exchange->iMessageId = aMsgId; + exchange->iRole = aRole; + exchange->iIV.SetLength(0); + AppendL(exchange); + + return exchange; +} + +// +// The implementation for class MIkeDialogComplete virtual function +// +TInt CTransNegotiation::DialogCompleteL(CIkev1Dialog* /*aDialog*/, TAny* aUserInfo, + HBufC8* aUsername, HBufC8* aSecret, HBufC8* aDomain) +{ +/*--------------------------------------------------------------------------- + * + * A response received from client user (through asynchronous dialog) + * This method is introduced as a TUserCallback for CGetIKEPassword dialog + * object is created. When the dialog is completed this callback function + * is called to deliver Credentials data for CHRE payload attributes. + * Store credential buffers to CAuthDialogInfo object and call engine + * entry + * + *-------------------------------------------------------------------------*/ + TUint32 obj_id = 1; + CAuthDialogInfo* info = (CAuthDialogInfo*)aUserInfo; + DEBUG_LOG1(_L("CIKECRACKNegotiation::DialogCompleteL(), aUserInfo = %x"), aUserInfo); + + if ( info ) + { + obj_id = info->GetObjId(); + DEBUG_LOG1(_L("Preparing to call AuthDialogCompletedL(), ObjId = %x"), obj_id); + if ( obj_id == XAUTH_DIALOG_ID ) + { + info->iUsername = aUsername; + info->iSecret = aSecret; + info->iDomain = aDomain; + obj_id = info->PluginSession()->AuthDialogCompletedL(info); + } + } + + return obj_id; +} diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/EABI/ikev2libU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/EABI/ikev2libU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + _Z12Ikev2PlugInLR17MKmdEventLoggerIfR9MIkeDebug @ 1 NONAME + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/bwins/IKEV2LIBU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/bwins/IKEV2LIBU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?Ikev2PlugInL@@YAPAVMIkePluginIf@@AAVMKmdEventLoggerIf@@AAVMIkeDebug@@@Z @ 1 NONAME ; class MIkePluginIf * Ikev2PlugInL(class MKmdEventLoggerIf &, class MIkeDebug &) + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Build information file +* +*/ + + +#include + +PRJ_PLATFORMS + +PRJ_EXPORTS + + +PRJ_MMPFILES +#ifdef VPNCLIENT_USE_STUBS + ikev2libtest.mmp +#else + ikev2lib.mmp +#endif + +PRJ_TESTMMPFILES + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/group/ikev2lib.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/group/ikev2lib.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project ikev2lib +* +*/ + + + +#include + +TARGET ikev2lib.dll +TARGETTYPE DLL +UID 0x1000008d 0x10206993 + +CAPABILITY CAP_SERVER CommDD NetworkControl +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE ikev2plugin.cpp +SOURCE ikev2negotiation.cpp +SOURCE ikemsgrec.cpp +SOURCE ikecrypto.cpp +SOURCE ikev2retransmittimer.cpp +SOURCE ikev2proposal.cpp +SOURCE ikev2pfkey.cpp +SOURCE ipsecproposal.cpp +SOURCE ipsecselectors.cpp +SOURCE ikev2natt.cpp +SOURCE Ikev2Config.cpp +SOURCE Ikev2EapInterface.cpp +SOURCE ikev2mobike.cpp +SOURCE ikev2keepalive.cpp +SOURCE ikev2sa.cpp +SOURCE ikev2pluginsession.cpp +SOURCE ikev2sender.cpp +SOURCE ikev2receiver.cpp +SOURCE ikev2message.cpp +SOURCE ikev2identity.cpp +SOURCE ikev2trafficselector.cpp +SOURCE ikev2ipsecsarekeydata.cpp +SOURCE ikev2deactivationtimer.cpp +SOURCE ikev2ipsecsadata.cpp +SOURCE ikev2sadata.cpp +SOURCE ikev2acquire.cpp +SOURCE ikev2expire.cpp +SOURCE ikev2messagesendqueue.cpp + +USERINCLUDE ../inc +USERINCLUDE ../../kmdapi/inc +USERINCLUDE ../../kmdserver/inc +USERINCLUDE ../../ikesocket/inc +USERINCLUDE ../../eventmediatorapi/inc +USERINCLUDE ../../ikecert/inc +USERINCLUDE ../../ikepolparser/inc +USERINCLUDE ../../vpnmanager/inc +USERINCLUDE ../../utlcrypto/inc +USERINCLUDE ../../pkiserviceapi/inc +USERINCLUDE ../../../vpnapiimpl/inc +USERINCLUDE ../../ikeutils/inc + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY euser.lib +LIBRARY ecom.lib +LIBRARY esock.lib +LIBRARY insock.lib +LIBRARY ipsecpolapi.lib +LIBRARY utlcrypto.lib +LIBRARY ikecert.lib +LIBRARY random.lib +LIBRARY ikeutils.lib +LIBRARY ikepolparser.lib +LIBRARY bafl.lib diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/group/ikev2libtest.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/group/ikev2libtest.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Test project definition file for project ikev2lib +* +*/ + + + +#include + +TARGET ikev2lib.dll +TARGETTYPE DLL +UID 0x1000008d 0x10206993 + +CAPABILITY CAP_SERVER CommDD NetworkControl +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE ikev2plugin.cpp +SOURCE ikev2negotiation.cpp +SOURCE ikemsgrec.cpp +SOURCE ikecrypto.cpp +SOURCE ikev2retransmittimer.cpp +SOURCE ikev2proposal.cpp +SOURCE ikev2pfkey.cpp +SOURCE ipsecproposal.cpp +SOURCE ipsecselectors.cpp +SOURCE ikev2natt.cpp +SOURCE ikev2config.cpp +SOURCE ikev2eapinterface.cpp +SOURCE ikev2mobike.cpp +SOURCE ikev2keepalive.cpp +SOURCE ikev2sa.cpp +SOURCE ikev2pluginsession.cpp +SOURCE ikev2sender.cpp +SOURCE ikev2receiver.cpp +SOURCE ikev2message.cpp +SOURCE ikev2identity.cpp +SOURCE ikev2trafficselector.cpp +SOURCE ikev2ipsecsarekeydata.cpp +SOURCE ikev2deactivationtimer.cpp +SOURCE ikev2ipsecsadata.cpp +SOURCE ikev2sadata.cpp +SOURCE ikev2acquire.cpp +SOURCE ikev2expire.cpp +SOURCE ikev2messagesendqueue.cpp + +USERINCLUDE ../inc +USERINCLUDE ../../kmdapi/inc +USERINCLUDE ../../kmdserver/inc +USERINCLUDE ../../ikesocket/inc +USERINCLUDE ../../eventmediatorapi/inc +USERINCLUDE ../../ikecert/inc +USERINCLUDE ../../ikepolparser/inc +USERINCLUDE ../../vpnmanager/inc +USERINCLUDE ../../utlcrypto/inc +USERINCLUDE ../../pkiserviceapi/inc +USERINCLUDE ../../../vpnapiimpl/inc +USERINCLUDE ../../ikeutils/inc + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY ikelibs_proxy.lib +LIBRARY euser.lib +LIBRARY ecom.lib +LIBRARY esock.lib +LIBRARY insock.lib +LIBRARY ipsecpolapi.lib +LIBRARY utlcrypto.lib +LIBRARY ikecert.lib +LIBRARY random.lib +LIBRARY ikeutils.lib +LIBRARY ikepolparser.lib +LIBRARY bafl.lib diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikecrypto.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikecrypto.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Cryptographic Intermediate Layer to use and change any crypto library easily. +* +*/ + +#ifndef __IKECRYPTO_H_ +#define __IKECRYPTO_H__ + + +#include +#include "utlcrypto.h" + +NONSHARABLE_CLASS(CDHKeys) : public CBase +{ +public: + static CDHKeys* NewL(const TDesC8& aN,const TDesC8& aG); + static CDHKeys* CreateDHKeyL(TUint aGroupDesc); + HBufC8* ComputeAgreedKeyL(const TDesC8 &aPeerPublicKey); + HBufC8* GetPubKey(); + void XValueL(); + inline const HBufC8* KValueL(const TDesC8& aY) const {return iDHKey->CompleteKL(aY);} + inline TInt ModulusLength() {return iModuluslength;} + ~CDHKeys(); +private: + CUtlDiffieHellman* iDHKey; + const HBufC8* iPubKey; + TInt iModuluslength; +}; + + +class IkeCrypto +{ +public: + static void DecryptL(const TUint8* aInputPayload, TUint8* aOutputPayload, TInt aLength, TUint8* aIV, + const TDesC8& aKey, TUint16 aEncrAlg); + static void EncryptL(const TDesC8& aInput, TPtr8& aOutput, const TDesC8& aIv, const TDesC8& aKey, TUint16 aEncrAlg); + static TInt IntegHMACL(const TDesC8& aInput, TDes8& aChecksum, const TDesC8& aKeyData, TUint16 aIntegAlg); + static HBufC8* PrfhmacL(const TDesC8& aInput, const TDesC8& aKeyData, TUint16 aPrfAlg); + static HBufC8* PrfL(const TDesC8& aInput, TUint16 aPrfAlg); + static TInt AlgorithmInfo(TUint16 aTransform, TUint16 aAlgCode, TInt* aBlockLth=NULL, + TUtlCrypto::TUtlSymmetricCipherId* aCipherId=NULL, + TUtlCrypto::TUtlMessageDigestId* aDigestId=NULL); + static HBufC8* GenerateKeyingMaterialL(const TDesC8& aK, const TDesC8& aS, TInt aKeyMatLth, TUint16 aPRFAlg); +}; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikemsgrec.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikemsgrec.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Received IKE message handling rules. +* +*/ +#ifndef _IKEMSGREC_H_ +#define _IKEMSGREC_H_ +#include "ikev2payloads.h" + +class TIkev2SAData; + +NONSHARABLE_CLASS(CIkev2Payloads) : public CBase + { +public: + static CIkev2Payloads* NewL(const ThdrISAKMP &aHdr, const TIkev2SAData& aIkeV2SaData); + static CIkev2Payloads* NewL(TPayloadIkev2* aPayload, TUint8 aPayloadType, TIkev2SAData& aIkeV2SaData); + ~CIkev2Payloads(); + + ThdrISAKMP* GetIkeMsg(); + TInt Status(); + void SetStatus(TInt aStatus); + TBool Encrypted(); + TInt ParsePayloadL(TPayloadIkev2* aPayload, TUint16 aPlType); + +private: + CIkev2Payloads(const TIkev2SAData& aIkeV2SaData); + void ConstructL(); + + TInt ParsePayloadsL(TPayloadIkev2* aPayload, TInt aLength, TUint16 aPlType, TUint16 aRefPlType ); + void DecryptEncrPayloadL(TPayloadIkev2* aPayload); + +public: + TPayloadIkev2* iSa; + TKEPayloadIkev2* iKe; + TPayloadIkev2* iNonce; + TAuthPayloadIkev2* iAuth; + TIDPayloadIkev2* iIdI; + TIDPayloadIkev2* iIdR; + TTSPayloadIkev2* iTsI; + TTSPayloadIkev2* iTsR; + TPayloadIkev2* iEncr; + TCPPayloadIkev2* iCp; + TPayloadIkev2* iEap; + + CArrayFixFlat* iProps; + CArrayFixFlat* iTrans; + CArrayFixFlat* iCerts; + CArrayFixFlat* iCertReqs; + CArrayFixFlat* iNotifs; + CArrayFixFlat* iDeletes; + CArrayFixFlat* iVids; + + CArrayFixFlat* iGenPlds; + +private: + const TIkev2SAData& iIkeV2SaData; + ThdrISAKMP* iIkeMsg; + TBool iEncrypted; + TInt iStatus; + + }; +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2EapInterface.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2EapInterface.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,124 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: "intermediate" class between +* CIkev2Negotiation class of ikev2plugin and ECOM plug-in +* +*/ +#ifndef __IKEV2EAPINTERFACE_H_ +#define __IKEV2EAPINTERFACE_H_ + +#include +#include // MAbsEapVpnInterface + +class CIkeData; +class TPayloadIkev2; +class CEapVpnInterface; +class MIkeDebug; + +class MIkev2EapIfObserver + { +public: + virtual void SendEapDataL(HBufC8* aEapData) = 0; + virtual void EapEventL(TInt aEvent) = 0; + }; + +/** + * CIkev2EapIf + * + * CIkev2EapIf is an "intermediate" class between + * CIkev2Negotiation class of ikev2plugin and ECOM plug-in (eapplugin) + * which provides access into general EAP protocol implementation in + * system. CIkev2EapIf implements also the callback functions required + * by the EAP ECOM plug-in. + * + * @lib internal ikev2lib.lib + * @since S60 3.0 + */ +NONSHARABLE_CLASS(CIkev2EapIf) : public CBase, public MAbsEapVpnInterface + { +public: + + /** + * NewL + * + * @since S60 3.0 + * @param aNeg IKE negotiation. Must be != NULL. Ownership not taken. + * @param aEapType EAP type. + * @param aIkeData Ref to IKE data. Ownership not taken. + * @param aDebug Debug trace interface + * @return self + */ + static CIkev2EapIf* NewL(MIkev2EapIfObserver& aEapIfObserver, + TUint8 aEapType, + CIkeData* aIkeData, + MIkeDebug& aDebug); + + ~CIkev2EapIf(); + inline TInt Status() {return iErrorStatus;} + inline HBufC8* Identity() + { + HBufC8* Id = (HBufC8*)iIdentity; + iIdentity = 0; + return Id; + } + inline HBufC8* MSK() + { + HBufC8* msk = (HBufC8*)iMSK; + iMSK = NULL; + return msk; + } + void ErrorStopL() {}; + void EapDataInbound(TPayloadIkev2* aEapPayload); + void QueryIdentity(); + + /** + * From MAbsEapVpnInterface. + * Implementation of pure virtual methods + */ + void EapOutboundL(HBufC8* aResponse); + void EapIdentityResponseL(HBufC8* aIdentity); + void EapSharedKeyL(HBufC8* aSharedKey); + void EapIndication(TNotification aNotification); + +private: // implementation + + CIkev2EapIf(MIkev2EapIfObserver& aEapIfObserver, TUint8 aEapType, MIkeDebug& aDebug); + void ConstructL(CIkeData* aIkeData); + +private: // data + MIkev2EapIfObserver& iEapIfObserver; + CEapVpnInterface* iEapPlugin; // Own: ECOM plug-in + HBufC8* iIdentity; // Identity buffer + HBufC8* iMSK; // Preshared key + TInt iErrorStatus; // Error status, if construct fails + TUint8 iEapType; + TUint8 iReserved[3]; // Dummy for alignment + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; +}; + +// +// Internal EAP event codes used in IKEv2 plug-in EapEventL() calls +// +const TInt KEapEventSuccess = 0; +const TInt KEapEventGetIdentity = 1; +const TInt KEapEventGetPSK = 2; +const TInt KEapEventFailed = 3; + +#endif // __IKEV2EAPINTERFACE_H_ + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2Negotiation.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2Negotiation.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,329 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 negotiation +* +*/ +#ifndef _IKEV2NEGOTIATION_H_ +#define _IKEV2NEGOTIATION_H_ + +#include + +#include "ikev2SAdata.h" +#include "ikev2natt.h" +#include "pfkeymsg.h" +#include "ikev2payloads.h" +#include "ikev2mobike.h" +#include "ikev2retransmittimer.h" +#include "ikecrypto.h" +#include "ikemsgrec.h" +#include "kmdapi.h" +#include "ikev2pkiservice.h" +#include "ikecert.h" +#include "ipsecsaspiretriever.h" +#include "ikev2ipsecsadata.h" +#include "ikev2EapInterface.h" + +static const TUint16 KMaxSendAttemps = 6; + +#define DEF_MSG_ID_WINDOW 1 + +#define IKEV2_DEF_NONCE_SIZE (160/8) //160 bits = 20 bytes +#define IKEV2_MIN_NONCE_SIZE (128/8) //128 bits = 16 bytes +#define IKEV2_DEF_LIFETIME 14400 //4 hours + +// +// IKE/IPSEC SA negotiation states +// +const TInt KStateIdle = 0; +const TInt KStateIkeInitPkiService = 1; +const TInt KStateIkeSaInitRequest = 2; +const TInt KStateIkeSaAuthRequest = 4; +const TInt KStateIkeWaitingId = 5; +const TInt KStateIkeSaEapStarted = 6; +const TInt KStateIkeSaEapGoing = 7; + +const TInt KStateIkeSaInitResponse = 11; +const TInt KStateIkeSaAuthWaitSpi = 12; +const TInt KStateIkeSaAuthResponse = 14; + + +const TInt KStateIkeSaCompleted = 20; + +const TInt KStateIkeChildSARequest = 21; +const TInt KStateIkeChildSAResponse = 22; + +const TInt KStateIkeSARekeyRequest = 23; +const TInt KStateIkeSARekeyResponse = 24; + +const TInt KStateIkeInfoRequest = 31; +const TInt KStateIkeInfoResponse = 32; +const TInt KStateIkeDeleteRequest = 33; +const TInt KStateIkeDeleteResponse = 34; +const TInt KStateChildDeleteRequest = 35; +const TInt KStateChildDeleteResponse = 36; + +class CIkev2PluginSession; +class CPFKeySocketIf; +class CIkev2Config; +class CIkeData; +class CIkev2Acquire; +class CIkev2Expire; +class MKmdEventLoggerIf; +class MIkeDebug; +class CIkeV2Message; +class CIkeV2Identity; +class CIkev2MessageSendQueue; + +/** + * CIkev2Negotiation + * + * @lib internal (ikev2lib.lib) + */ +NONSHARABLE_CLASS(CIkev2Negotiation) : public CBase, + public MIkeV2PkiServiceObserver, + public MIpsecSaSpiRetrieverCallback, + public MIkev2EapIfObserver, + public MIkev2RetransmitTimerCallback + { + friend class Ikev2MobIke; + +public: + + /** + * NewL + * + * @since S60 ?S60_version + * @param aControl Plugin control. Must be != NULL + * ownership not taken. + * @param aIkeData ?description + * @param aVpnIapId ?description + * @param aPhysicalInterfaceAddress IP address of the physical connection with scope. + * @param aRemote ?description + * @return self + */ + static CIkev2Negotiation* NewL(CIkev2PluginSession& aIkeV2PlugInSession, + CPFKeySocketIf& aPfKeySocketIf, + MKmdEventLoggerIf& aEventLogger, + CIkev2MessageSendQueue& aMessageSendQue, + MIkeDebug& aDebug, + CIkeData* aIkeData, + TUint32 aVpnIapId, + TUint32 aSAId, + TInetAddr aPhysicalInterfaceAddress, + TInetAddr aRemoteAddress); + + /** + * NewL + * + * @since S60 ?S60_version + * @param aControl Plugin control. Must be != NULL + * ownership not taken. + * @param aSAId ?description + * @return self + */ + static CIkev2Negotiation* NewL(CIkev2PluginSession& aIkeV2PlugInSession, + CPFKeySocketIf& aPfKeySocketIf, + MKmdEventLoggerIf& aEventLogger, + CIkev2MessageSendQueue& aMessageSendQue, + MIkeDebug& aDebug, + TIkev2SAData& aIkev2SAdata); + + ~CIkev2Negotiation(); + + void StartIkeSANegotiationL(); + TBool StartRespondingL(const ThdrISAKMP& aIkeMessage); + void StartIkeSADeleteL(); + void ProcessIkeMessageL(const ThdrISAKMP& aIkeMessage, const TInetAddr& aRemote, TUint16 aLocalPort); + void ProcessAcquireL(const TPfkeyMessage& aPfkeyMessage); + void ProcessExpireL(const TPfkeyMessage& aPfkeyMessage); + void StartIpsecSaRekeyingL(const TPfkeyMessage &aPfkeyMsg); + void BuildIkeSaRekeyMsgL(TBool aRequest); + + void SendKeepAliveMsgL(); + + TBool Stopped(); + + void CancelOperation(); + +// from base class MIkeV2PkiServiceObserver + void IkeV2PkiInitCompleteL(TInt aStatus); + +// from base class MIpsecSaSpiRetrieverCallback + void IpsecSaSpiRetrieved(TUint32 aSpiRequestId, + TInt aStatus, + TUint32 aSpi); + + +// from base class MIkev2EapIfObserver + void SendEapDataL(HBufC8* aEapData); + void EapEventL(TInt aEvent); + +// from base class MIkev2RetransmitTimerCallback + + /** + * From MIkev2RetransmitTimerCallback + * Request IKE request resend. + */ + void RetransmitRequest(); + +private: // implementation + CIkev2Negotiation(CIkev2PluginSession& aIkeV2PlugInSession, + CPFKeySocketIf& aPfKeySocketIf, + MKmdEventLoggerIf& aEventLogger, + CIkev2MessageSendQueue& aMessageSendQue, + MIkeDebug& aDebug, + TUint32 aSaId); + void ConstructL(); + + TBool ImplicitChildSa(); + HBufC8* PeekProposedSa(); + HBufC8* GetProposedSa(); + void SetProposedSa(HBufC8* aSaPl); + + CIkev2Acquire** GetAcquireQue(); + CIkev2Expire** GetExpireQue(); + TBool RequestsPending(); + void SetNotifyCode(TInt aMsgType); + TInt GetNotifyCode(); + void StoreNotifyData32(TUint32 aData); + void StoreNotifyData16(TUint16 aData); + TUint8* NotifyData(TInt& aDataLth); + TInetAddr GetLocalAddr() const; + + void IkeSaCompletedL(); + void IkeSaFailed(TInt aStatus = KKmdIkeNoResponseErr); + void IpsecSANegotiatedL(); + void CheckNotifyCodeL(CIkev2Payloads* IkeMsg); + void CreateIkeSPI(TIkeSPI& aSPI, TBool aRekey=EFalse); + void GetNatStatus(TBool aSupported, const TInetAddr& aRemote); + void GetIpsecSPI(CIkev2Acquire* aAcquire); + + void GetNonceDataL(TBool aInitiator); + void GetOwnIdentityL(TBool aEapIdResponse=EFalse); + + void LoadEapPluginL(); + TBool InitPkiServiceL(); + void StartIkeSaInitL(); + void SendIkeAuthMessageL(); + + void ContinueIkeNegotiationL(); + void BuildChildSAMessageL(CIkev2Acquire* aAcquire, TBool aInitiator); + void BuildDeleteRequestL(CIkev2Expire* aExpire); + + //Send the ike message. Claims the ownership of the message. + void SendIkeMsgL(CIkeV2Message* aMsg); + + TBool ProcessIkeSaInitL(CIkev2Payloads* aIkeMsg, const TInetAddr& aRemote); + TBool ProcessIkeAuthL(CIkev2Payloads* aIkeMsg); + TBool ProcessChildSaL(CIkev2Payloads* aIkeMsg); + TBool ProcessInfoMsgL(CIkev2Payloads* aIkeMsg); + TBool ProcessIkeSARekeyL(CIkev2Payloads* aIkeMsg); + TBool ProcessDeletePayloadsL(const CArrayFixFlat& aDeletes, TBool aRequest); + TBool ProcessNotifyPayloadsL(const CArrayFixFlat& aNotifys, TBool aRequest, TInt aExchange); + TBool ProcessCookieL(const CArrayFixFlat& aNotifys, TBool aRequest); + void ProcessInvalidKePayloadNotifyL(); + + void GenerateIkeKeysL(TIkev2SAData* aRekeydSaData=NULL); + + void SaveSignedDataL(TBool aLocal, const TDesC8& aIkeMsg); + void AddIdToSignedDataL(TBool aLocal, HBufC8* aSigned, const TDesC8& aIdData); + HBufC8* SignAuthDataL(const TDesC8& aAuthData, TUint8 aAuthMethod); + TBool AddIdAndAuthenticatePeerL(CIkev2Payloads* aIkeMsg); + TBool AuthenticatePeerL(TAuthPayloadIkev2* aAuth); + TBool VerifyPeerCertificateL(CArrayFixFlat* aCerts, TIDPayloadIkev2* aId ); + + TBool ProcessKeyExchangeL(TKEPayloadIkev2* aKePayload, TUint16 aGroup); + + void AppendKEPayloadL(CIkeV2Message& aIkeMsg, TUint16 aDHGroup); + + TPayloadIkev2* PadEncrPayload(HBufC8* aMsg, TPayloadIkev2* aEncrPl); + TUint16 TotalLength( TPayloadIkev2* aLoad, TPayloadIkev2* aLoad2 ); + TBool CheckPayloadsOrder(CIkev2Payloads* aIkeMsg, TUint8 aExchange, TBool aResponse); + TPayloadIkev2* BuildI2CertPayload(HBufC8* aMsg, TPayloadIkev2* aPrevPl); + TPayloadIkev2* BuildI1CertPayload(HBufC8* aMsg, TPayloadIkev2* aPrevPl); + + void IpsecSaSpiRetrievedL(TUint32 aSpiRequestId, TUint32 aSpi); + + /** + * Handles IKE datagram resend. + */ + void DoRetransmitL(TBool aResponse=EFalse); + +public: // Data + // + // Header Data (Common with IKEv2 SA) + // + TIkev2SAData iHdr; // Common negotiation info for IKE SA + TIkeV2IpsecSAData iChild; // Common negotiation info for IPSEC SA + CIkev2PluginSession& iIkeV2PlugInSession; // IKEv2 plugin engine + + + CIkev2Negotiation* iNext; // A link field to maintain negotiations. + +private: // Data + + CPFKeySocketIf& iPfKeySocketIf; + MKmdEventLoggerIf& iEventLogger; + CIkev2MessageSendQueue& iMessageSendQue; + MIkeDebug& iDebug; + + CIpsecSaSpiRetriever* iSpiRetriever; + + TInt iState; // Negotiation State + TUint32 iSAid_Rekey;// Rekeyed SAid + TIkeSPI iSPI_Rekey; // Local SPI for rekeyed IKE SA + TBool iStopped; // Negotiation failed indicator + TBool iDeleteIkeSA; // A notify message received from peer which requires IKE SA to be deleted + TBool iChildSARejected; // A notify message received which indicates that Child SA is not accepted + + TBool iDeactivateGoing; // Negotiation started due deactivate + TBool iCookieReturned; // Cookie returned to responder + TBool iPkiAuthRequired; // Private key signature is required as authentication + TBool iEapCompleted; // EAP authentication completed succesfully + TBool iPeerIdInSignedData; // Peer id has already been added to signed data + TBool iRekeyCollision; // Rekey collision occurred + TBool iProcessEvents; // Indicates whether the object is accepting events (not accepting when destructor called) + + CIkev2RetransmitTimer* iTimer; // Timer to retransmit IKE request message + CDHKeys* iDHKeys; // Diffie-Hellman calculation object + CIkev2NatT* iNatNotify; // Pointer to IKEv2 NAT Traversal object + CIkev2Config* iConfigMode; // Pointer to IKEv2 Config object + CIkev2EapIf* iEapPlugin; // Pointer to IKEv2 EAP interface object + CIkeV2PkiService* iPkiService; // Pointer to PKI service Interface object + HBufC8* iSavedSaInit; // Saved IKE_SA_INIT request (waiting PKI service init) + HBufC8* iProposedSA; // Proposed IKE/IPSEC SA payload content + HBufC8* iDHPublicPeer; // Diffie-Hellman Public value (peer) + HBufC8* iNonce_I; // Initiator Nonce + HBufC8* iNonce_R; // Responder Nonce + HBufC8* iAuthMsgInit; // Signed octet buffer (for initiator AUTH payload) + HBufC8* iAuthMsgResp; // Signed octet buffer (for responder AUTH payload) + HBufC8* iPresharedKey; // Configured preshared key- or EAP MSK data buffer + + CIkeV2Identity* iLocalIdentity; + CIkeV2Identity* iRemoteIdentity; + + CX509Certificate* iPeerCert; // Verified peer certificate + + TUint16 iSendAttempt; + TInt iNotifyCode; // Error status for Notification payload + TInt iNotifyDataLth; // Notify data length + TUint8 iNotifyData[4]; // Short notify data packed into network order + + CIkev2Acquire* iChildSaRequest;// On going Child SA request + CIkev2Acquire* iAcquireFirst; // Pending PFKEY Acquire request + CIkev2Expire* iExpireFirst; // Pending PFKEY Expire request + + TInt iDHGroupGuess; //Number of DH group guess retries for IKE_SA_INIT resquest + }; +#endif // _IKEV2NEGOTIATION_H_ diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2SA.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2SA.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,79 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 SA data definition +* +*/ + +#ifndef _IKEV2SA_H_ +#define _IKEV2SA_H_ + +#include "ikev2SAdata.h" +#include "ikev2keepalive.h" + +class CIkev2PluginSession; +class TIkeV2IpsecSAData; +class MIkeDebug; + +// +// Class CIkev2SA +// +NONSHARABLE_CLASS(CIkev2SA) : public CTimer, public MIkeV2DpdHeartBeatEventHandler + { +public: + static CIkev2SA* NewL(CIkev2PluginSession& aIkeV2PluginSession, + TIkev2SAData& aIkev2SAdata, + MIkeDebug& aDebug); + ~CIkev2SA(); + + void UpdateL(TIkev2SAData* aIkev2SAdata, TIkeV2IpsecSAData* aIpsecSAData); + TBool RemoteAddrChanged(TInetAddr& aNewIp); + TIkeV2IpsecSAData* RemoveIpsecSaData(const TDesC8& aInSpi, const TDesC8& aOutSpi); + TIkeV2IpsecSAData* FindIpsecSaData(const TDesC8& aInSpi, const TDesC8& aOutSpi, TBool aRemove); + void DeleteIpsecSaData(const TDesC8& aInSpi, const TDesC8& aOutSpi); + void EventHandlerL(); + TIkeV2IpsecSAData* GetIpsecSaQue(); + void SetIpsecSaQue(TIkeV2IpsecSAData* aQue); + +private: + CIkev2SA(CIkev2PluginSession& aIkeV2PluginSession, MIkeDebug& aDebug); + void ConstructL(TIkev2SAData& aIkev2SAdata); + void StartTimer(); + void DeleteIpsecSas(TIkeV2IpsecSAData* aSa); + void LinkIpsecSa(TIkeV2IpsecSAData* aSa); + void PurgeIpsecDataQue(); + +protected: + // + // CActive methods + // + void DoCancel(); + void RunL(); + +public: + // + // Header Data + // + TIkev2SAData iIkeV2SaData; // Common negotiation info + CIkev2SA* iNext; // A link field to maintain negotiations. + +private: + CIkev2PluginSession& iIkeV2PluginSession; + MIkeDebug& iDebug; + TIkeV2IpsecSAData* iIpsecSaQue; // Ipsec SA information queue + CIkeV2KeepAlive* iIkeKeepAlive; // Pointer to common IKE keepalive object + TUint32 iRemainingTime; // Current lifetime left + + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2SAdata.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2SAdata.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,151 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 SA data definition +* Class TIkev2SAData is the IKEv2 SA parameter definition which +* is used to pass SA information between IKE server and IKEv2 +* plug-in. +* +*/ +#ifndef __IKEV2SADATA_H__ +#define __IKEV2SADATA_H__ +#include +#include +#include "ikemsgheader.h" +#include "internaladdress.h" +#include "ipsecsadata.h" +#include "ipsecsalifetime.h" +#include "ikev2message.h" + +class CIkeData; + +#define SECOND 1000000 // One second is 1000000 us. (1 us. per tick) + +// +// Private generic PFKEY extension type value +// +#define IKEV2_KEY_MATERIAL_SIZE 40 +#define IKEV2_MAX_IV_SIZE 16 + +class TIkev2SAData +{ +public: + TIkev2SAData(); + + void CleanUp(); + void FreeRespMsg(); + void FreeRequestMsg(); + void StoreVirtualIp(const TInetAddr& aVirtualAddr); + void SaveRespMsg(CIkeV2Message* aRespMsg); + void SaveRequestMsg(CIkeV2Message* aRequestMsg); + void Copy(TIkev2SAData& aSrc); + TUint32 SaId() const; + void SetSaId(TUint32 aSaId); + TIkeSPI& SpiI(); + void SetSpiI(const TIkeSPI& aSpiI); + TIkeSPI& SpiR(); + void SetSpiR(const TIkeSPI& aSpiR); + + void GenerateIkeKeyDerivatesL(const TDesC8& aSKEYSEED,TUint16 aPrfAlg, + const TDesC8& aNonceI, const TDesC8& aNonceR); + + /** + * Gets the request message ID we should use in our next + * request. + */ + TUint32 NextRequestId() const; + + /** + * Get the message ID we expecting see + * in a next received response. + */ + TUint32 ExpectedResponseId() const; + + /** + * Get the message ID we expecting see + * in a next received request. We should + * also use this message ID in our + * corresponding response. + */ + TUint32 ExpectedRequestId() const; + + +private: + TUint32 iSAId; // Internal negotiation Id + TIkeSPI iSPI_I; // Initiator SPI + TIkeSPI iSPI_R; // Responder SPI + +public: + + TInt iSAState; // IKE SA State + TBool iInitiator; // TRUE if local end is initiator + + CIkeData* iIkeData; + TUint32 iVpnIapId; + + TInetAddr iLocalAddr; // The address of the physical interface we are using. + TInetAddr iVirtualAddr; // The address assigned to the VPN interface by the SGW. + TInetAddr iRemoteAddr; // Remote Address ("From Policy") + TInetAddr iDestinAddr; // Current peer destination address and port. + // (Is different that iRemoteAddr, if the SGW is behind NAT) + + TUint32 iNATFlags; // If not zero, there is NAT between sites + TBool iFloatedPort; // If true floated port used (and NON-ESP-MARKER) + + TUint32 iWindowSize; // Message ID window size (currently 1) + CIkeV2Message* iLastResponse; // The last IKE response message buffer + CIkeV2Message* iLastRequest; // The last IKE response message buffer + TInt iRespRetryCount;// Count of response retries tranmitted in sequence + + // + // Selected IKE SA proposal + // + TUint16 iEncrAlg; // Encryption algorithm (transform ID 1) + TUint16 iPRFAlg; // Pseudo Random function (transform ID 2) + TUint16 iIntegAlg; // Integrity algorithm (transform ID 3) + TUint16 iDHGroup; // Diffie Hellmann Group(transform ID 4) + + TUint16 iEAPType; // EAP type if any + TUint16 iAuthMethod; // Authentication method selected + TUint32 iLifetime; // Local lifetime in seconds + TInt iCipherKeyLth; // Cipher key length + TInt iCipherBlkLth; // Cipher block length + TInt iIntChkSumLth; // Integrity checksum length + TBool iMobikeUsed; // MOBIKE protocol supported by both ends + // + // IKEv2 keymaterial + // + TBuf8 iSK_d; + TBuf8 iSK_ai; + TBuf8 iSK_ar; + TBuf8 iSK_ei; + TBuf8 iSK_er; + TBuf8 iSK_pi; + TBuf8 iSK_pr; +}; + + +// +// IKE SA states +// +const TInt KSaStateNotDefined = 0; +const TInt KSaStateReady = 1; +/* +const TInt KSaStateRekeying = 2; +const TInt KSaStateWaitingChildSa = 3; +const TInt KSaStateDeleting = 4; +const TInt KSaStateNotifying = 5; +const TInt KSaStateRoaming = 6; +*/ + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2acquire.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2acquire.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,133 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 Acquire definition +* Class CIkev2Acquire is a IKEv2 specific data structure +* containing information needed, when establishing a new +* IPsec SA +*/ + + +#ifndef __IKEV2ACQUIRE_H__ +#define __IKEV2ACQUIRE_H__ + +#include + +#include "ipsecsalifetime.h" + +class TPfkeyMessage; +class TInetAddr; +struct TIpsecSaSpec; +class CIpsecSARekeyData; +class TIkeV2TrafficSelector; + +// +// +// CIkev2Acquire +// This class is used to handle PFKEY Acquire primitives received from +// Ipsec plug-in. +// + +NONSHARABLE_CLASS(CIkev2Acquire) : public CBase +{ + public: + static CIkev2Acquire* NewL(const TPfkeyMessage& aPfkeyMessage, TUint32 aId, + const TInetAddr& aLocalAddr, TUint16 aDHGroup, TBool aImplicitSa, + const TIpsecSaSpec* aSaSpec = 0, const CIpsecSARekeyData* aRekeyData = 0); + static CIkev2Acquire* NewL(TUint32 aId, HBufC8* aSa, + CArrayFix* aTS_i, + CArrayFix* aTS_r ); + static void Link(CIkev2Acquire* aAcquire, CIkev2Acquire** aAnchor); + static CIkev2Acquire* Find(TUint32 aId, CIkev2Acquire** aAnchor, TBool aRemove=EFalse); + static void PurgeQue(CIkev2Acquire** aAnchor); + static TBool Responding(CIkev2Acquire** aAnchor); + static CIkev2Acquire* GetNext(CIkev2Acquire** aAnchor, TBool aResponse); + static void SetFirst(CIkev2Acquire* aAcquire, CIkev2Acquire** aAnchor); + static CIkev2Acquire* PeekFirst(CIkev2Acquire** aAnchor); + static CIkev2Acquire* RemoveFromQue(TUint32 aId, CIkev2Acquire** aAnchor); + + TUint32 Id(); + TPtrC8 SPI_In(); + TPtrC8 SPI_Out(); + TPtrC8 SPI_ToBeRekeyed(); + void SetSPI_In(const TDesC8& aSPI); + void SetSPI_Out(const TDesC8& aSPI); + void SetSPI_ToBeRekeyed(const TDesC8& aSPI); + TUint16 DHGroup(); + void DHGroup(TUint16 aDHGroup); + TBool Transport(); + void SetTransport(); + TBool Response(); + void SetResponse(); + void SetHardLifetime(const TIpsecSALifetime& aHard ); + TIpsecSALifetime* HardLifetime(); + void SetSoftLifetime(const TIpsecSALifetime& aSoft ); + TIpsecSALifetime* SoftLifetime(); + TUint8 ReplayWindow(); + void SetReplayWindow(TUint8 aReplayWindow); + TUint32 Pid(); + void SetPid(TUint32 aPfKeyPid); + TUint32 Seq(); + void SetSeq(TUint32 aPfKeySeq); + void SetVirtualIp(); + TBool ForVirtualIp(); + TBool SrcSpecific(); + void SetSrcSpecific(TBool aSrcSpecific); + TUint8 IpsecProtocol(); + void SetIpsecProtocol(TUint8 aProtocol); + + HBufC8* LocalId(); + HBufC8* RemoteId(); + HBufC8* SA()const; + void AddIpsecSpiToSa(const TDesC8& aSpi); + const CArrayFix& TS_i(); + const CArrayFix& TS_r(); + void ReplaceSA(HBufC8* aSA); + void ReplaceTS_i(CArrayFix* aTS); + void ReplaceTS_r(CArrayFix* aTS); + void ReplaceLocalId(HBufC8* aId); + void ReplaceRemoteId(HBufC8* aId); + + CIkev2Acquire(TInt aId); + ~CIkev2Acquire(); + + private: + void ConstructL(const TPfkeyMessage& aReq, const TInetAddr& aLocalAddr, TUint16 aDHGroup, TBool aImplicitSa, + const TIpsecSaSpec* aSaSpec, const CIpsecSARekeyData* aRekeyData); + + private: + TUint32 iId; // Unique sequence number for GETSPI + TBuf8<4> iSPIIn; // Ipsec SPI value in (local SPI) + TBuf8<4> iSPIOut; // Ipsec SPI value out (remote SPI) + TBuf8<4> iSPIToBeRekeyed;// Ipsec SPI value of IPSec SA to be rekeyed + TUint32 iDHGroup; // DH group for PFS + TBool iTransport; // Transport Mode requested + TBool iResponse; // Object is for Child SA response + TBool iSrcSpecific; // Requested SA is "local address" specific + TBool iForVirtualIp; // This Acquire is just for getting virtual IP + TInt iReplayWindow; // Ipsec replay window value + TInt iProtocol; // Ipsec protocol + TUint32 iPfKeyPid; // Saved from PFKEY Acquire + TUint32 iPfKeySeq; // Saved from PFKEY Acquire + TIpsecSALifetime iHard; + TIpsecSALifetime iSoft; + HBufC8* iSA; // Ipsec SA payload built from Pfkey Acquire + + CArrayFix* iTS_i; // Local Traffic selector info + CArrayFix* iTS_r; // Remote Traffic selector info + HBufC8* iLocalId; // Local Id data, if any + HBufC8* iRemoteId; // Remote Id data, if any + CIkev2Acquire* iNext; // Next pending acquire +}; + +#endif /* __IKEV2ACQUIRE_H__ */ diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2config.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This class is used to handle IKEv2 configuration payload attributes. +* +*/ +#ifndef __IKEV2CONFIG_H_ +#define __IKEV2CONFIG_H_ +#include +#include "vpnmandefs.h" + +class CIkev2Acquire; +class TCPPayloadIkev2; +class TDataAttributes; +class TInetAddr; +// +// +// CIkev2Config +// This class is used to handle IKEv2 config payload attributes +// + +NONSHARABLE_CLASS(CIkev2Config) : public CBase +{ + public: + static CIkev2Config* NewL(CIkev2Acquire* aAcquire, TInetAddr* aRemoteIp=NULL); + ~CIkev2Config(); + TBool ProcessCpL(TCPPayloadIkev2* aCpPayload); + TPtrC8 Cp() const; + TUint8 CpType() const; + TUint32 ExpireTime() const; + TVPNAddress VirtualIp(); + + + private: + void ConstructL(CIkev2Acquire* aAcquire, TInetAddr* aRemoteIp); + TInt AddAttribute(TDataAttributes* aAttr, TUint8 aType, TInt aLth, TUint8* aData); + + private: + TBool iRequestGoing; // CP Request going + TUint32 iAddressExpiry; // Address expiration time + HBufC8* iCp; // CP Payload buffer + TUint8 iCpType; + TVPNAddress iVIP; // Virtual IP +}; + + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2const.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2const.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,266 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 constants. +* +*/ + + +#ifndef _IKEV2CONST_H_ +#define _IKEV2CONST_H_ + +#include + +// +// All Headers with values in network byte order +// +#define MIN_IKEV2_PAYLOAD_SIZE 4 + + +//Version +#define MAJORV2 2 +#define MAJORV1 1 +#define MINOR 0 +#define MAJOR2MINOR0 (MAJORV2 << 4) + +// +// IKEv2 HEADER FLAGS (bits 0-2 reserved for IKEv1) +// +#define IKEV2_INITIATOR 0x8 // Original Initiator Bit +#define IKEV2_HIGHER_VERSION 0x10 // Higher version supported +#define IKEV2_RESPONSE_MSG 0x20 // Current message is a response + +// +// IKEv2 EXCHANGE TYPES +// +#define IKE_SA_INIT 34 +#define IKE_AUTH 35 +#define CREATE_CHILD_SA 36 +#define INFORMATIONAL 37 + +// +//Payload types +// +#define IKEV2_PAYLOAD_NONE 0 // (Terminator) +#define IKEV2_PAYLOAD_SA 33 // Security Association +#define IKEV2_PAYLOAD_PROP 2 // Proposal +#define IKEV2_PAYLOAD_TRANS 3 // Transform +#define IKEV2_PAYLOAD_KE 34 // Key Exchange +#define IKEV2_PAYLOAD_ID_I 35 // Identification (Initiator) +#define IKEV2_PAYLOAD_ID_R 36 // Identification (Responder) +#define IKEV2_PAYLOAD_CERT 37 // Certificate +#define IKEV2_PAYLOAD_CR 38 // Certificate Request +#define IKEV2_PAYLOAD_AUTH 39 // Authentication +#define IKEV2_PAYLOAD_NONCE 40 // Nonce +#define IKEV2_PAYLOAD_NOTIF 41 // Notification +#define IKEV2_PAYLOAD_DELETE 42 // Delete +#define IKEV2_PAYLOAD_VID 43 // Vendor ID +#define IKEV2_PAYLOAD_TS_I 44 // Traffic selector (initiator) +#define IKEV2_PAYLOAD_TS_R 45 // Traffic selector (Responder) +#define IKEV2_PAYLOAD_ENCR 46 // Encrypted +#define IKEV2_PAYLOAD_CONFIG 47 // Configuration +#define IKEV2_PAYLOAD_EAP 48 // Extensible Authentication + +#define IKEV2_PAYLOAD_PRIVATE 128 // Private use (up to 255) + +// +// Critical bit in general paylaod header +// Encrypted bit is an internal definition to indicate that received +// payload was encrypted (=received inside encrypted payload) +// +#define IKEV2_PL_CRITICAL 0x80 +#define IKEV2_PL_ENCRYPTED 0x01 +#define IKEV2_PL_SELECTED 0x02 + +// +// Protocol ID values +// +#define IKEV2_PROT_NONE 0 +#define IKEV2_PROTOCOL 1 +#define IKEV2_IPSEC_AH 2 +#define IKEV2_IPSEC_ESP 3 + +// +// Transform type values +// +#define IKEV2_ENCR 1 // IKE and ESP +#define IKEV2_PRF 2 // IKE +#define IKEV2_INTEG 3 // IKE, AH, optional in ESP +#define IKEV2_DH 4 // IKE, optional AH and ESP +#define IKEV2_ESN 5 // optional AH and ESP + +// +// Transform ID values for encryption algorithm type +// + +#define ENCR_DES_IV64 1 // RFC1827 +#define ENCR_DES 2 // RFC2405 +#define ENCR_3DES 3 // RFC2451 +#define ENCR_RC5 4 // RFC2451 +#define ENCR_IDEA 5 // RFC2451 +#define ENCR_CAST 6 // RFC2451 +#define ENCR_BLOWFISH 7 // RFC2451 +#define ENCR_3IDEA 8 // RFC2451 +#define ENCR_DES_IV32 9 // +#define ENCR_NULL 11 // RFC2410 +#define ENCR_AES_CBC 12 // RFC3602 +#define ENCR_AES_CTR 13 // RFC3664 + +// +// Attribute type values (used only with encryption algorithm transform) +// +#define IKEV2_ENCR_KEY_LTH 14 // + +// +// Transform ID values for Pseudo-random Function type +// +#define PRF_HMAC_MD5 1 // RFC2104 +#define PRF_HMAC_SHA1 2 // RFC2104 +#define PRF_HMAC_TIGER 3 // RFC2104 +#define PRF_AES128_CBC 4 // RFC3664 + +// +// Transform ID values for Integrity Algorithm type +// +#define AUTH_HMAC_MD5_96 1 // RFC2403 +#define AUTH_HMAC_SHA1_96 2 // RFC2403 +#define AUTH_DES_MAC 3 // +#define AUTH_KPDK_MD5 4 // RFC1826 +#define AUTH_AES_XCBC_96 5 // RFC3566 + +// +// Transform ID values for Diffie-Hellman group type +// +#define DH_GROUP_768 1 // Appendix B +#define DH_GROUP_1024 2 // Appendix B +#define DH_GROUP_1536 5 // RFC3526 +#define DH_GROUP_2048 14 // RFC3526 + + +// +//NOTIFY MESSAGES - ERROR TYPES +// +#define UNSUPPORTED_CRITICAL_PAYLOAD 1 +#define INVALID_IKE_SPI 4 +#define INVALID_MAJOR_VERSION 5 +#define INVALID_SYNTAX 7 +#define INVALID_MESSAGE_ID 9 +#define INVALID_SPI 11 +#define NO_PROPOSAL_CHOSEN 14 +#define INVALID_KE_PAYLOAD 17 +#define AUTHENTICATION_FAILED 24 +#define SINGLE_PAIR_REQUIRED 34 +#define NO_ADDITIONAL_SAS 35 +#define INTERNAL_ADDRESS_FAILURE 36 +#define FAILED_CP_REQUIRED 37 +#define TS_UNACCEPTABLE 38 +#define INVALID_SELECTORS 39 + +// +// NOTIFY MESSAGES - STATUS TYPES +// +#define INITIAL_CONTACT 16384 +#define SET_WINDOW_SIZE 16385 +#define ADDITIONAL_TS_POSSIBLE 16386 +#define IPCOMP_SUPPORTED 16387 +#define NAT_DETECTION_SOURCE_IP 16388 +#define NAT_DETECTION_DESTINATION_IP 16389 +#define COOKIE 16390 +#define USE_TRANSPORT_MODE 16391 +#define HTTP_CERT_LOOKUP_SUPPORTED 16392 +#define REKEY_SA 16393 +#define ESP_TFC_PADDING_NOT_SUPPORTED 16394 +#define NON_FIRST_FRAGMENTS_ALSO 16395 + +// +// NOTIFY MESSAGES CODES FOR MOBIKE +// +#define MOBIKE_SUPPORTED 16396 +#define ADDITIONAL_IPV4_ADDRESS 16397 +#define ADDITIONAL_IPV6_ADDRESS 16398 +#define UPDATE_SA_ADDRESS 16400 +#define COOKIE2 16401 +#define NAT_PREVENTION 16402 //Is this the same as NO_NATS_ALLOWED? +// NOTIFY MESSAGES ERROR CODES FOR MOBIKE +#define UNACCPETABLE_ADDRESSES 9500 +#define NAT_PREVENTED 9501 + +// +// IKEv2 Identity type codes +// +#define ID_NOT_DEFINED 0 +#define ID_IPV4_ADDR 1 +#define ID_FQDN 2 +#define ID_RFC822_ADDR 3 +#define ID_IPV4_ADDR_SUBNET 4 // For IPSEC ID:s +#define ID_IPV6_ADDR 5 +#define ID_IPV6_ADDR_SUBNET 6 // For IPSEC ID:s +#define ID_DER_ASN1_DN 9 +#define ID_KEY_ID 11 + +// +// IKEv2 Authentication methods +// +#define RSA_DIGITAL_SIGN 1 +#define PRESHARED_KEY 2 +#define DSS_DIGITAL_SIGN 3 + +// +// IKEv2 Traffic selector type values +// +#define TS_IPV4_ADDR_RANGE 7 +#define TS_IPV6_ADDR_RANGE 8 + +// +// IKEv2 CFG Types (For Config payload) +// +#define CFG_REQUEST 1 +#define CFG_REPLY 2 +#define CFG_SET 3 +#define CFG_ACK 4 + +// +// IKEv2 Configuration attributes +// +#define INTERNAL_IP4_ADDRESS 1 // 0 or 4 octets +#define INTERNAL_IP4_NETMASK 2 // 0 or 4 octets +#define INTERNAL_IP4_DNS 3 // 0 or 4 octets +#define INTERNAL_IP4_NBNS 4 // 0 or 4 octets +#define INTERNAL_ADDRESS_EXPIRY 5 // 0 or 4 octets +#define INTERNAL_IP4_DHCP 6 // 0 or 4 octets +#define APPLICATION_VERSION 7 // 0 or more +#define INTERNAL_IP6_ADDRESS 8 // 0 or 16 +#define INTERNAL_IP6_DNS 10 // 0 or 16 octets +#define INTERNAL_IP6_NBNS 11 // 0 or 16 octets +#define INTERNAL_IP6_DHCP 12 // 0 or 16 octets +#define INTERNAL_IP4_SUBNET 13 // 0 or 8 octets +#define SUPPORTED_ATTRIBUTES 14 // Multiple of 2 +#define INTERNAL_IP6_SUBNET 15 // 17 octets + +// +// IKEv2 Certificate Encoding codes +// +#define PKCS7_WRAPPED_X509_CERT 1 +#define PGP_CERTIFICATE 2 +#define DNS_SIGNED_KEY 3 +#define X509_CERTIFICATE_SIGN 4 +#define KERBEROS_TOKEN 6 +#define CERT_REVOCATION_LIST 7 +#define AUTHORITY_REVOCATION_LIST 8 +#define SPKI_CERTIFICATE 9 +#define X509_CERTIFICATE_ATTRIBUTE 10 +#define RAW_RSA_KEY 11 +#define HASH_AND_URL_X509_CERT 12 +#define HASH_AND_URL_X509_BUNDLE 13 + +#endif \ No newline at end of file diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2deactivationtimer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2deactivationtimer.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Timer to trigger cancellation of session deletion. +* +*/ + +#ifndef C_IKEV2DEACTIVATIONTIMER_H +#define C_IKEV2DEACTIVATIONTIMER_H + +#include + +/** + * Deactivation timer callback interface. + * Callback interface which is used by CIkev2DeactivationTimer object to + * notify about deactivation timeout. + * + */ +NONSHARABLE_CLASS(MIkev2DeactivationTimerCallback) + { +public: + /** + * Notifies about deactivation timeout. + */ + virtual void DeactivationTimeout() = 0; + }; + + +/** + * Deactivation timer. + * + */ +NONSHARABLE_CLASS(CIkev2DeactivationTimer) : public CTimer +{ +public: + static CIkev2DeactivationTimer* NewL(MIkev2DeactivationTimerCallback& aCallback); + ~CIkev2DeactivationTimer(); + + /** + * Issues a request to the timer. + */ + void IssueRequest(); + +protected: + void RunL(); + +private: + CIkev2DeactivationTimer(MIkev2DeactivationTimerCallback& aCallback); + + MIkev2DeactivationTimerCallback& iCallback; + +}; + +#endif // C_IKEV2DEACTIVATIONTIMER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2expire.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2expire.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* CExpire. This class is used to handle PFKEY Expire primitives received +* from IPSec plug-in. +* +*/ +#ifndef __IKEV2EXPIRE_H__ +#define __IKEV2EXPIRE_H__ + +#include + +class TPfkeyMessage; +// +// +// CIkev2Expire +// This class is used to handle PFKEY Expire primitives received from +// Ipsec plug-in. +// +class CIkev2Expire : public CBase +{ + public: + CIkev2Expire() {} + ~CIkev2Expire() {} + static CIkev2Expire* NewL(const TPfkeyMessage& aPfkeyMessage); + static CIkev2Expire* GetNext(CIkev2Expire** aAnchor); + static void Link(CIkev2Expire* aExpire, CIkev2Expire** aAnchor); + static void PurgeQue(CIkev2Expire** aAnchor); + TPtrC8 SPI(); + void SetSPI(const TDesC8& aSPI); + TUint8 Protocol(); + void SetProtocol(TUint8 aProt); + + private: + TBuf8<4> iSPI; // Ipsec SPI value in (local SPI) + TUint8 iProtocol; // Ipsec protocol code + TUint8 iReserved[3]; // For alignment + CIkev2Expire* iNext; // Next pending acquire + +}; + +#endif /* __IKEV2EXPIRE_H__ */ diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2identity.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2identity.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Identity data structure for IKEv2 +* +*/ + +#ifndef IKEV2IDENTITY_H_ +#define IKEV2IDENTITY_H_ + +#include + +NONSHARABLE_CLASS(CIkeV2Identity) : public CBase + { +public: + static CIkeV2Identity* NewL(TUint8 aIdType, const TDesC8& aIdentity); + ~CIkeV2Identity(); + + TUint8 IdType() const; + TPtrC8 Identity() const; + + /** + * Returns id payload data, excluding the + * IKE payload fixed header: + * + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! ID Type ! RESERVED | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ! ! + * ~ Identification Data ~ + * ! ! + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + TPtrC8 PayloadData() const; + +private: + void ConstructL(TUint8 aIdType, const TDesC8& aIdentity); + + HBufC8* iIdPayloadData; + }; + +#endif /* IKEV2IDENTITY_H_ */ diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2ipsecsadata.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2ipsecsadata.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 IPsec SA data definition +* Class TIkeV2IpsecSAData is the IKEv2 specific version of +* IPsec SA parameter definition which +* is used to pass SA information between store IPsec SA +* information internally by the IKEv2 plugin. +* +*/ + +#ifndef __IKEV2IPSECSADATA_H__ +#define __IKEV2IPSECSADATA_H__ + +#include + +class CIpsecSARekeyData; +class MIkeDebug; + +class TIkeV2IpsecSAData + { +public: + TIkeV2IpsecSAData(MIkeDebug& aDebug); + void Copy(const TIkeV2IpsecSAData& aSrc); + //void StoreKeyMaterial(HBufC8* aKeyMaterial); + void PurgeKeyMaterial(); + void DeleteRekeyData(); + + void GenerateIpsecKeysL(const TDesC8& aSKd, + const TDesC8& aGPowIr, + const TDesC8& aNonceI, + const TDesC8& aNonceR, + TUint16 aPrfAlg); + +public: + + + TBuf8<4> iSPI_In; // Local SPI + TBuf8<4> iSPI_Out; // Remote SPI + +// +// Selected IPSEC SA proposal +// + TUint16 iEncrAlg; // Encryption algorithm (transform ID 1) + TUint16 iIntegAlg; // Integrity algorithm (transform ID 3) + TUint8 iSaType; // AH, ESP SA type from pfkeyv2.h + TUint8 iESN; // 0 = no ESN; 1 = ESN with ESP + TInt iCipherKeyLth; // Cipher key length + TInt iIntegKeyLth; // Integrity key length + TBool iTransport; // if Transport mode value is ETrue + TBool iSrcSpecific; // if IPSec SA is source specific is ETrue + + CIpsecSARekeyData* iRekeyData; +// +// IPSEC keymaterial buffers +// + HBufC8* iKeyMaterial; // Cipher key buffer + TIkeV2IpsecSAData* iNext; // Next Ipsec SA pair + +private: + MIkeDebug& iDebug; + }; + + +#endif /* __IKEV2IPSECSADATA_H__ */ diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2ipsecsarekeydata.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2ipsecsarekeydata.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Rekey data +* +*/ + +#ifndef IKEV2IPSECSAREKEYDATA_H_ +#define IKEV2IPSECSAREKEYDATA_H_ + +#include +#include "ipsecsalifetime.h" +#include "ikev2trafficselector.h" + +class TIkeV2TrafficSelector; + +NONSHARABLE_CLASS(CIpsecSARekeyData) : public CBase + { +public: + static CIpsecSARekeyData* NewL(const TInt aReplayWindow, + const TIpsecSALifetime* aHard, + const TIpsecSALifetime* aSoft, + const CArrayFix& aTS_i, + const CArrayFix& aTS_r, + const TDesC8& aLocalId, const TDesC8& aRemoteId); + ~CIpsecSARekeyData(); + + TInt ReplayWindow() const; + TIpsecSALifetime HardLifetime() const; + TIpsecSALifetime SoftLifetime() const; + + const TPtrC8 LocalId() const; + const TPtrC8 RemoteId() const; + + /** + * Copies the initiator side traffic selectors. + * Ownership is transferrer + */ + CArrayFix* TsIL() const; + + /** + * Copies the responder side traffic selectors. + * Ownership is transferrer + */ + CArrayFix* TsRL() const; +private: + CIpsecSARekeyData(const TInt aReplayWindow, + const TIpsecSALifetime* aHard, + const TIpsecSALifetime* aSoft); + + void ConstructL(const CArrayFix& aTS_i, + const CArrayFix& aTS_r, + const TDesC8& aLocalId, const TDesC8& aRemoteId); + + + + CArrayFix* CopyTsL(const CArrayFix& aTS) const; + + // + // Saved from Acquire object for possible IPSec SA rekeying + // + TInt iReplayWindow; + TIpsecSALifetime iHard; + TIpsecSALifetime iSoft; + + + CArrayFix* iTS_i; + CArrayFix* iTS_r; + HBufC8* iLocalId; + HBufC8* iRemoteId; + }; + + +#endif /* IKEV2IPSECSAREKEYDATA_H_ */ diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2keepalive.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2keepalive.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,72 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Common keep alive object +* +*/ + +#ifndef _IKEV2KEEPALIVE_H_ +#define _IKEV2KEEPALIVE_H_ + + +#include +#include + +class CIkev2PluginSession; + +/** +* IKE keepalive event handler +* @internalComponent +*/ +class MIkeV2DpdHeartBeatEventHandler +{ + public: + /** + * IKE PKI service operation completed + * @internalComponent + * @param aStatus completion status of operation + * @param aObject pointer to CIkePkiService object + * + */ + virtual void EventHandlerL()=0; +}; + + +NONSHARABLE_CLASS(CIkeV2KeepAlive) : public CTimer +{ + public: + static CIkeV2KeepAlive* NewL(TInt DpdKeepAlive, + MIkeV2DpdHeartBeatEventHandler& aHandler); + ~CIkeV2KeepAlive(); + + protected: + // + // CActive methods + // + void DoCancel(); + void RunL(); + + private: // implementation + CIkeV2KeepAlive(TInt DpdKeepAlive, + MIkeV2DpdHeartBeatEventHandler& aHandler); + void ConstructL(); + void StartTimer(); + + private: // data + MIkeV2DpdHeartBeatEventHandler& iCallback; + + TInt iDpdKeepAlive; + TInt iRemainingTime; +}; + +#endif //_IKEV2KEEPALIVE_H_ diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2message.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2message.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,377 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class to represent IKEv2 payloads and to construct IKEv2 datagrams +* +*/ + +#ifndef IKEV2MESSAGE_H_ +#define IKEV2MESSAGE_H_ + +#include + +class CIkeCaList; +class CDesC8Array; +class TIkeV2TrafficSelector; +class CIkeV2Identity; + +NONSHARABLE_CLASS(CIkeV2Payload) : public CBase + { +public: + ~CIkeV2Payload(); + + TUint8 NextPayload() const; + void SetNextPayload(TUint8 aNextPayload); + + TUint16 PayloadLength() const; + void SetPayloadLength(TUint16 aLength); + + TPtrC8 PayloadData() const; + TUint8 PayloadType() const; + +protected: + CIkeV2Payload(TUint8 aPayloadType); + + HBufC8* iPayloadData; + +private: + TUint8 iPayloadType; + }; + + +NONSHARABLE_CLASS(CIkevV2CertReqPayload) : public CIkeV2Payload + { +public: + static CIkevV2CertReqPayload* NewL(const CIkeCaList& aCaList); + +private: + CIkevV2CertReqPayload(); + void ConstructL(const CIkeCaList& aCaList); + }; + +NONSHARABLE_CLASS(CIkevV2CertPayload) : public CIkeV2Payload + { +public: + static CIkevV2CertPayload* NewL(const TDesC8& aCertData); + +private: + CIkevV2CertPayload(); + void ConstructL(const TDesC8& aCertData); + }; + + + +NONSHARABLE_CLASS(CIkevV2SaPayload) : public CIkeV2Payload + { +public: + static CIkevV2SaPayload* NewL(const TDesC8& aSaData); + +private: + CIkevV2SaPayload(); + void ConstructL(const TDesC8& aSaData); + + }; + + +NONSHARABLE_CLASS(CIkevV2KePayload) : public CIkeV2Payload + { +public: + static CIkevV2KePayload* NewL(TUint16 aDHGroup, const TDesC8& aKeData); + +private: + CIkevV2KePayload(); + void ConstructL(TUint16 aDHGroup, const TDesC8& aKeData); + }; + + +NONSHARABLE_CLASS(CIkevV2NoncePayload) : public CIkeV2Payload + { +public: + static CIkevV2NoncePayload* NewL(const TDesC8& aNonceData); + +private: + CIkevV2NoncePayload(); + void ConstructL(const TDesC8& aNonceData); + }; + + +NONSHARABLE_CLASS(CIkevV2IdPayload) : public CIkeV2Payload + { +protected: + CIkevV2IdPayload(TUint8 aPayloadType); + void ConstructL(const CIkeV2Identity& aIdentity); + }; + +NONSHARABLE_CLASS(CIkevV2IdiPayload) : public CIkevV2IdPayload + { +public: + static CIkevV2IdiPayload* NewL(const CIkeV2Identity& aIdentity); + +private: + CIkevV2IdiPayload(); + }; + + +NONSHARABLE_CLASS(CIkevV2IdrPayload) : public CIkevV2IdPayload + { +public: + static CIkevV2IdrPayload* NewL(const CIkeV2Identity& aIdentity); + +private: + CIkevV2IdrPayload(); + }; + + +NONSHARABLE_CLASS(CIkeV2AuthPayload) : public CIkeV2Payload + { +public: + static CIkeV2AuthPayload* NewL(TUint8 aAuthMethod, const TDesC8& aAuthData); + +private: + CIkeV2AuthPayload(); + void ConstructL(TUint8 aAuthMethod, const TDesC8& aAuthData); + }; + + +NONSHARABLE_CLASS(CIkeV2NotifyPayload) : public CIkeV2Payload + { +public: + static CIkeV2NotifyPayload* NewL(TUint8 aProtocolId, + const TDesC8& aSpi, + TUint16 aNotifyType, + const TDesC8& aNotifyData); + +private: + CIkeV2NotifyPayload(); + void ConstructL(TUint8 aProtocolId, + const TDesC8& aSpi, + TUint16 aNotifyType, + const TDesC8& aNotifyData); + }; + + +NONSHARABLE_CLASS(CIkeV2ConfigurationPayload) : public CIkeV2Payload + { +public: + static CIkeV2ConfigurationPayload* NewL(TUint8 aCfgType, + const TDesC8& aConfigurationData); + +private: + CIkeV2ConfigurationPayload(); + void ConstructL(TUint8 aCfgType, + const TDesC8& aConfigurationData); + }; + + +NONSHARABLE_CLASS(CIkeV2VendorIdPayload) : public CIkeV2Payload + { +public: + static CIkeV2VendorIdPayload* NewL(const TDesC8& aVendorIdData); + +private: + CIkeV2VendorIdPayload(); + void ConstructL(const TDesC8& aVendorIdData); + }; + + +NONSHARABLE_CLASS(CIkeV2DeletePayload) : public CIkeV2Payload + { +public: + static CIkeV2DeletePayload* NewL(TUint8 aProtocolId, const CDesC8Array& aSpiList); + +private: + CIkeV2DeletePayload(); + void ConstructL(TUint8 aProtocolId, const CDesC8Array& aSpiList); + }; + + +NONSHARABLE_CLASS(CIkeV2EapPayload) : public CIkeV2Payload + { +public: + static CIkeV2EapPayload* NewL(const TDesC8& aEapData); + +private: + CIkeV2EapPayload(); + void ConstructL(const TDesC8& aEapData); + }; + + +NONSHARABLE_CLASS(CIkeV2TsPayload) : public CIkeV2Payload + { +protected: + CIkeV2TsPayload(TUint aPayloadType); + void ConstructL(const CArrayFix& aTsList); + }; + +class CIkeV2TsiPayload : public CIkeV2TsPayload + { +public: + static CIkeV2TsiPayload* NewL(const CArrayFix& aTsList); + +private: + CIkeV2TsiPayload(); + }; + +NONSHARABLE_CLASS(CIkeV2TsrPayload) : public CIkeV2TsPayload + { +public: + static CIkeV2TsrPayload* NewL(const CArrayFix& aTsList); + +private: + CIkeV2TsrPayload(); + }; + + +NONSHARABLE_CLASS(CIkeV2EncryptedPayload) : public CIkeV2TsPayload + { +public: + static CIkeV2EncryptedPayload* NewL(TUint aBlockSize); + + TUint BlockSize() const; + TPtrC8 InitializationVector() const; + + void SetContentLength(TUint16 aLength); +private: + CIkeV2EncryptedPayload(); + void ConstructL(TUint aBlockSize); + + TUint iBlockSize; + }; + +class MIkeDebug; +class TInetAddr; + +NONSHARABLE_CLASS(CIkeV2Message) : public CBase + { +public: + + /** + * Constructs new IKE message. + * + * @param aInitiatorSpi Initiator SPI + * @param aResponderSpi Responder SPI + * @param aExchangeType Type of the exchange. Possible values are: + * IKE_SA_INIT, IKE_AUTH, CREATE_CHILD_SA and INFORMATIONAL. + * @param aFlags Message flags. Possible flags are: + * IKEV2_INITIATOR and IKEV2_RESPONSE_MSG. + */ + static CIkeV2Message* NewL(const TDesC8& aInitiatorSpi, + const TDesC8& aResponderSpi, + TUint8 aExchangeType, + TBool aIntiator, + TBool aResponse, + TUint32 aMessageId, + MIkeDebug& aDebug); + ~CIkeV2Message(); + + TPtrC8 InitiatorSpi()const; + TPtrC8 ResponderSpi() const; + + TUint8 NextPayload() const; + + TUint8 MajorVersion() const; + TUint8 MinorVersion() const; + + TUint8 ExchangeType() const; + + TUint8 Flags() const; + + TUint32 MessageId() const; + + TUint32 Length() const; + + void AppendCertReqPayloadL(const CIkeCaList& aCaList); + void AppendCertPayloadL(const TDesC8& aCertificateData); + void AppendSaPayloadL(const TDesC8& aSaData); + void AppendKePayloadL(TUint16 aDHGroup, const TDesC8& aKeData); + void AppendNoncePayloadL(const TDesC8& aNonceData); + void AppendIdiPayloadL(const CIkeV2Identity& aIdentity); + void AppendIdrPayloadL(const CIkeV2Identity& aIdentity); + void AppendAuthPayloadL(TUint8 aAuthMethod, const TDesC8& aAuthData); + void AppendNotifyPayloadL(TUint8 aProtocolId, + const TDesC8& aSpi, + TUint16 aNotifyType, + const TDesC8& aNotifyData); + + /** + * A special method for adding a cookie notify in the + * beginning of an existing ike message. + */ + void PrependCookieNotifyPayloadL(const TDesC8& aCookieData); + + void AppendConfigurationPayloadL(TUint8 aCfgType, + const TDesC8& aConfigurationData); + void AppendVendorIdPayloadL(const TDesC8& aVendorIdData); + void AppendDeletePayloadL(TUint8 aProtocolId, const CDesC8Array& aSpiList); + void AppendEapPayloadL(const TDesC8& aEapData); + void AppendTsiPayloadL(const CArrayFix& aTsList); + void AppendTsrPayloadL(const CArrayFix& aTsList); + + /** + * Adds the encrypted payload to the message. + * The added encrypted payload has to be the first added payload. + */ + void AppendEncryptedPayloadL(TUint aBlockSize); + + + /** + * Gets the ike message datagram, which is ready to be + * send to the receiver. + * + * @param aEncryptionAlgorith Encryption algorithm to be used to encrypt the datagram. + * If the message does not contain an encryption payload, this + * parameter is ignored. + * @param aEncryptionKey Encryption key used to used to encrypt the datagram. + * If the message does not contain an encryption payload, this + * parameter is ignored. + * @param aIntegrityAlgorithm Algorithm used to calculate the integrity checks sum. + * If the message does not contain an encryption payload, this + * parameter is ignored. + * @param aSourceAddress Source address of the datagram. Needed for message tracing in + * debug builds. + * @param aDestinationAddress Destination address of the datagram. Needed for message tracing in + * debug builds. + */ + void PrepareIkeMessageDatagramL(TUint16 aEncryptionAlgorithm, + const TDesC8& aEncryptionKey, + TUint16 aIntegrityAlgorithm, + const TDesC8& aIntegrityKey, + const TInetAddr& aSourceAddress, + const TInetAddr& aDestinationAddress); + + TPtrC8 IkeMessageDatagram() const; +private: + CIkeV2Message(MIkeDebug& aDebug); + void ConstructL(const TDesC8& aInitiatorSpi, + const TDesC8& aResponderSpi, + TUint8 aExchangeType, + TBool aIntiator, + TBool aResponse, + TUint32 aMessageId); + + void AppendPayloadL(CIkeV2Payload* aPayload); + + void SetFlags(TUint8 aFlags); + void SetLength(TUint32 aDatagramLength); + void SetNextPayload(TUint8 aNextPayload); + + + MIkeDebug& iDebug; + HBufC8* iIkeV2MessageHeader; + RPointerArray iPayloads; + + TBool iModified; + HBufC8* iIkeV2Datagram; + }; + +#endif /* IKEV2MESSAGE_H_ */ diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2messagesendqueue.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2messagesendqueue.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,87 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 IKE message send que. +* +*/ + +#ifndef IKEV2MESSAGESENDQUEUE_H_ +#define IKEV2MESSAGESENDQUEUE_H_ + +#include +#include +#include "ikev2sender.h" + + +class MIkeDataInterface; +class MIkeDebug; + +class TIkeMsgWaitQueueObject + { +public: + TPtrC8 iIkeMsg; + TBool iFloatedPort; + }; + + +NONSHARABLE_CLASS(CIkev2MessageSendQueue) : public CActive, + public MIkev2SenderCallback + { +public: + static CIkev2MessageSendQueue* NewL(MIkeDataInterface& aDataInterface, + const TInetAddr& aDestinationAddress, + TUint8 aDscp, + TUint aNatKeepAliveInterval, + MIkeDebug& aDebug); + ~CIkev2MessageSendQueue(); + + void SendIkeMessageL(const TPtrC8 aIkeMsg, TBool aFloatedPort); + void CancelSend(const TPtrC8& aIkeMsg); + + void CancelAll(); + + void NewSaBehindNatL(TUint aSaId); + void SaBehindNatDeleted(TUint aSaId); + +protected: + void SendIkeMsgCompleted( TInt aStatus ); + + void RunL(); + void DoCancel(); + +private: + CIkev2MessageSendQueue(MIkeDataInterface& aDataInterface, + const TInetAddr& aDestinationAddress, + TUint8 aDscp, + TUint aNatKeepAliveInterval, + MIkeDebug& aDebug); + void ConstructL(); + void ArmKeepaliveTimer(); + + MIkeDataInterface& iDataInterface; + TUint iNatKeepAliveInterval; + TInetAddr iDestinationAddress; + TUint8 iDscp; + MIkeDebug& iDebug; + + CIkev2Sender* iSender; + RTimer iNatKeepaliveTimer; + + RArray iIkeMsgSendBuffer; //IkeMsgs waiting for send + TPtrC8 iIkeMsgInSending; //IkeMsgs, which is currently in sending + + RArray iSasBehindNat; + TUint iRemainingTime; + }; + +#endif /* IKEV2MESSAGESENDQUEUE_H_ */ diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2mobike.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2mobike.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 Mobility and Multihoming Protocol. +* +*/ +#ifndef _IKEV2MOBIKE_H_ +#define _IKEV2MOBIKE_H_ + +class CIkev2Negotiation; +class TNotifPayloadIkev2; + +class Ikev2MobIke + { +public: + static TBool ProcessNotifysL(CIkev2Negotiation* aNegotiation, + const CArrayFixFlat& aNotifys, + TBool aRequest, TInt Exchange); + static TBool SendUpdateSaAddrNotifyL(CIkev2Negotiation* aNegotiation); + + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2natt.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2natt.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Class CIkev2NatT implements NAT Traversal functionality specified in IKEv2. +* +*/ +#ifndef _IKEV2NATT_H_ +#define _IKEV2NATT_H_ + +class TNotifPayloadIkev2; +class TInetAddr; + +class CIkev2NatT : public CBase + { +public: + CIkev2NatT(){}; + static CIkev2NatT* NewL(const TInetAddr& aSourceAddr, const TInetAddr& aDestinationAddr, TUint16 aPort, + const TDesC8& aInitiatorSpi, const TDesC8& aResponderSpi); + ~CIkev2NatT() {delete iSrcNotify; delete iDstNotify; } + + static TUint32 CheckPeerNotifysL(const CArrayFixFlat& aNotifys, + const TInetAddr& aLocalAddr, const TInetAddr& aRemoteAddr, TUint16 aPort, + const TDesC8& aInitiatorSpi, const TDesC8& aResponderSpi, TBool& aSupported); + TPtrC8 SourceNofify() const { return *iSrcNotify;} + TPtrC8 DestinNofify() const { return *iDstNotify;} + +private: + void ConstructL(const TInetAddr& aSourceAddr, const TInetAddr& aDestinationAddr, TUint16 aPort, + const TDesC8& aInitiatorSpi, const TDesC8& aResponderSpi); + + HBufC8* GenerateNatDetectionHashL(const TDesC8& aInitiatorSpi, const TDesC8& aResponderSpi, + TInetAddr aIpAddress, TUint16 aPort) const; + + HBufC8* iSrcNotify; + HBufC8* iDstNotify; + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2payloads.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2payloads.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,571 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Payload classes. +* +*/ +#ifndef _IKEV2PAYLOADS_H_ +#define _IKEV2PAYLOADS_H_ +#include "ikev2const.h" +#include "ikemsgheader.h" + +// +// GENERIC PAYLOAD HEADER +// +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Next Payload !C! RESERVED ! Payload Length ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +class TPayloadIkev2 +{ + public: + static inline TInt Size() { return sizeof(TPayloadIkev2); } + static inline TPayloadIkev2* Cast(const TAny* aPayload) { return (TPayloadIkev2*)aPayload; } + inline void Init() { PUT32(&u.iData8[0], 0);} + inline TUint8 GetNextPayload() { return u.iData8[0]; } + inline void SetNextPayload(TUint8 aPayload) { u.iData8[0] = aPayload; } + inline TUint16 GetLength() const { return (TUint16)GET16(&u.iData8[2]); } + inline void SetLength(TUint16 aLength) { PUT16(&u.iData8[2], aLength); } + inline TBool GetCritical() const { return ((u.iData8[1] & IKEV2_PL_CRITICAL) == IKEV2_PL_CRITICAL); } + inline void SetReserved() { u.iData8[1] &= IKEV2_PL_CRITICAL; } + inline void SetCritical() { u.iData8[1] |= IKEV2_PL_CRITICAL; } + inline TUint8* PayloadPtr() { return (TUint8 *)((char *)this); } + inline TUint8* PayloadData() const + { return (TUint8 *)((char *)this + sizeof(*this)); } //returns a * to the specific data of this payload + inline const TUint PlDataLen() const + { if ( GetLength() > sizeof(*this) ) + return (GetLength() - sizeof(*this)); + else return 0; + } //returns a * to the specific data of this payload + inline TPayloadIkev2 *Next() const + { return (TPayloadIkev2 *)((char *)this + GetLength()); } + // + // The following methods are used to manage "ENCRYPTED" bit (0) + // in payload reserved field. This bit is set to 1 when a + // payload has been received within a encrypted payload. + // Encrypted bit is NEVER set into transmitted payload. + // + inline TBool Encrypted() const { return ((u.iData8[1] & IKEV2_PL_ENCRYPTED) == IKEV2_PL_ENCRYPTED); } + inline void SetEncrypted() { u.iData8[1] |= IKEV2_PL_ENCRYPTED; } + inline void ResetEncrypted() { u.iData8[1] &= ~IKEV2_PL_ENCRYPTED; } + + private: + union + { + TUint32 iData32[1]; + TUint16 iData16[2]; + TUint8 iData8[4]; + } u; +}; + +#define TSAPayload TPayloadIkev2 +#define TNoncePayload TPayloadIkev2 +#define TVendorPlIkev2 TPayloadIkev2 +#define TEAPPayloadIkev2 TPayloadIkev2 +// +// Transform Attributes +// +// In this phase there is only one attribute defined for IKEv2 which is +// encryption key length for transform type Encryption Algorithm +// +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// !A! Attribute Type ! AF=0 Attribute Length ! +// !F! ! AF=1 Attribute Value ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! AF=0 Attribute Value ! +// ! AF=1 Not Transmitted ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +class TDataAttributes +{ + public: + inline TInt Size() const { return sizeof(*this); } + inline TBool IsBasic() const {return ((u.iData8[0] & 0x80) != 0);} //return if basic attrib or variable + inline void SetBasic() { u.iData8[0] |= 0x80;} + inline void SetVariable() { u.iData8[0] &= 0x7f;} + inline TUint16 GetType() { return TUint16(GET16(&u.iData16[0]) & 0x7fff);} + inline void SetType(TUint16 aType) { PUT16(&u.iData16[0], aType);} + inline TUint16 GetValue() { return TUint16(GET16(&u.iData16[1]));} + inline void SetValue(TUint16 aValue) { PUT16(&u.iData16[1], aValue); } + inline TUint8* Data() {return (TUint8*)((TUint8*)this + Size());} + inline TDataAttributes* Next() + { + if ( IsBasic() ) + return (TDataAttributes*)((TUint8*)this + Size()); + else return (TDataAttributes*)((TUint8*)this + (Size() + (TInt)GetValue())); + } + + private: + union + { + TUint32 iData32[1]; + TUint16 iData16[2]; + TUint8 iData8[4]; + } u; +}; + +// +// Transform Payload +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! 0 (last) or 3 ! RESERVED ! Transform Length ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// !Transform Type ! RESERVED ! Transform ID ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! ! +// ~ Transform Attributes ~ +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +class TTransformIkev2 +{ + public: + static inline TTransformIkev2* Cast(const TAny* aPayload) { return (TTransformIkev2*)aPayload; } + inline void Init() { PUT32(&u.iData8[0], 0);} + inline TInt Size() const { return sizeof(*this); } + inline TUint8 GetType() const { return u.iData8[4]; }; + inline void SetType(TUint8 aPayload) { u.iData8[4] = aPayload; }; + inline TUint16 GetID() const { return (TUint16)GET16(&u.iData16[3]); }; + inline void SetID(TUint16 aId) { PUT16(&u.iData16[3], aId); }; + inline void SetReserved() { u.iData8[5] = 0; }; + inline TDataAttributes* Attributes() const {return (TDataAttributes*)((TUint8*)this + Size()); } + // + // The following methods are used to manage "SELECTED" bit (0) + // in teh Transform payload reserved field. This bit is set to 1 when + // the transform payload has been selected into acceptable + // proposal. + // "SELECTED" is NEVER set into transmitted payload. + // + inline TBool IsSelected() { return ((u.iData8[5] & IKEV2_PL_SELECTED) == IKEV2_PL_SELECTED);} + inline void Selected() { u.iData8[5] |= IKEV2_PL_SELECTED; } + inline void NotSelected() { u.iData8[5] &= ~IKEV2_PL_SELECTED; } + + private: + union + { + TUint32 iData32[2]; + TUint16 iData16[4]; + TUint8 iData8[8]; + } u; + +}; + +// +// Proposal Payload +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! 0 (last) or 2 ! RESERVED ! Proposal Length ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Proposal # ! Protocol ID ! SPI Size !# of Transforms! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ~ SPI (variable) ~ +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! ! +// ~ ~ +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +class TProposalIkev2 +{ + public: + static inline TProposalIkev2 *Cast(const TAny* aPayload) { return (TProposalIkev2 *)aPayload;} + inline TInt Size() const { return sizeof(*this); } + inline TUint8 GetNum() const { return u.iData8[4]; } + inline void SetNum(TUint8 aNumber) { u.iData8[4] = aNumber; } + inline TUint8 GetProtocol() const { return u.iData8[5]; } + inline void SetProtocol(TUint8 aProtocol) { u.iData8[5] = aProtocol; } + inline TUint8 GetSPISize() const { return u.iData8[6]; } + inline void SetSPISize(TUint8 aSpiSize) { u.iData8[6] = aSpiSize; } + inline TUint8 GetNumTrans() const { return u.iData8[7]; }; + inline void SetNumTrans(TUint8 aNumber) { u.iData8[7] = aNumber; } + inline TTransformIkev2* TransformPl() const //next payload (transform) + { return (TTransformIkev2*)((TUint8*)this + sizeof(*this) + GetSPISize()); } + inline TUint8 *SPI() {return (TUint8 *)((TUint8*)this + sizeof(*this));} //*to the SPI + inline void GetIpsecSPI(TUint32* aSPI) const {Mem::Copy( (TUint8*)aSPI, ((TUint8*)this + sizeof(*this)), 4); } + inline void SetIpsecSPI(TUint32 aSPI) { Mem::Copy(((TUint8*)this + sizeof(*this)), (TUint8*)&aSPI, 4); } + inline TInt PropHdrLth() const { return (Size() + (TInt)GetSPISize()); } + inline TBool Last() const { return u.iData8[0] == 0;} + + private: + union + { + TUint32 iData32[2]; + TUint16 iData16[4]; + TUint8 iData8[8]; + } u; + +}; + +// +// Key Exchange Payload +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Next Payload !C! RESERVED ! Payload Length ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! DH Group # ! RESERVED ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! ! +// ~ Key Exchange Data ~ +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +class TKEPayloadIkev2 +{ + public: + static inline TKEPayloadIkev2 *Cast(const TAny* aPayload) { return (TKEPayloadIkev2 *)aPayload;} + static inline TInt Size() { return sizeof(TKEPayloadIkev2); } + inline TUint16 GetDHGroup() const { return (TUint16)GET16(&u.iData16[2]); }; + inline void SetDHGroup(TUint16 aGroup) { PUT16(&u.iData16[2], aGroup); }; + inline void SetReserved() { PUT16(&u.iData16[3], 0); }; + inline TUint8 *DHPublic() {return (TUint8 *)((TUint8*)this + sizeof(*this));} + inline TUint8 GetNextPayload() { return u.iData8[0]; } + + private: + union + { + TUint32 iData32[2]; + TUint16 iData16[4]; + TUint8 iData8[8]; + } u; + +}; + +// +// Identification Payload +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Next Payload !C! RESERVED ! Payload Length ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! ID Type ! RESERVED | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! ! +// ~ Identification Data ~ +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +class TIDPayloadIkev2 +{ + public: + static inline TIDPayloadIkev2 *Cast(const TAny* aPayload) { return (TIDPayloadIkev2 *)aPayload;} + static inline TInt Size() { return sizeof(TIDPayloadIkev2); } + inline TUint8 GetIdType() { return u.iData8[4]; }; + inline void SetIdType(TUint8 aIdType) { u.iData8[4] = aIdType; }; + inline void SetReserved() { PUT16(&u.iData16[3], 0); u.iData8[5] = 0; }; + inline TUint8 *IdData() {return (TUint8*)((TUint8*)this + sizeof(*this));} + inline TUint8 GetNextPayload() { return u.iData8[0]; } + + private: + union + { + TUint32 iData32[2]; + TUint16 iData16[4]; + TUint8 iData8[8]; + } u; + +}; + +// +// Authentication Payload +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Next Payload !C! RESERVED ! Payload Length ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Auth Method ! RESERVED ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! ! +// ~ Authentication Data ~ +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +class TAuthPayloadIkev2 +{ + public: + static inline TAuthPayloadIkev2 *Cast(const TAny* aPayload) { return (TAuthPayloadIkev2 *)aPayload;} + static inline TInt Size() { return sizeof(TAuthPayloadIkev2); } + inline TUint8 GetAuthMethod() { return u.iData8[4]; }; + inline void SetAuthMethod(TUint8 aMethod) { u.iData8[4] = aMethod; }; + inline void SetReserved() { PUT16(&u.iData16[3], 0); u.iData8[5] = 0; }; + inline TUint8 *AuthData() {return (TUint8*)((TUint8*)this + sizeof(*this));} + + private: + union + { + TUint32 iData32[2]; + TUint16 iData16[4]; + TUint8 iData8[8]; + } u; + +}; + +// +// Traffic Selector Payload +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Next Payload !C! RESERVED ! Payload Length ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Number of TSs ! RESERVED ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! ! +// ~ ~ +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +class TTSPayloadIkev2 +{ + public: + static inline TTSPayloadIkev2 *Cast(const TAny* aPayload) { return (TTSPayloadIkev2 *)aPayload;} + static inline TInt Size() { return sizeof(TTSPayloadIkev2); } + inline TUint8 GetNumberOfTs() { return u.iData8[4]; }; + inline void SetNumberOfTs(TUint8 aNumber) { u.iData8[4] = aNumber; }; + inline void SetReserved() { PUT16(&u.iData16[3], 0); u.iData8[5] = 0; }; + inline TUint8* TrafficSelectors() {return (TUint8*)((TUint8*)this + sizeof(*this));} + inline TUint8 GetNextPayload() { return u.iData8[0]; } + + private: + union + { + TUint32 iData32[2]; + TUint16 iData16[4]; + TUint8 iData8[8]; + } u; + +}; + +// +// Traffic Selector +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! TS Type !IP Protocol ID*| Selector Length | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Start Port* | End Port* | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! ! +// ~ Starting Address* ~ +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! ! +// ~ Ending Address* ~ +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +class TTrafficSelector +{ + public: + static inline TTrafficSelector* Cast(const TAny* aPayload) { return (TTrafficSelector *)aPayload;} + static inline TInt Size() { return sizeof(TTrafficSelector); } + inline void Init() { PUT32(&u.iData8[0], 0); PUT32(&u.iData8[4], 0); }; + inline void SetLength(TUint16 aLth) { PUT16(&u.iData8[2], aLth); }; + inline void SetType(TUint8 aType) { u.iData8[0] = aType; }; + inline void SetProtocol(TUint8 aProt) { u.iData8[1] = aProt; }; + inline void SetStartPort(TUint16 aPort) { PUT16(&u.iData8[4], aPort); }; + inline void SetEndPort(TUint16 aPort) { PUT16(&u.iData8[6], aPort); }; + inline TUint16 Length() const { return (TUint16)GET16(&u.iData8[2]); }; + inline TUint16 StartPort() const { return (TUint16)GET16(&u.iData8[4]); }; + inline TUint16 EndPort() const { return (TUint16)GET16(&u.iData8[6]); }; + inline TUint8 Protocol() const { return u.iData8[1]; }; + inline TUint8 Type() const { return u.iData8[0]; }; + inline const TUint8 *Addresses() const {return (TUint8*)((TUint8*)this + sizeof(*this));} + private: + union + { + TUint32 iData32[2]; + TUint16 iData16[4]; + TUint8 iData8[8]; + } u; + +}; + + +// +// Certificate Payload +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Next Payload !C! RESERVED ! Payload Length ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Cert Encoding ! ! +// +-+-+-+-+-+-+-+-+ ! +// ~ Certificate Data ~ +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +class TCertPayloadIkev2 +{ + public: + static inline TCertPayloadIkev2 *Cast(const TAny* aPayload) { return (TCertPayloadIkev2 *)aPayload;} + static inline TInt Size() { return sizeof(TPayloadIkev2) + sizeof(char); } + inline TUint8 GetEncoding() const { return u.iData8[4]; }; + inline void SetEncoding(TUint8 aEncoding) { u.iData8[4] = aEncoding; }; + inline TUint8 *Certificate() const {return (TUint8*)((TUint8*)this + Size());} + inline TUint8 GetNextPayload() const { return u.iData8[0]; } + + private: + union + { + TUint8 iData8[5]; + } u; +}; +// +// Certificate Request Payload +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Next Payload !C! RESERVED ! Payload Length ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Cert Encoding ! ! +// +-+-+-+-+-+-+-+-+ ! +// ~ Certification Authority ~ +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +class TCReqPayloadIkev2 +{ + public: + static inline TCReqPayloadIkev2 *Cast(const TAny* aPayload) { return (TCReqPayloadIkev2 *)aPayload;} + static inline TInt Size() { return sizeof(TPayloadIkev2) + sizeof(char); } + inline TUint8 GetEncoding() const { return u.iData8[4]; }; + inline void SetEncoding(TUint8 aEncoding) { u.iData8[4] = aEncoding; }; + inline TUint8* Authority() const {return (TUint8*)((TUint8*)this + Size());} + inline TUint8 GetNextPayload() { return u.iData8[0]; } + + private: + union + { + TUint8 iData8[5]; + } u; +}; + +// +// Notify Payload +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Next Payload !C! RESERVED ! Payload Length ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Protocol ID ! SPI Size ! Notify Message Type ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! ! +// ~ Security Parameter Index (SPI) ~ +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! ! +// ~ Notification Data ~ +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +class TNotifPayloadIkev2 +{ + public: + static inline TNotifPayloadIkev2 *Cast(const TAny* aPayload) { return (TNotifPayloadIkev2 *)aPayload;} + static inline TInt Size() { return sizeof(TNotifPayloadIkev2); } + inline TUint8 GetProtocolId() { return u.iData8[4]; }; + inline void SetProtocolId(TUint8 aProtId) { u.iData8[4] = aProtId; }; + inline TUint8 GetSPISize() const { return u.iData8[5]; } + inline void SetSPISize(TUint8 aSpiSize) { u.iData8[5] = aSpiSize; } + inline TUint16 GetMsgType() const { return (TUint16)GET16(&u.iData16[3]); }; + inline void SetMsgType(TUint16 aType) { PUT16(&u.iData16[3], aType); }; + inline TUint8* SPI() {return (TUint8*)((TUint8*)this + sizeof(*this));} + inline TUint8* NotifData() const {return (TUint8*)((TUint8*)this + Size() + GetSPISize());} + inline TUint NotifDataLength() const { return TPayloadIkev2::Cast(this)->GetLength() - Size() - GetSPISize(); } + private: + union + { + TUint32 iData32[2]; + TUint16 iData16[4]; + TUint8 iData8[8]; + } u; + +}; + +// +// Delete Payload +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Next Payload !C! RESERVED ! Payload Length ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Protocol ID ! SPI Size ! # of SPIs ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! ! +// ~ Security Parameter Index(es) (SPI) ~ +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +class TDeletePlIkev2 +{ + public: + static inline TDeletePlIkev2 *Cast(const TAny* aPayload) { return (TDeletePlIkev2 *)aPayload;} + static inline TInt Size() { return sizeof(TDeletePlIkev2); } + inline TUint8 GetProtocolId() const { return u.iData8[4]; }; + inline void SetProtocolId(TUint8 aProtId) { u.iData8[4] = aProtId; }; + inline TUint8 GetSPISize() const { return u.iData8[5]; } + inline void SetSPISize(TUint8 aSpiSize) { u.iData8[5] = aSpiSize; } + inline TUint16 GetNbrOfSpis() const { return (TUint16)GET16(&u.iData16[3]); }; + inline void SetNbrOfSpis(TUint16 aType) { PUT16(&u.iData16[3], aType); }; + inline const TUint8* SPIs() const {return (TUint8*)((TUint8*)this + sizeof(*this));} + private: + union + { + TUint32 iData32[2]; + TUint16 iData16[4]; + TUint8 iData8[8]; + } u; + +}; + +// +// Configuration Payload +// 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! Next Payload !C! RESERVED ! Payload Length ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! CFG Type ! RESERVED ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// ! ! +// ~ Configuration Attributes ~ +// ! ! +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// +class TCPPayloadIkev2 +{ + public: + static inline TCPPayloadIkev2 *Cast(const TAny* aPayload) { return (TCPPayloadIkev2 *)aPayload;} + static inline TInt Size() { return sizeof(TCPPayloadIkev2); } + inline TUint8 GetCFGType() { return u.iData8[4]; }; + inline void SetCFGType(TUint8 aCFGType) { u.iData8[4] = aCFGType; }; + inline void SetReserved() { PUT16(&u.iData16[3], 0); u.iData8[5] = 0; }; + inline TDataAttributes* Attributes() {return (TDataAttributes*)((TUint8*)this + sizeof(*this));} + + private: + union + { + TUint32 iData32[2]; + TUint16 iData16[4]; + TUint8 iData8[8]; + } u; + +}; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2pfkey.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2pfkey.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Utility methods to handle PFKEY messaging +* +*/ +#ifndef __IKEV2PFKEY +#define __IKEV2PFKEY + +#include + +class CIkev2Acquire; +class TIkeV2IpsecSAData; +class TIkev2SAData; +class CIkev2PluginSession; + +class Ikev2Pfkey +{ + public: + static void UpdateIpsecSaDataBaseL(const TIkev2SAData& aIkev2SA, + const TIkeV2IpsecSAData& aChild, + CIkev2PluginSession& aIkePluginSession, + CIkev2Acquire& aAcquire); + + static CIkev2Acquire* DeleteInboundSPI(const TIkev2SAData& aIkev2SA, + CIkev2PluginSession& aIkePluginSession, + CIkev2Acquire* aAcquire); + + private: + static const TUint8* GetIpsecKeys(TPtrC8* aEncrKey, TPtrC8* aIntegKey, const TUint8* aKeyMaterial, TInt aCipherKeyLth, TInt aIntegKeyLth); +}; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2plugin.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2plugin.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE v2 Protocol plug-in. +* +*/ +#if !defined(__IKEV2PLUGIN_H__) +#define __IKEV2PLUGIN_H__ + +#include +#include + +#include "ikepluginif.h" +#include "pfkeysocketif.h" + +class CIkev2PluginSession; +class CIpsecSaSpecList; +class CIpsecPolicyUtil; + + +NONSHARABLE_CLASS(CIkev2PlugIn) : public CBase, + public MIkePluginIf, + public MPFKeyMessageListener + +/** +* IKEv2 protocol plugin +* @internalComponent +*/ + { +public: + static CIkev2PlugIn* NewL( MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ); + ~CIkev2PlugIn(); + + MIkePluginSessionIf* CreateSessionL( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + MIkeDataInterface& aIkeDataInterface ); + + void PfkeyMessageReceived( const TPfkeyMessage& aPfkeyMessage ); + void PluginSessionDeleted(const MIkePluginSessionIf* aDeletedSession); + +private: + CIkev2PlugIn( MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ); + void ConstructL(); + + + RPointerArray iPluginSessions; + MKmdEventLoggerIf& iEventLogger; + MIkeDebug& iDebug; + + CPFKeySocketIf* iPfKeySocketIf; + CIpsecPolicyUtil* iIpsecPolicyUtil; + }; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2pluginsession.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2pluginsession.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,303 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 plugin session, handles one IKEv2 vpn connection +* +*/ + +#ifndef C_IKEV2PLUGINSESSION_H +#define C_IKEV2PLUGINSESSION_H + +#include + +#include "ikepluginsessionif.h" +#include "ikev2receiver.h" +#include "ikev2deactivationtimer.h" + + +class MIkeDataInterface; +class CIkev2PlugIn; +class MKmdEventLoggerIf; +class MIkeDebug; +class CIkev2Negotiation; +class CIkev2SA; +class TIkev2SAData; +class TIkeV2IpsecSAData; +class CIkev2Receiver; +class TIpsecSaSpec; +class TIpsecSAData; +class TPfkeyMessage; +class CIpsecSaSpecList; +class CPFKeySocketIf; +class CIpsecPolicyUtil; +class CIkev2MessageSendQueue; + + +NONSHARABLE_CLASS(CIkev2PluginSession) : public CBase, + public MIkePluginSessionIf, + public MIkev2ReceiverCallback, + public MIkev2DeactivationTimerCallback + { +public: + static CIkev2PluginSession* NewL( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + MIkeDataInterface& aDataInterface, + CIkev2PlugIn& aPlugin, + CPFKeySocketIf& aPfKeySocketIf, + CIpsecPolicyUtil& aIpsecPolicyUtil, + MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ); + ~CIkev2PluginSession(); + + /** + * Starts negotiation with a peer. + * + * @param aIkeData IKE policy data + * @param aVpnInterfaceIndex VPN interface index + * @param aInternalAddress Internal address (returned) + * @param aStatus Completion status (returned) + */ + void NegotiateWithHost( const CIkeData& aIkeData, + TVPNAddress& aInternalAddress, + TRequestStatus& aStatus ); + + /** + * Cancels negotiate request. DeleteSession() method needs to be called + * after this method to delete session. + */ + void CancelNegotiateWithHost(); + + /** + * Deletes session. IKE/IPSec SA:s are deleted. + * + * @param aSilentClose Specified if a silent close in question (Delete + * payloads not transmitted to peer) + * @param aStatus Completion status (returned) + */ + void DeleteSession( const TBool aSilentClose, + TRequestStatus& aStatus ); + + /** + * Cancels deletion requests. IKE/IPSec SA:s are deleted. + */ + void CancelDeleteSession(); + + void NotifyError( TRequestStatus& aStatus ); + + /** + * Cancels error notification request. + */ + void CancelNotifyError(); + + + /** + * Requests notification about change of internal address. + * + * @param aStatus Completion status (returned) + */ + void NotifyInternalAddressChanged( TVPNAddress& aInternalAddress, + TRequestStatus& aStatus ); + + /** + * Cancels internal address notification request. + */ + void CancelNotifyInternalAddressChanged(); + + void IkeMessageReceivedL( const ThdrISAKMP& aIkeMessage, + const TInetAddr &aRemote, + TUint16 aLocalPort ); + + void LinkNegotiation( CIkev2Negotiation* aNegotiation ); + void RemoveNegotiation( CIkev2Negotiation* aNegotiation ); + + CIkev2SA* FindIkev2SA( TUint32 aSAId, + TInt aRequiredState, + TInt aNewState ); + TBool UpdateIkev2SAL( TIkev2SAData* aIkev2SAData, + TIkeV2IpsecSAData* aIpsecSAData ); + TIkeV2IpsecSAData* FindIpsecSAData( TUint32 aSAId, + const TDesC8& aSpi, + TBool aInbound ); + void DeleteIkev2SA( TUint32 aSAId ); + + TUint32 GetSAId(); + TBool CreateIkev2SAL( TIkev2SAData& aIkev2SAData ); + + void IkeSaCompleted( TInt aStatus, + TVPNAddress& aInternalAddress ); + void VirtualIpChanged( TVPNAddress& VirtualIp ); + + void StartResponding(); + void StopResponding(); + + void DeleteIpsecSAData( TUint32 aSAId, + const TDesC8& aSpi, + TBool aInbound ); + + void IkeSaDeleted( TInt aStatus ); + + CIpsecSaSpecList* GetIPsecSaSpecListL( const TInetAddr& aLocalAddr, + const TInetAddr& aLocalMask, + const TInetAddr& aRemoteAddr, + const TInetAddr& aRemoteMask, + TInt aProtocol ); + + TBool InheritIpsecSas( TUint32 aDstSAId, + TUint32 aSrcSAId ); + + TUint32 VpnInterfaceIndex() const; + TBool RemoteAddrChanged( TIkev2SAData* aIkev2SAData, + TInetAddr& aNewIp ); + + void KeepAliveIkeSAL( TIkev2SAData* aIkev2SAdata ); + CIkev2Negotiation* FindNegotiation( TUint32 aSAId, + TInt aRequiredState ); + + TBool DeleteIkeSAL( TIkev2SAData* aIkev2SAdata, + TBool aNormal ); + void RekeyIkeSAL( TIkev2SAData* aIkev2SAdata ); + + void DeleteIpsecSA( const TUint32 aSPI, + const TInetAddr& aSrc, + const TInetAddr& aDst, + const TUint8 aProtocol ); + + void AddSAL( const TIpsecSAData& aSAData ); + void UpdateSAL( const TIpsecSAData& aSAData ); + + void PfkeyMessageReceived( const TPfkeyMessage& aPfkeyMessage ); + + TBool MatchDestinationAddress( const TInetAddr& aDestAddr ) const; + +// from base class MIkev2ReceiverCallback + + /** + * From MIkev2ReceiverCallback. + * Notification about received IKE message. + * @param aIkeMsg IKE message + * @param aSrcAddr Source IP address/port + * @param aLocalPort Local port + */ + void IkeMsgReceived( const ThdrISAKMP& aIkeMsg, + const TInetAddr& aSrcAddr, + TInt aLocalPort); + + /** + * From MIkev2ReceiverCallback. + * Notification about receive error. + * @param aStatus Error value + */ + void ReceiveError( TInt aError ); + + +// from base class MIkev2DeactivationTimerCallback + + /** + * From MIkev2DeactivationTimerCallback + * Notification about deactivation timeout. + */ + void DeactivationTimeout(); + + +private: + CIkev2PluginSession( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + MIkeDataInterface& aDataInterface, + CIkev2PlugIn& aPlugin, + CPFKeySocketIf& aPfKeySocketIf, + CIpsecPolicyUtil& aIpsecPolicyUtil, + MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ); + void ConstructL(); + + + void DoNegotiateWithHostL( const CIkeData& aIkeData ); + void DoDeleteIkeSAExhangeL( TIkev2SAData& aIkev2SAdata ); + + TIkev2SAData* FindIkev2SAData( TUint32 aSAId, + TInt aRequiredState, + TInt aNewState ); + TBool CheckIkeMessageHeader( const ThdrISAKMP& aIkeMessage, + TUint32& NegotiationId ); + void PfkeyMessageReceivedL( const TPfkeyMessage& aPfkeyMessage ); + + /** + * Handles completion of client's negotiate request. + * @param aStatus Status + */ + void DoCompleteNegotiateWithHost( TInt aStatus ); + + /** + * Handles completion of client's delete session request. + * @param aStatus Status + */ + void DoCompleteDeleteSession( TInt aStatus ); + + /** + * Handles completion of client's notify error request. + * @param aStatus Status + */ + void DoCompleteNotifyError( TInt aStatus ); + + /** + * Cancels active operations. + */ + void DoCancelActiveOperations(); + + /** + * Cancels data transfer. + */ + void DoCancelDataTransfer(); + +private: // data + + TUint32 iVpnIapId; + TUint32 iVpnNetId; + MIkeDataInterface& iDataInterface; + CIkev2PlugIn& iPlugin; + CPFKeySocketIf& iPfKeySocketIf; + CIpsecPolicyUtil& iIpsecPolicyUtil; + MKmdEventLoggerIf& iEventLogger; + MIkeDebug& iDebug; + + TUint32 iSAIdSeed; + TUint32 iVpnInterfaceIndex; + + + TRequestStatus* iClientStatusNegotiate; + TVPNAddress* iInternalAddress; //Not owned by this class + CIkeData* iIkeData; + + CIkev2Negotiation* iFirstNegotiation; + CIkev2SA* iFirstIkev2SA; + + TRequestStatus* iClientStatusDelete; + + CIkev2Receiver* iReceiver; + CIkev2MessageSendQueue* iMessageSendQue; + + TRequestStatus* iClientStatusInternalAddressChange; + TVPNAddress* iChangedInternalAddress; + + TUint32 iCurrIkeSaRespCount; + + TRequestStatus* iClientStatusNotifyError; + + CIkev2DeactivationTimer* iDeactivationTimer; + TBool iActivated; + }; + + +#endif //C_IKEV2PLUGINSESSION_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2proposal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2proposal.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 Proposal handling. +* +*/ + + +#ifndef __IKEV2PROPOSAL_H_ +#define __IKEV2PROPOSAL_H_ +#include +#include "ikepolparser.h" +#include "ikemsgheader.h" + +class CIkev2Payloads; +class TPayloadIkev2; +class TProposalIkev2; +class TTransformIkev2; +class CIkeV2Identity; +class TIkev2SAData; +class TIkeV2IpsecSAData; + +class Ikev2Proposal +{ +public: + static HBufC8* FromPolicyToProposaL(TIkev2SAData& aIkeSaData, + const TDesC8& aRekeySpi, + TInt aDHGroupGuess, + TBool aRekey=EFalse); + static HBufC8* BuildSaResponseL(TProposalIkev2* aAcceptedProp, CIkev2Payloads* aAcceptedTrans); + static TBool GetSelectedProposalData(TIkev2SAData& aIkev2SaData, + TIkeV2IpsecSAData& aChildSaData, + const CIkev2Payloads& aAcceptedProp, + const TProposalIkev2& aProp); + static TBool VerifySaResponseL(TIkev2SAData& aIkeSaData, + TIkeV2IpsecSAData& aIpsecSaData, + const TDesC8& aReferenceSaData, + const CIkev2Payloads& aRespProp); + static TBool VerifySaRequestAndGetProposedSaBufferL(TIkev2SAData& aIkeSaData, + TIkeV2IpsecSAData& aIpsecSaData, + const TDesC8& aReferenceSaData, + const CIkev2Payloads& aProposed, + HBufC8*& aProposedSaBuffer); + static TBool VerifyProposaL(CIkev2Payloads* aReference, TProposalIkev2* aProposal, TIkev2SAData& aIkev2SaData); + static TBool CompareTransforms(CArrayFixFlat* aRefTrans, + CArrayFixFlat* aTrans); + static HBufC8* GetPSKFromPolicyL(CIkeData* aHostData); + static TBool IkeSaRekey(CIkev2Payloads* aIkeMsg); + static TBool GetRekeySpi(CIkev2Payloads* aIkeMsg, TIkeSPI& aSPI); + static void ChangeSpiInProposal(HBufC8* aSaBfr, TIkeSPI& aSPI); + static TUint16 GetDHGroup(TInt aDHGroup); + static CIkeV2Identity* GetRemoteIdentityL(CIkeData* aHostData); + + static inline TBool PkiServiceNeeded(CIkeData* aHostData) + { + ASSERT(aHostData); + if ( aHostData->iCAList && aHostData->iCAList->Count() ) + return ETrue; + else return EFalse; + } +}; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2receiver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2receiver.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,154 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Receiver of UDP datagrams +* +*/ + + +#ifndef C_IKEV2RECEIVER_H +#define C_IKEV2RECEIVER_H + +#include +#include + +// FORWARD DECLARATIONS +class MIkeDataInterface; +class ThdrISAKMP; + +/** + * IKEv2 receiver callback interface. + * Callback interface which is used by CIkev2Receiver object to notify + * about received IKE message. + * + * @lib internal (ikev2lib.lib) + */ +NONSHARABLE_CLASS(MIkev2ReceiverCallback) + { +public: + /** + * Notifies about received IKE message. + * + * @param aIkeMsg IKE message + * @param aSrcAddr Source IP address/port + * @param aLocalPort Local port + */ + virtual void IkeMsgReceived( const ThdrISAKMP& aIkeMsg, + const TInetAddr& aSrcAddr, + TInt aLocalPort ) = 0; + + /** + * Notifies about receive error. + * @param aStatus Error value + */ + virtual void ReceiveError( TInt aError ) = 0; + }; + +/** + * IKEv2 receiver. + * Active object provides functionality for receiving UDP datagrams. + * + * @lib internal (ikev2lib.lib) + */ +NONSHARABLE_CLASS(CIkev2Receiver) : public CActive + { +public: + /** + * Two-phased constructor. + * @param aDataInterface IKE data interface + * @param aCallback Callback interface + */ + static CIkev2Receiver* NewL( MIkeDataInterface& aDataInterface, + MIkev2ReceiverCallback& aCallback ); + + /** + * Destructor. + */ + ~CIkev2Receiver(); + + /** + * Starts receiving. + */ + void StartReceive(); + + /** + * Stops receiving. + */ + void StopReceive(); + +private: + + CIkev2Receiver( MIkeDataInterface& aDataInterface, + MIkev2ReceiverCallback& aCallback ); + + void ConstructL(); + + /** + * Receives UDP data. + */ + void DoReceive(); + +// from base class CActive + + /** + * From CActive + * Handles completion of receive. + */ + void RunL(); + + /** + * From CActive + * Handles cancellation of receive. + */ + void DoCancel(); + +private: // data + + /** + * UDP data. + * Own. + */ + HBufC8* iUdpData; + + /** + * Source IP address/port. + * Own. + */ + TInetAddr iSrcAddr; + + /** + * Local port. + * Own. + */ + TInt iLocalPort; + + /** + * Informs if data is received. + * Own. + */ + TBool iReceivingData; + + /** + * IKE data interface. + * Not own. + */ + MIkeDataInterface& iDataInterface; + + /** + * Callback interface. + * Not own. + */ + MIkev2ReceiverCallback& iCallback; + }; + +#endif // C_Ikev2Receiver_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2retransmittimer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2retransmittimer.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Timer to trigger IKE request resend, if do not obtain a reply +* +*/ + +#ifndef C_IKEV2RETRANSMITTIMER_H +#define C_IKEV2RETRANSMITTIMER_H + +#include + +/** + * IKEv2 retransmit timer callback interface. + * Callback interface which is used by CIkev2RetransmitTimer object to request + * IKE request resend. + * + * @lib internal (ikev2lib.lib) + */ +NONSHARABLE_CLASS(MIkev2RetransmitTimerCallback) + { +public: + /** + * Request IKE request resend. + */ + virtual void RetransmitRequest() = 0; + }; + +/** + * IKEv2 retransmit timer. + * Triggers IKE request retransmit after timeout. + * + * @lib internal (ikev2lib.lib) + */ +NONSHARABLE_CLASS(CIkev2RetransmitTimer) : public CTimer +{ +public: + static CIkev2RetransmitTimer* NewL( MIkev2RetransmitTimerCallback& aCallback ); + ~CIkev2RetransmitTimer(); + + /** + * Issues a reques to the timer. + * The actual time out value is calculated: + * timeout = aSendAttempt * 1 second; + * + * @param aSendAttempt the current send attempt count + */ + void IssueRequest( TUint16 aSendAttempt ); + +protected: + void RunL(); + +private: + CIkev2RetransmitTimer( MIkev2RetransmitTimerCallback& aCallback ); + +private: // data + MIkev2RetransmitTimerCallback& iCallback; +}; +#endif // C_IKEV2RETRANSMITTIMER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2sender.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2sender.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,116 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Sender of UDP datagrams +* +*/ + + +#ifndef C_IKEV2SENDER_H +#define C_IKEV2SENDER_H + +#include + +// FORWARD DECLARATIONS +class MIkeDataInterface; +class TInetAddr; + +/** + * IKEv2 sender callback interface. + * Callback interface which is used by CIkev2Sender object to notify + * about completion of sending. + * + * @lib internal (ikev2lib.lib) + */ +NONSHARABLE_CLASS(MIkev2SenderCallback) + { +public: + /** + * Notifies about completion of sending. + * + * @param aStatus Completion status + * @param aMsg IKE message + */ + virtual void SendIkeMsgCompleted( TInt aStatus ) = 0; + + }; + +/** + * IKEv1 sender. + * Active object provides functionality for sending UDP datagrams. + * + * @lib internal (ikev1lib.lib) + */ +NONSHARABLE_CLASS(CIkev2Sender) : public CActive + { +public: + /** + * Two-phased constructor. + * @param aDataInterface IKE data interface + * @param aCallback Callback interface + */ + static CIkev2Sender* NewL( MIkeDataInterface& aDataInterface, + MIkev2SenderCallback& aCallback ); + + /** + * Destructor. + */ + ~CIkev2Sender(); + + /** + * Sends IKE message. + * @param aLocalPort Local port + * @param aDestAddr Destination IP address/port + * @param aIkeMsg IKE message + */ + void SendIkeMsg( TInt aLocalPort, + TInetAddr& aDestAddr, + TUint8 aDscp, + const TDesC8& aIkeMsg ); + + +private: + + CIkev2Sender( MIkeDataInterface& aDataInterface, + MIkev2SenderCallback& aCallback ); + +// from base class CActive + + /** + * From CActive + * Handles completion of asynchronous sending. + */ + void RunL(); + + /** + * From CActive + * Handles cancellation of asynchronous sending. + */ + void DoCancel(); + +private: // data + + /** + * IKE data interface. + * Not own. + */ + MIkeDataInterface& iDataInterface; + + /** + * Callback interface. + * Not own. + */ + MIkev2SenderCallback& iCallback; + }; + +#endif // C_IKEV2SENDER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ikev2trafficselector.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ikev2trafficselector.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class that represents traffic selectors in IKEv2 +* +*/ + + +#ifndef IKEV2TRAFFICSELECTOR_H_ +#define IKEV2TRAFFICSELECTOR_H_ + +#include +#include + +class TIkeV2TrafficSelector + { +public: + + /** + * Parses the traffic selector from IKEv2 datagrams + * TrafficSelector payloads TrafficSelector + * + * If the traffic selector can not be parsed, the method leaves with + * KErrArgument. + */ + static TIkeV2TrafficSelector* NewL(const TDesC8& aIkeV2TrafficSector); + + TIkeV2TrafficSelector(TInetAddr aStartingAddress, TInetAddr aEndingAddress, TUint8 aProtocolId); + TIkeV2TrafficSelector(const TIkeV2TrafficSelector& aTrafficSelector); + + TInetAddr StartingAddress() const; + TInetAddr EndingAddress() const; + TInetAddr Mask() const; + + TUint8 ProtocolId() const; + + /** + * Possible values are: + * TS_IPV4_ADDR_RANGE and TS_IPV6_ADDR_RANGE + */ + TUint8 Type() const; + HBufC8* IdFromTsL() const; + + bool operator>(const TIkeV2TrafficSelector& aOtherSelector) const; + bool operator<(const TIkeV2TrafficSelector& aOtherSelector) const; + bool operator!=(const TIkeV2TrafficSelector& aOtherSelector) const; + bool operator==(const TIkeV2TrafficSelector& aOtherSelector) const; + bool operator>=(const TIkeV2TrafficSelector& aOtherSelector) const; + bool operator<=(const TIkeV2TrafficSelector& aOtherSelector) const; + +private: + + TInetAddr CalcuateMask() const; + + TInetAddr iStartingAddress; //start address and port + TInetAddr iEndingAddress; //end address and port + + TInetAddr iMask; //Calculated from iStartingAddress and iEndingAddress + TUint8 iProtocolId; + }; + + +#endif /* IKEV2TRAFFICSELECTOR_H_ */ diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ipsecproposal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ipsecproposal.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IPSec Proposal handling. +* +*/ + +#ifndef __IPSECPROPOSAL_H_ +#define __IPSECPROPOSAL_H_ +#include + +class TPfkeyMessage; +class TPayloadIkev2; +class CIpsecSaSpecList; + +class IpsecProposal +{ +public: + static HBufC8* BuildIpsecSaRequestL(const TPfkeyMessage& aPfkeyMessage, TUint16 aDHGroup); + static HBufC8* BuildIpsecSaRequestL(const TUint8 aSaType, + const TUint8 aEncryptAlg, const TUint16 aEncryptMaxbits, + const TUint8 aAuthAlg, const TUint16 aFlags, TUint16 aDHGroup); + static HBufC8* BuildIpsecSaFromPolicyL(const CIpsecSaSpecList& aSaList, TUint16 aDhGroup); +}; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/inc/ipsecselectors.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/inc/ipsecselectors.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IPSec Traffic Selector handling. +* +*/ + +#ifndef __IPSECSELECTORS_H_ +#define __IPSECSELECTORS_H_ +#include + +class TPfkeyMessage; +class TTSPayloadIkev2; +class TTrafficSelector; +class TInetAddr; +class TPfkeyIdentity; +class CIkev2Acquire; +class CIkev2PluginSession; +class CIkev2Payloads; +class TIkeV2TrafficSelector; +class CIkev2PluginSession; + +class IpsecSelectors +{ +public: + /** + * Add aDhGroup, if PFS is used. + */ + static CIkev2Acquire* GetIpsecPolicyL(CIkev2PluginSession& aPluginSession, CIkev2Payloads* aIkeMsg, TInt aDhGroup = 0); + static CIkev2Acquire* BuildVirtualAcquireL(CIkev2PluginSession& aPluginSession); + static TBool VerifyTrafficSelectorsL(CIkev2Acquire* aAcquire, TTSPayloadIkev2* aTsI, TTSPayloadIkev2* aTsR ); + static void BuildTrafficSelectorsL(CIkev2Acquire* aAcquire, const TInetAddr& aLocalAddr, + const TPfkeyIdentity& aSrcIdent, const TPfkeyIdentity& aDstIdent, + TUint8 aProtocol); + static TIkeV2TrafficSelector IdentityToSelectorL(const TDesC8& aIdentity, TUint8 aProtocol=0); + static TBool GetRangeEndAddresses(TInetAddr& aStartAddr, TInetAddr& aEndAddr, TInt aPrefixLen); + static TBool ValidataTs(const CArrayFix& aTsRef, + const CArrayFix& aTs); + static TBool CheckPorts(TUint16 aStartRef, TUint16 aEndRef, TUint16 aStart, TUint16 aEnd ); + static TBool CheckAddresses(TUint8 aType, TUint8* aRefAddresses, TUint8* aAddresses ); + +}; + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/rom/ikev2lib.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/rom/ikev2lib.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Image description file for project +* IKEv2 Protocol Plug-in +* +*/ + + + +#ifndef __IKEV2LIB_IBY__ +#define __IKEV2LIB_IBY__ + +#ifdef SYMBIAN_EXCLUDE_IPSEC + +REM Feature IKEV2LIB not included in this rom + +#else + +file=ABI_DIR\BUILD_DIR\ikev2lib.dll SHARED_LIB_DIR\ikev2lib.dll + +#endif // SYMBIAN_EXCLUDE_IPSEC + +#endif // __IKEV2LIB_IBY__ + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/Ikev2Config.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/Ikev2Config.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,273 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This class is used to handle IKEv2 configuration payload attributes. +* +*/ + +#include "ikedebug.h" +#include "ikev2config.h" +#include "ikev2payloads.h" +#include "ikev2const.h" +#include "internaladdress.h" +#include "ipsecselectors.h" +#include "ikev2acquire.h" +#include "ikev2trafficselector.h" + +CIkev2Config* CIkev2Config::NewL(CIkev2Acquire* aAcquire, TInetAddr* aRemoteIp) +{ + CIkev2Config* Config = new (ELeave)CIkev2Config(); + CleanupStack::PushL(Config); + Config->ConstructL(aAcquire, aRemoteIp); + CleanupStack::Pop(Config); + return Config; +} + +CIkev2Config::~CIkev2Config() + { + delete iCp; + } + + +TBool CIkev2Config::ProcessCpL(TCPPayloadIkev2* Cp) +{ + ASSERT(Cp); + // + // Process received CP payload according to message type + // If CP request is going and reply received parse attributes to get + // Virtual IP and possible DNS addresses. If INTERNAL_ADDRESS_EXPIRY + // present save it into object too. (used as IKE SA lifetime). + // If CP request received sanity check attributes (CFG_REPLY has + // already been built on constructor ConstructL(). + // All other messages (CFG_SET and CFG_ACK) are silently discarded + // + TBool Status = EFalse; + + if ( (Cp->GetCFGType() == CFG_REQUEST) || (Cp->GetCFGType() == CFG_REPLY) ) + { + Status = ETrue; + + TInt AttrLth; + TUint32 Ipv4Addr; + TIp6Addr Ipv6Addr; //IPV6 raw address + TDataAttributes* Attribute = Cp->Attributes(); + TInt Lth = (TInt)(TPayloadIkev2::Cast(Cp)->GetLength()) - TCPPayloadIkev2::Size(); + + while ( Status && Lth ) + { + AttrLth = (TInt)Attribute->GetValue(); + switch ( Attribute->GetType() ) + { + + case INTERNAL_IP4_ADDRESS: + if ( (AttrLth == 0) || (AttrLth == 4) ) + { + if (AttrLth == 4) + { + Ipv4Addr = GET32(Attribute->Data()); + iVIP.iVPNIfAddr.SetAddress(Ipv4Addr); + } + } + else Status = EFalse; + break; + + case INTERNAL_IP4_DNS: + if ( (AttrLth == 0) || (AttrLth == 4) ) + { + if (AttrLth == 4) + { + Ipv4Addr = GET32(Attribute->Data()); + + //Only two DNS server addresses supported + if (iVIP.iVPNIfDNS1.IsUnspecified()) + { + iVIP.iVPNIfDNS1.SetAddress(Ipv4Addr); + } + else if (iVIP.iVPNIfDNS2.IsUnspecified()) + { + iVIP.iVPNIfDNS2.SetAddress(Ipv4Addr); + } + } + } + else Status = EFalse; + break; + + case INTERNAL_ADDRESS_EXPIRY: + if ( (AttrLth == 0) || (AttrLth == 4) ) + { + if ( AttrLth == 4 ) + { + iAddressExpiry = GET32(Attribute->Data()); + } + } + else Status = EFalse; + break; + + case INTERNAL_IP6_ADDRESS: + if ( (AttrLth == 0) || (AttrLth == 16) ) + { + if ( (AttrLth == 16)) + { + Mem::Copy(&Ipv6Addr.u.iAddr8, Attribute->Data(), sizeof(Ipv6Addr.u.iAddr8)); + iVIP.iVPNIfAddr.SetAddress(Ipv6Addr); + } + } + else Status = EFalse; + break; + + default: + // + // All other parameters are just ignored + // + break; + + } + + AttrLth += Attribute->Size(); + if ( Lth < AttrLth ) + { + Status = EFalse; + break; // Error + } + else Lth -= AttrLth; + + Attribute = Attribute->Next(); + + } + + if ( !Status && Cp->GetCFGType() != CFG_REPLY) + { + delete iCp; + iCp = NULL; + } + } + + return Status; +} + +void CIkev2Config::ConstructL(CIkev2Acquire* aAcquire, TInetAddr* aRemoteIp) +{ + ASSERT(aAcquire); + // + // Build either Config Payload Request or Reply depending on + // CIkev2Acquire object "role". + // If CIkev2Acquire is a request (=not response) build CFG_REQUEST + // If CIkev2Acquire is a response) build CFG_REPLY and replace initiator + // Traffic selector in CIkev2Acquire with Traffic selector containing + // "dummy" Virtual IP address built from CIkev2Acquire ID. + // + iCp = HBufC8::NewL(80); + TDataAttributes* Attributes = reinterpret_cast(const_cast(iCp->Ptr())); + TInt AttrLth = 0; + + if ( !aAcquire->Response() ) + { + iCpType = CFG_REQUEST; + AttrLth += AddAttribute(Attributes, INTERNAL_IP4_ADDRESS, 0, NULL); + Attributes = Attributes->Next(); + AttrLth += AddAttribute(Attributes, INTERNAL_IP4_DNS, 0, NULL); + } + else + { + // + // Build "dummy" virtual IPv4 + // + iCpType = CFG_REPLY; + TUint32 virtualIp = aAcquire->Id(); + if ( !aRemoteIp || + ((aRemoteIp->Family() == KAfInet6) && !aRemoteIp->IsV4Mapped() && !aRemoteIp->IsV4Compat())) + { + // + // "Dummy" virtual IPv4 is created from CIkev2Acquire object Id + // data. The address format is the following: 10.x.y.z where bit 1 is always 0 + // + virtualIp = aAcquire->Id(); + virtualIp &= 0xfdfdfd; + virtualIp |= 0x0a000000; + } + else + { + // + // "Dummy" virtual IPv4 is created from original peer + // address as follows: + // Original address: x.y.z.w ==> Virtual IP: 10.y.z.w + // If original address: 10.y.z.w ==> Virtual IP: 172.y.z.w + // + virtualIp = aRemoteIp->Address(); + if ( (virtualIp & 0xff000000 ) != 0x0a000000) + virtualIp = (virtualIp & 0xffffff) | 0x0a000000; + else virtualIp = (virtualIp & 0xffffff) | 0xac000000; + } + TInetAddr Ipv4Addr; + Ipv4Addr.SetAddress(virtualIp); + virtualIp = ByteOrder::Swap32(virtualIp); + AttrLth += AddAttribute(Attributes, INTERNAL_IP4_ADDRESS, 4, (TUint8*)&virtualIp); + + // + // Replace original Initiator Traffic selector with new based + // on "virtualIp" + // + __ASSERT_DEBUG(aAcquire->TS_i().Count() > 0, User::Invariant()); + TUint8 Protocol = aAcquire->TS_i()[0].ProtocolId(); + + CArrayFix* newSelectors = + new (ELeave) CArrayFixFlat(1); + CleanupStack::PushL(newSelectors); + TIkeV2TrafficSelector selector(Ipv4Addr, Ipv4Addr, Protocol); + newSelectors->AppendL(selector); + aAcquire->ReplaceTS_i(newSelectors); + CleanupStack::Pop(newSelectors); + } + iCp->Des().SetLength(AttrLth); +} + +TInt CIkev2Config::AddAttribute(TDataAttributes* aAttr, TUint8 aType, TInt aLth, TUint8* aData) +{ + ASSERT(aAttr); + // + // Set R-Bit zero by adding attribute as variable length attribute + // + aAttr->SetVariable(); + aAttr->SetType(aType); + aAttr->SetValue((TUint16)aLth); + if ( aLth && aData ) + Mem::Copy(aAttr->Data(), aData, aLth); + + return (aLth + aAttr->Size()); +} + +TPtrC8 CIkev2Config::Cp() const + { + __ASSERT_DEBUG(iCp != NULL, User::Invariant()); + return *iCp; + } + + +TUint8 CIkev2Config::CpType()const + { + return iCpType; + } + +TUint32 CIkev2Config::ExpireTime() const + { + return iAddressExpiry; + } + + +TVPNAddress CIkev2Config::VirtualIp() + { + TVPNAddress Vip = iVIP; + iVIP = TVPNAddress(); + return Vip; + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/Ikev2EapInterface.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/Ikev2EapInterface.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,165 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of classes CIkev2EapIf. +* +*/ + +#include +#include "ikedebug.h" +#include "ikev2EapInterface.h" +#include "ikev2payloads.h" +#include "ikev2const.h" +#include "ikepolparser.h" +#include "ikev2plugin.h" + +CIkev2EapIf* CIkev2EapIf::NewL(MIkev2EapIfObserver& aEapIfObserver, TUint8 aEapType, CIkeData* aIkeData, MIkeDebug& aDebug) + { + CIkev2EapIf* eapIf = new (ELeave)CIkev2EapIf(aEapIfObserver, aEapType, aDebug); + CleanupStack::PushL(eapIf); + eapIf->ConstructL(aIkeData); + CleanupStack::Pop(eapIf); + return eapIf; + } + +CIkev2EapIf::CIkev2EapIf(MIkev2EapIfObserver& aEapIfObserver, TUint8 aEapType, MIkeDebug& aDebug) +:iEapIfObserver(aEapIfObserver), iEapType(aEapType), iDebug(aDebug) + { + } + +void CIkev2EapIf::ConstructL(CIkeData* aIkeData) + { + // + // Construct EAP ECOM plug-in library. + // If ECOM plug-in loading fails return an error instead of leaving + // + DEBUG_LOG(_L("Constructing CEappluginInterface")); + iEapPlugin = CEapVpnInterface::NewL(this, ETrue); + DEBUG_LOG(_L("Starting CEappluginInterface")); + iEapPlugin->StartL(iEapType); + + HBufC8* RealmPrefixBfr = NULL; + HBufC8* ManualRealmBfr = NULL; + HBufC8* ManualUserNameBfr = NULL; + TPtrC8 RealmPrefix(NULL,0); + TPtrC8 ManualRealm(NULL,0); + TPtrC8 ManualUserName(NULL,0); + TBool HideIdentity(EFalse); + if ( aIkeData ) + { + HideIdentity = aIkeData->iEAPHideIdentity; + if ( aIkeData->iEAPRealmPrefix ) + { + RealmPrefixBfr = aIkeData->iEAPRealmPrefix->GetAsciiDataL(); + if ( RealmPrefixBfr ) + RealmPrefix.Set(RealmPrefixBfr->Des()); + } + if ( aIkeData->iEAPManualRealm ) + { + ManualRealmBfr = aIkeData->iEAPManualRealm->GetAsciiDataL(); + if ( ManualRealmBfr ) + ManualRealm.Set(ManualRealmBfr->Des()); + } + if ( aIkeData->iEAPManualUserName ) + { + ManualUserNameBfr = aIkeData->iEAPManualUserName->GetAsciiDataL(); + if ( ManualUserNameBfr ) + ManualUserName.Set(ManualUserNameBfr->Des()); + } + } + + DEBUG_LOG(_L("Calling CEappluginInterface::EapConfigure")); + iErrorStatus = iEapPlugin->EapConfigure( + ManualUserName, ManualRealm, RealmPrefix, HideIdentity); + + delete RealmPrefixBfr; + delete ManualRealmBfr; + delete ManualUserNameBfr; + } + +CIkev2EapIf::~CIkev2EapIf() + { + delete iEapPlugin; + delete iIdentity; + delete iMSK; + } + +void CIkev2EapIf::EapDataInbound(TPayloadIkev2* aEapPayload) + { + ASSERT(aEapPayload); + // + // Pass EAP payload data to EAP plug-in as inbound data + // + TInt Lth = (TInt)aEapPayload->PlDataLen(); + TPtrC8 EapData(aEapPayload->PayloadData(), Lth); + + DEBUG_LOG(_L("Calling CEappluginInterface::EapInbound")); + iEapPlugin->EapInbound(EapData); + } + +void CIkev2EapIf::QueryIdentity() + { + // + // Query identity information from EAP plugin for IKE Id + // + DEBUG_LOG(_L("Calling CEappluginInterface::QueryIdentity")); + iEapPlugin->QueryIdentity(); + } + +void CIkev2EapIf::EapOutboundL(HBufC8* aResponse) + { + // + // Pass outgoing EAP data to IKEv2 plug-in + // + DEBUG_LOG(_L("Data received from CEappluginInterface")); + iEapIfObserver.SendEapDataL(aResponse); + } + +void CIkev2EapIf::EapIdentityResponseL(HBufC8* aResponse) + { + // + // Pass Identity data to IKEv2 plug-in + // + DEBUG_LOG(_L("Identity received from CEappluginInterface")); + + delete iIdentity; + iIdentity = aResponse; + + iEapIfObserver.EapEventL(KEapEventGetIdentity); + } + +void CIkev2EapIf::EapSharedKeyL(HBufC8* aResponse) + { + // + // Pass pre-shared key material to IKEv2 plug-in + // + DEBUG_LOG(_L("MSK received from CEappluginInterface")); + + delete iMSK; + iMSK = aResponse; + + iEapIfObserver.EapEventL(KEapEventGetPSK); + } + +void CIkev2EapIf::EapIndication(TNotification aNotification) + { + // + // Pass EAP notification to IKEv2 plug-in + // + DEBUG_LOG1(_L("EAP indication received from CEappluginInterface: %d"), aNotification); + + TRAP_IGNORE( aNotification == ESuccess ? + iEapIfObserver.EapEventL(KEapEventSuccess) : + iEapIfObserver.EapEventL(KEapEventFailed) ); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikecrypto.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikecrypto.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,332 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Intermediate class between IKEv2 and crypto library. +* +*/ + + +#include "dhparameters.h" +#include "ikecrypto.h" +#include "ikev2const.h" + +CDHKeys* CDHKeys::NewL(const TDesC8& aN, const TDesC8& aG) +{ + CDHKeys *keys = new (ELeave) CDHKeys(); + keys->iDHKey = TUtlCrypto::MakeDiffieHellmanL(aN, aG); + keys->iModuluslength = aN.Length(); + return keys; +} + +CDHKeys* CDHKeys::CreateDHKeyL(TUint aGroupDesc) +{ + TPtrC8 prime_ptr(NULL, 0); + TPtrC8 gen_ptr(NULL, 0); + + switch (aGroupDesc) + { + case DH_GROUP_768: + prime_ptr.Set((TUint8 *)&MODP_768_PRIME[0], MODP_768_PRIME_LENGTH); + gen_ptr.Set((TUint8 *)&MODP_768_GENERATOR[0], MODP_768_GENERATOR_LENGTH); + break; + case DH_GROUP_1024: + prime_ptr.Set((TUint8 *)&MODP_1024_PRIME[0], MODP_1024_PRIME_LENGTH); + gen_ptr.Set((TUint8 *)&MODP_1024_GENERATOR[0], MODP_1024_GENERATOR_LENGTH); + break; + case DH_GROUP_1536: + prime_ptr.Set((TUint8 *)&MODP_1536_PRIME[0], MODP_1536_PRIME_LENGTH); + gen_ptr.Set((TUint8 *)&MODP_1536_GENERATOR[0], MODP_1536_GENERATOR_LENGTH); + break; + case DH_GROUP_2048: + prime_ptr.Set((TUint8 *)&MODP_2048_PRIME[0], MODP_2048_PRIME_LENGTH); + gen_ptr.Set((TUint8 *)&MODP_2048_GENERATOR[0], MODP_2048_GENERATOR_LENGTH); + break; + default: //Cannot happen because checked before!!! + User::Leave(KErrNotSupported); + } + + CDHKeys *DhKeys = CDHKeys::NewL(prime_ptr, gen_ptr); + + return DhKeys; +} + +HBufC8* CDHKeys::ComputeAgreedKeyL(const TDesC8 &aPeerPublicKey) +{ + return (HBufC8*)KValueL(aPeerPublicKey); +} + + +HBufC8* CDHKeys::GetPubKey() +{ + HBufC8* DHPublicKey = (HBufC8*)iPubKey; + iPubKey = NULL; // Exclusive ownership of iPubKey buffer is returned to caller + return DHPublicKey; +} + +void CDHKeys::XValueL() +{ + if ( !iPubKey ) + iPubKey = iDHKey->GenerateXL(); +} + +CDHKeys::~CDHKeys() +{ + delete iDHKey; +} + + +void IkeCrypto::DecryptL(const TUint8* aInput, TUint8* aOutput, TInt aLength, + TUint8* aIV, const TDesC8& aKey, TUint16 aEncrAlg) +{ + TUtlCrypto::TUtlSymmetricCipherId CipherId; + TInt IVLth; + IkeCrypto::AlgorithmInfo(IKEV2_ENCR, aEncrAlg, &IVLth, &CipherId); + + if ( !aInput || !aOutput || !aIV ) + User::Leave(KErrArgument); + + TPtrC8 IvPtr(aIV, IVLth); + TPtrC8 CipherText(aInput, aLength); + TPtr8 PlainText(aOutput, aLength); + + CUtlSymmetricCipher* UtlCipher = + TUtlCrypto::MakeSymmetricDecryptorL(CipherId, aKey, IvPtr); + CleanupStack::PushL(UtlCipher); + UtlCipher->ProcessFinalL(CipherText, PlainText); + CleanupStack::PopAndDestroy(UtlCipher); +} + + +void IkeCrypto::EncryptL(const TDesC8& aInput, TPtr8& aOutput, + const TDesC8& aIv, const TDesC8& aKey, TUint16 aEncrAlg) +{ + TUtlCrypto::TUtlSymmetricCipherId CipherId; + TInt CbLth; + IkeCrypto::AlgorithmInfo(IKEV2_ENCR, aEncrAlg, &CbLth, &CipherId); + + __ASSERT_DEBUG(CbLth == aIv.Length(), User::Invariant()); + __ASSERT_DEBUG(aInput.Length() % CbLth == 0, User::Invariant()); + __ASSERT_DEBUG(aInput.Length() <= aOutput.MaxLength(), User::Invariant()); + + CUtlSymmetricCipher* UtlCipher = + TUtlCrypto::MakeSymmetricEncryptorL(CipherId, aKey, aIv); + CleanupStack::PushL(UtlCipher); + UtlCipher->ProcessFinalL(aInput, aOutput); + CleanupStack::PopAndDestroy(UtlCipher); +} + +TInt IkeCrypto::IntegHMACL(const TDesC8& aInput, TDes8& aChecksum, const TDesC8& aKeyData, TUint16 aIntegAlg) +{ + TUtlCrypto::TUtlMessageDigestId DigestId; + TInt HmacLth; + IkeCrypto::AlgorithmInfo(IKEV2_INTEG, aIntegAlg, &HmacLth, NULL, &DigestId); + CUtlMessageDigest* Digest = TUtlCrypto::MakeMessageDigesterL(DigestId, aKeyData); + + const TPtrC8 hash = Digest->Final(aInput); + + //We don't always use the whole hash. + //(e.g., HMAC-SHA1-96 uses only first 12 bytes) + __ASSERT_DEBUG(hash.Length() >= HmacLth, User::Invariant()); + + aChecksum = hash.Left(HmacLth); + delete Digest; + + return HmacLth; +} + +HBufC8* IkeCrypto::PrfhmacL(const TDesC8& aInput, const TDesC8& aKeyData, TUint16 aPrfAlg) +{ + TUtlCrypto::TUtlMessageDigestId DigestId; + TInt PrfLth; + IkeCrypto::AlgorithmInfo(IKEV2_PRF, aPrfAlg, &PrfLth, NULL, &DigestId); + CUtlMessageDigest* Digest = TUtlCrypto::MakeMessageDigesterL(DigestId, aKeyData); + CleanupStack::PushL(Digest); + + HBufC8* checksum = Digest->Final(aInput).AllocL(); + + CleanupStack::PopAndDestroy(Digest); + + return checksum; + +} + +HBufC8* IkeCrypto::PrfL(const TDesC8& aInput, TUint16 aPrfAlg) +{ + TUtlCrypto::TUtlMessageDigestId DigestId; + TInt PrfLth; + IkeCrypto::AlgorithmInfo(IKEV2_PRF, aPrfAlg, &PrfLth, NULL, &DigestId); + CUtlMessageDigest* digest = TUtlCrypto::MakeMessageDigesterL(DigestId); + CleanupStack::PushL(digest); + + HBufC8* hash = digest->Final(aInput).AllocL(); + + CleanupStack::PopAndDestroy(digest); + + return hash; + +} + +TInt IkeCrypto::AlgorithmInfo(TUint16 aTransform, TUint16 aAlgCode, TInt* aBlockLth, + TUtlCrypto::TUtlSymmetricCipherId* aCipherId, + TUtlCrypto::TUtlMessageDigestId* aDigestId) +{ + TInt KeyLth = 0; + TInt BlockLth = 0; + + switch ( aTransform ) + { + case IKEV2_ENCR: + switch ( aAlgCode ) + { + case ENCR_DES: + KeyLth = 8; + BlockLth = 8; + if ( aCipherId ) + *aCipherId = TUtlCrypto::EUtlSymmetricCipherDesCbc; + break; + + case ENCR_3DES: + KeyLth = 24; + BlockLth = 8; + if ( aCipherId ) + *aCipherId = TUtlCrypto::EUtlSymmetricCipher3DesCbc; + break; + + case ENCR_AES_CBC: + KeyLth = 0; + BlockLth = 16; + if ( aCipherId ) + *aCipherId = TUtlCrypto::EUtlSymmetricCipherAesCbc; + break; + + case ENCR_NULL: + KeyLth = 0; + BlockLth = 0; + break; + default: + break; + } + break; + + case IKEV2_PRF: + switch ( aAlgCode ) + { + case PRF_HMAC_MD5: + KeyLth = 16; + BlockLth = 16; + if ( aDigestId ) + *aDigestId = TUtlCrypto::EUtlMessageDigestMd5; + break; + + case PRF_HMAC_SHA1: + KeyLth = 20; + BlockLth = 20; + if ( aDigestId ) + *aDigestId = TUtlCrypto::EUtlMessageDigestSha1; + break; + + default: + break; + } + break; + + case IKEV2_INTEG: + switch ( aAlgCode ) + { + case AUTH_HMAC_MD5_96: + KeyLth = 16; + BlockLth = 12; + if ( aDigestId ) + *aDigestId = TUtlCrypto::EUtlMessageDigestMd5; + break; + + case AUTH_HMAC_SHA1_96: + KeyLth = 20; + BlockLth = 12; + if ( aDigestId ) + *aDigestId = TUtlCrypto::EUtlMessageDigestSha1; + break; + + default: + break; + } + break; + + default: + break; + + } + + if ( aBlockLth ) + *aBlockLth = BlockLth; + + return KeyLth; + +} + +HBufC8* IkeCrypto::GenerateKeyingMaterialL(const TDesC8& aK, const TDesC8& aS, TInt aKeyMatLth, TUint16 aPRFAlg) +{ + // + // Since the amount of keying material needed may be greater than + // the size of the output of the prf algorithm prf+ is used as + // follows prf+ (K,S) = T1 | T2 | T3 | T4 | ... + // where: T1 = prf (K, S | 0x01) + // T2 = prf (K, T1 | S | 0x02) .. + // TN = prf (K, TN-1 | S | 0xN ) ;[ N < 256 ] + // + TInt PrfKeyLth = IkeCrypto::AlgorithmInfo(IKEV2_PRF, aPRFAlg, NULL); + TInt S_Lth = aS.Length(); + TUint8 IterCount = (TUint8)((aKeyMatLth/PrfKeyLth) + 1); + HBufC8* KeyMat = HBufC8::NewL((IterCount * PrfKeyLth) + S_Lth + 1); + CleanupStack::PushL(KeyMat); + TPtr8 KeyMatPtr(KeyMat->Des()); + + TUint8 i = 1; + // + // Produce key material T1 | T2 | T3 | T4 | ... + // + + HBufC8* tValue = NULL; + HBufC8* inputBuffer = HBufC8::NewLC(PrfKeyLth + aS.Length() + sizeof(i)); + TPtr8 inputBufferPtr(inputBuffer->Des()); + while ( i <= IterCount ) + { + inputBufferPtr.Zero(); + if (tValue != NULL) + { + inputBufferPtr.Append(*tValue); + } + // + // Append value S into key material buffer and concatenate 8 bit integer + // value i into S + // + inputBufferPtr.Append(aS); + inputBufferPtr.Append(&i, sizeof(i)); + + delete tValue; + tValue = NULL; + // + // Calculate TN = prf (SKEYSEED, TN-1 | S | 0xN) + // + tValue = IkeCrypto::PrfhmacL(*inputBuffer, aK, aPRFAlg); + KeyMatPtr.Append(*tValue); + i++; + } + delete tValue; + + CleanupStack::PopAndDestroy(inputBuffer); + CleanupStack::Pop(); // Keymat + + return KeyMat; +} + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikemsgrec.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikemsgrec.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,452 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Received IKE message handling rules. +* +*/ + +#include "ikev2SAdata.h" +#include "ikemsgrec.h" +#include "ikecrypto.h" +// +// CIkev2Payloads +// + +CIkev2Payloads::CIkev2Payloads(const TIkev2SAData& aIkeV2SaData) +:iIkeV2SaData(aIkeV2SaData) +{ +} + +CIkev2Payloads::~CIkev2Payloads() +{ + delete iProps; + delete iTrans; + delete iCerts; + delete iCertReqs; + delete iNotifs; + delete iDeletes; + delete iVids; + delete iGenPlds; +} + +CIkev2Payloads* CIkev2Payloads::NewL(const ThdrISAKMP &aHdr, const TIkev2SAData& aIkeV2SaData) +{ + CIkev2Payloads* Payloads = new (ELeave) CIkev2Payloads(aIkeV2SaData); + CleanupStack::PushL(Payloads); + + Payloads->ConstructL(); + + Payloads->iIkeMsg = (ThdrISAKMP*)&aHdr; // Save pointer to IKE message data + TInt Lth = aHdr.GetLength() - ThdrISAKMP::Size(); + Payloads->ParsePayloadsL(TPayloadIkev2::Cast(aHdr.Next()), Lth, aHdr.GetPayload(), IKEV2_PAYLOAD_NONE); + + CleanupStack::Pop(Payloads); + + return Payloads; +} + +CIkev2Payloads* CIkev2Payloads::NewL(TPayloadIkev2* aPayload, TUint8 aPayloadType, TIkev2SAData& aIkeV2SaData) +{ + User::LeaveIfNull((TAny*)aPayload); + CIkev2Payloads* Payloads = new (ELeave) CIkev2Payloads(aIkeV2SaData); + CleanupStack::PushL(Payloads); + + Payloads->ConstructL(); + + Payloads->ParsePayloadsL(aPayload, aPayload->GetLength(), aPayloadType, aPayloadType); + + CleanupStack::Pop(Payloads); + + return Payloads; +} + +TBool CIkev2Payloads::ParsePayloadL(TPayloadIkev2* aPayload, TUint16 aPlType) +{ + User::LeaveIfNull((TAny*)aPayload); + + if ( aPlType == IKEV2_PAYLOAD_SA ) + iProps->Reset(); + else if ( aPlType == IKEV2_PAYLOAD_PROP ) + iTrans->Reset(); + if ( ParsePayloadsL(aPayload, aPayload->GetLength(), aPlType, aPlType) != 0 ) + return EFalse; + else return ETrue; +} + +void CIkev2Payloads::ConstructL() +{ + iProps = new (ELeave) CArrayFixFlat(4); + iTrans = new (ELeave) CArrayFixFlat(4); + iCerts = new (ELeave) CArrayFixFlat(4); + iCertReqs = new (ELeave) CArrayFixFlat(2); + iNotifs = new (ELeave) CArrayFixFlat(2); + iDeletes = new (ELeave) CArrayFixFlat(2); + iVids = new (ELeave) CArrayFixFlat(2); + iGenPlds = new (ELeave) CArrayFixFlat(2); +} + + +TInt CIkev2Payloads::ParsePayloadsL(TPayloadIkev2* aPayload, TInt aLength, TUint16 aPlType, TUint16 aRefPlType ) +{ + ASSERT(aPayload); + TBool Critical; + TInt PlLth; + TInt RefLth; + + while ( aPlType != IKEV2_PAYLOAD_NONE ) + { + PlLth = aPayload->GetLength(); + RefLth = TPayloadIkev2::Size(); + + if ( ( aLength < TPayloadIkev2::Size() ) || (aLength < PlLth) ) + { + if ( aLength && ( aRefPlType != IKEV2_PAYLOAD_SA )) + SetStatus(INVALID_SYNTAX); // Payload length mismatch !! + return aLength; + } + + if ( (aRefPlType != IKEV2_PAYLOAD_NONE) && (aRefPlType != aPlType) ) + { + SetStatus(INVALID_SYNTAX); // Illegal payload type !! + return aLength; + } + + Critical = aPayload->GetCritical(); + + switch ( aPlType ) + { + case IKEV2_PAYLOAD_PROP: + iProps->AppendL(TProposalIkev2::Cast(aPayload)); + // + // Parse Transform payloads within a Proposal payload + // (recursively) + // + ParsePayloadsL(TPayloadIkev2::Cast(TProposalIkev2::Cast(aPayload)->TransformPl()), + (PlLth - TProposalIkev2::Cast(aPayload)->PropHdrLth()), + IKEV2_PAYLOAD_TRANS, IKEV2_PAYLOAD_TRANS); + if ( Status() ) + return aLength; + break; + + case IKEV2_PAYLOAD_TRANS: + RefLth = TTransformIkev2::Cast(aPayload)->Size(); + iTrans->AppendL(TTransformIkev2::Cast(aPayload)); + break; + + case IKEV2_PAYLOAD_SA: //also includes proposal and transform + if ( !iSa ) // Only one SA payload (The first) + { + iSa = aPayload; + // + // Parse Proposal payloads within a SA payload + // (recursively) + // + ParsePayloadsL(TPayloadIkev2::Cast(aPayload->PayloadData()), aPayload->PlDataLen(), + IKEV2_PAYLOAD_PROP, IKEV2_PAYLOAD_PROP); + if ( Status() ) + return aLength; + } + break; + + case IKEV2_PAYLOAD_KE: + RefLth = TKEPayloadIkev2::Size(); + if ( !iKe ) // Only one KE payload (The first) + { + iKe = TKEPayloadIkev2::Cast(aPayload); + } + break; + + case IKEV2_PAYLOAD_ID_I: + if ( !Encrypted() ) + { + SetStatus(INVALID_SYNTAX); // ID payload MUST be encrypted + return aLength; + } + RefLth = TIDPayloadIkev2::Size(); + if ( !iIdI ) // Only one Initiator ID payload (The first) + { + iIdI = TIDPayloadIkev2::Cast(aPayload); + } + break; + + case IKEV2_PAYLOAD_ID_R: + if ( !Encrypted() ) + { + SetStatus(INVALID_SYNTAX); // ID payload MUST be encrypted + return aLength; + } + RefLth = TIDPayloadIkev2::Size(); + if ( !iIdR ) // Only one Responder ID payload (The first) + { + iIdR = TIDPayloadIkev2::Cast(aPayload); + } + break; + + case IKEV2_PAYLOAD_CERT: + RefLth = TCertPayloadIkev2::Size(); + iCerts->AppendL(TCertPayloadIkev2::Cast(aPayload)); + break; + + case IKEV2_PAYLOAD_CR: + RefLth = TCReqPayloadIkev2::Size(); + iCertReqs->AppendL(TCReqPayloadIkev2::Cast(aPayload)); + break; + + case IKEV2_PAYLOAD_AUTH: + if ( !Encrypted() ) + { + SetStatus(INVALID_SYNTAX); // Auth payload MUST be encrypted + return aLength; + } + RefLth = TAuthPayloadIkev2::Size(); + if ( !iAuth ) // Only one Authentication payload (The first) + { + iAuth = TAuthPayloadIkev2::Cast(aPayload); + } + break; + + case IKEV2_PAYLOAD_NONCE: + if ( !iNonce ) + { // Only one SA payload (The first) + iNonce = aPayload; + } + break; + + case IKEV2_PAYLOAD_NOTIF: + RefLth = TNotifPayloadIkev2::Size(); + iNotifs->AppendL(TNotifPayloadIkev2::Cast(aPayload)); + break; + + case IKEV2_PAYLOAD_DELETE: + RefLth = TDeletePlIkev2::Size(); + iDeletes->AppendL(TDeletePlIkev2::Cast(aPayload)); + break; + + case IKEV2_PAYLOAD_VID: + iVids->AppendL(aPayload); + break; + + case IKEV2_PAYLOAD_TS_I: + if ( !Encrypted() ) + { + SetStatus(INVALID_SYNTAX); // ID payload MUST be encrypted + return aLength; + } + RefLth = TTSPayloadIkev2::Size(); + if ( !iTsI ) // Only one Initiator ID payload (The first) + { + iTsI = TTSPayloadIkev2::Cast(aPayload); + } + break; + + case IKEV2_PAYLOAD_TS_R: + if ( !Encrypted() ) + { + SetStatus(INVALID_SYNTAX); // ID payload MUST be encrypted + return aLength; + } + RefLth = TTSPayloadIkev2::Size(); + if ( !iTsR ) // Only one Initiator ID payload (The first) + { + iTsR = TTSPayloadIkev2::Cast(aPayload); + } + break; + + case IKEV2_PAYLOAD_ENCR: + if ( !iEncr ) // Only one Initiator ID payload (The first) + { + DecryptEncrPayloadL(aPayload); + iEncr = aPayload; + } + else SetStatus(INVALID_SYNTAX); // Only ONE encrypted payload per message + if ( Status() ) + return aLength; + break; + + case IKEV2_PAYLOAD_CONFIG: + if ( !Encrypted() ) + { + SetStatus(INVALID_SYNTAX); // ID payload MUST be encrypted + return aLength; + } + RefLth = TCPPayloadIkev2::Size(); + if ( !iCp ) // Only one Config payload (The first) + { + iCp = TCPPayloadIkev2::Cast(aPayload); + } + break; + + case IKEV2_PAYLOAD_EAP: + if ( !Encrypted() ) + { + SetStatus(INVALID_SYNTAX); // ID payload MUST be encrypted + return aLength; + } + if ( !iEap ) // Only one Config payload (The first) + { + iEap = aPayload; + } + break; + + // + // Unknown payload detected. If Critical bit is not set + // + // + default: + if ( Critical ) + { + SetStatus(UNSUPPORTED_CRITICAL_PAYLOAD); + return aLength; + } + else iGenPlds->AppendL(aPayload); + break; + + } + + if ( PlLth < RefLth ) + { + SetStatus(INVALID_SYNTAX); // Length mismatch + return aLength; + } + + aLength -= PlLth; + aPlType = aPayload->GetNextPayload(); + aPayload = aPayload->Next(); + } + + if ( aLength ) + SetStatus(INVALID_SYNTAX); // Length mismatch + + return aLength; +} + +void CIkev2Payloads::DecryptEncrPayloadL(TPayloadIkev2* aPayload) +{ + ASSERT(aPayload); + // + // Process Encrypted Payload + // 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // ! Next Payload !C! RESERVED ! Payload Length ! + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // ! Initialization Vector ! + // ! (length is block size for encryption algorithm) ! + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // ! Encrypted IKE Payloads ! + // + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // ! ! Padding (0-255 octets) ! + // +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ + // ! ! Pad Length ! + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // ~ Integrity Checksum Data ~ + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // + // Save integrity checksum from encrypted payload tail the + // integrity checksum length is defined by used integrity algorithm + // + TInt CheksumLth = iIkeV2SaData.iIntChkSumLth; + TInt CbcLth = iIkeV2SaData.iCipherBlkLth; + TInt EmbeddedLth = aPayload->GetLength(); + if ( EmbeddedLth < (CheksumLth + CbcLth) ) + { + SetStatus(INVALID_SYNTAX); + return; + } + TUint8* MsgChecksum = (TUint8*)aPayload + EmbeddedLth - CheksumLth; + TBuf8 CheckSum; + // + // Decrypt encryption payload content and payload tail the + // integrity checksum length is defined by used integrity algorithm + // + + TInt EntireLth = iIkeMsg->GetLength() - iIkeV2SaData.iIntChkSumLth; + TInt EncryptedDataLength = aPayload->GetLength() - (iIkeV2SaData.iIntChkSumLth + iIkeV2SaData.iCipherBlkLth + TPayloadIkev2::Size()); + TUint8* IvPtr = aPayload->PayloadData(); + TUint8* EncryptedData = IvPtr + iIkeV2SaData.iCipherBlkLth; + + TPtrC8 entireDataPtr((TUint8*)iIkeMsg, EntireLth); + if ( iIkeV2SaData.iInitiator ) + { + IkeCrypto::IntegHMACL(entireDataPtr, CheckSum, iIkeV2SaData.iSK_ar, iIkeV2SaData.iIntegAlg); + IkeCrypto::DecryptL(EncryptedData, EncryptedData, EncryptedDataLength, IvPtr, iIkeV2SaData.iSK_er, iIkeV2SaData.iEncrAlg); + } + else + { + IkeCrypto::IntegHMACL(entireDataPtr, CheckSum, iIkeV2SaData.iSK_ai, iIkeV2SaData.iIntegAlg); + IkeCrypto::DecryptL(EncryptedData, EncryptedData, EncryptedDataLength, IvPtr, iIkeV2SaData.iSK_ei, iIkeV2SaData.iEncrAlg); + } + + + // + // Check that integrity cheksum is correct + // + if ( Mem::Compare(MsgChecksum, CheksumLth ,CheckSum.Ptr(), CheksumLth) != 0 ) + { + SetStatus(INVALID_SYNTAX); // Length mismatch + return; + } + // + // Process embedded payloads inside the encrypted payload + // - Bypass IV in the begin of encrypted payload data + // - Assure that padded "embedded" payloads have length which + // equals with multiple of CBC block length + // - Ignore padding bytes from that length + // + EmbeddedLth -= (CheksumLth + CbcLth + TPayloadIkev2::Size()); + if ( EmbeddedLth % CbcLth ) + { + SetStatus(INVALID_SYNTAX); + return; + } + MsgChecksum --; // Move pointer to padding length + if ( EmbeddedLth < (TInt)*MsgChecksum ) + { + SetStatus(INVALID_SYNTAX); + return; + } + EmbeddedLth -= (TInt)*MsgChecksum; + EmbeddedLth --; // Pad Length itself + TPayloadIkev2* EmbeddedPl = TPayloadIkev2::Cast(aPayload->PayloadData() + CbcLth); + + iEncrypted = ETrue; // Set encrypted indicator + + ParsePayloadsL(EmbeddedPl, EmbeddedLth, + aPayload->GetNextPayload(), IKEV2_PAYLOAD_NONE); + +} + +ThdrISAKMP* CIkev2Payloads::GetIkeMsg() +{ + return iIkeMsg; +} + + +TInt CIkev2Payloads::Status() +{ + return iStatus; +} + + +void CIkev2Payloads::SetStatus(TInt aStatus) +{ + if ( iStatus == 0) iStatus = aStatus; +} + + +TBool CIkev2Payloads::Encrypted() +{ + return iEncrypted; +} + + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2acquire.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2acquire.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,531 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 Acquire definition +* Class CIkev2Acquire is a IKEv2 specific data structure +* containing information needed, when establishing a new +* IPsec SA +*/ + +#include + +#include "ikev2acquire.h" +#include "pfkeymsg.h" +#include "ipsecproposal.h" +#include "ipsecselectors.h" +#include "ikev2payloads.h" +#include "ikev2ipsecsarekeydata.h" + +_LIT8(KZeroDesc, ""); +// +// +// CIkev2Acquire +// +// This class is used to handle PFKEY Acquire primitives received from +// Ipsec plug-in. +// +// +CIkev2Acquire::CIkev2Acquire(TInt aId) +:iId(aId), iSPIIn(0), iSPIOut(0), iSPIToBeRekeyed(0), iDHGroup(0), + iTransport(EFalse), iResponse(EFalse), iSrcSpecific(ETrue), iForVirtualIp(EFalse), + iReplayWindow(0), iProtocol(SADB_SATYPE_ESP), iPfKeyPid(0), iPfKeySeq(0), + iHard(0,0,0,0), iSoft(0,0,0,0), + iSA(0), iTS_i(0), iTS_r(0), iLocalId(0), iRemoteId(0), iNext(0) + { + } + + +CIkev2Acquire::~CIkev2Acquire() +{ + delete iSA; + iSA = NULL; + delete iTS_i; + iTS_i = NULL; + delete iTS_r; + iTS_r = NULL; + delete iLocalId; + iLocalId = NULL; + delete iRemoteId; + iRemoteId = NULL; +} + +void CIkev2Acquire::ConstructL(const TPfkeyMessage& aReq, const TInetAddr& aLocalAddr, + TUint16 aDHGroup, TBool aImplicitSa, + const TIpsecSaSpec* aSaSpec, const CIpsecSARekeyData* aRekeyData) +{ + SetIpsecProtocol(aReq.iBase.iMsg->sadb_msg_satype); + SetPid(aReq.iBase.iMsg->sadb_msg_pid); + SetSeq(aReq.iBase.iMsg->sadb_msg_seq); + iSrcSpecific = !(aReq.iSrcAddr.iAddr->IsUnspecified()); + + if (!aRekeyData) + { + // SADB_ACQUIRE was received + if ( aReq.iProposal.iComb->sadb_comb_flags & SADB_SAFLAGS_PFS ) + { + iDHGroup = (TUint32)aDHGroup; + } + + if ( aReq.iProposal.iComb->sadb_comb_flags & SADB_SAFLAGS_TUNNEL ) + { + iTransport = EFalse; + } + else + { + iTransport = ETrue; + } + + iHard.iAllocations = aReq.iProposal.iComb->sadb_comb_hard_allocations; + iHard.iBytes = aReq.iProposal.iComb->sadb_comb_hard_bytes; + iHard.iAddtime = aReq.iProposal.iComb->sadb_comb_hard_addtime; + iHard.iUsetime = aReq.iProposal.iComb->sadb_comb_hard_usetime; + + iSoft.iAllocations = aReq.iProposal.iComb->sadb_comb_soft_allocations; + iSoft.iBytes = aReq.iProposal.iComb->sadb_comb_soft_bytes; + iSoft.iAddtime = aReq.iProposal.iComb->sadb_comb_soft_addtime; + iSoft.iUsetime = aReq.iProposal.iComb->sadb_comb_soft_usetime; + + SetReplayWindow(aReq.iProposal.iExt->sadb_prop_replay); + + // + // Build SA payload (including Proposal and Transform payload) + // using parameters in TPfkeyMessage + // + if ( aImplicitSa ) + { + aDHGroup = 0; // No D-H group used with ipmplicit SA although PFS defined + } + iSA = IpsecProposal::BuildIpsecSaRequestL(aReq, aDHGroup); + + // + // Build Traffic selectors using parameters in TPfkeyMessage. + // For some reason the selectors are build using identity + // fields. + // + IpsecSelectors::BuildTrafficSelectorsL(this, aLocalAddr, + aReq.iSrcIdent, aReq.iDstIdent, + aReq.iDstAddr.iExt->sadb_address_proto); + // + // Store identity information from TPfkeyMessage to Acquire + // + if ( aReq.iSrcIdent.iExt ) + { + iLocalId = HBufC8::NewL(aReq.iSrcIdent.iData.Length()); + iLocalId->Des().Copy(aReq.iSrcIdent.iData); + } + else + { + iLocalId = KZeroDesc().AllocL(); + } + + if ( aReq.iDstIdent.iExt ) + { + iRemoteId = HBufC8::NewL(aReq.iDstIdent.iData.Length()); + iRemoteId->Des().Copy(aReq.iDstIdent.iData); + } + else + { + iRemoteId = KZeroDesc().AllocL(); + } + } + else + { + // SADB_EXPIRE was received due to soft lifetime expiration + TUint16 flags = (TUint16)(aReq.iSa.iExt->sadb_sa_flags | (aSaSpec->iTransportMode ? 0 : SADB_SAFLAGS_TUNNEL)); + if ( flags & SADB_SAFLAGS_PFS ) + { + iDHGroup = (TUint32)aDHGroup; + } + + if ( flags & SADB_SAFLAGS_TUNNEL ) + { + iTransport = EFalse; + } + else + { + iTransport = ETrue; + } + + if ( aImplicitSa ) + { + aDHGroup = 0; // No D-H group used with ipmplicit SA although PFS defined + } + + iSA = IpsecProposal::BuildIpsecSaRequestL(iProtocol, + aSaSpec->iEalg, aSaSpec->iEalgLen, aSaSpec->iAalg, + flags, aDHGroup); + + iReplayWindow = aRekeyData->ReplayWindow(); + iHard = aRekeyData->HardLifetime(); + iSoft = aRekeyData->SoftLifetime(); + + iTS_i = aRekeyData->TsIL(); + iTS_r = aRekeyData->TsRL(); + + + iLocalId = aRekeyData->LocalId().AllocL(); + iRemoteId = aRekeyData->RemoteId().AllocL(); + + iResponse = EFalse; + } +} + + +CIkev2Acquire* CIkev2Acquire::NewL(const TPfkeyMessage& aPfkeyMessage, TUint32 aId, + const TInetAddr& aLocalAddr, TUint16 aDHGroup, TBool aImplicitSa, + const TIpsecSaSpec* aSaSpec, const CIpsecSARekeyData* aRekeyData) +{ + CIkev2Acquire* Acquire = new (ELeave)CIkev2Acquire(aId); + CleanupStack::PushL(Acquire); + Acquire->ConstructL(aPfkeyMessage, aLocalAddr, aDHGroup, aImplicitSa, aSaSpec, aRekeyData); + CleanupStack::Pop(Acquire); + return Acquire; +} + + +void CIkev2Acquire::AddIpsecSpiToSa(const TDesC8& aSpi) + { + __ASSERT_DEBUG(aSpi.Length() == 4, User::Invariant()); + + TUint8* saBuffer = const_cast(iSA->Ptr()); + TProposalIkev2* Prop = TProposalIkev2::Cast(saBuffer); + + while ( Prop ) + { + TUint32 spiValue = 0; + TPtr8 spiValueDesc(reinterpret_cast(&spiValue), sizeof(spiValue)); + spiValueDesc = aSpi; + Prop->SetIpsecSPI(spiValue); + if ( !Prop->Last() ) + { + Prop = TProposalIkev2::Cast(TPayloadIkev2::Cast(Prop)->Next()); + } + else + { + Prop = NULL; + } + } + } + + +CIkev2Acquire* CIkev2Acquire::NewL(TUint32 aId, HBufC8* aSa, + CArrayFix* aTS_i, + CArrayFix* aTS_r ) +{ + CIkev2Acquire* Acquire = new (ELeave)CIkev2Acquire(aId); + Acquire->iSA = aSa; + Acquire->iTS_i = aTS_i; + Acquire->iTS_r = aTS_r; + return Acquire; +} + +void CIkev2Acquire::Link(CIkev2Acquire* aAcquire, CIkev2Acquire** aAnchor) +{ + ASSERT(aAcquire && aAnchor); + aAcquire->iNext = NULL; + CIkev2Acquire* Last = *aAnchor; + if ( Last ) + { + while ( Last->iNext ) + { + Last = Last->iNext; + } + Last->iNext = aAcquire; + } + else *aAnchor = aAcquire; +} + +CIkev2Acquire* CIkev2Acquire::Find(TUint32 aId, CIkev2Acquire** aAnchor, TBool aRemove) +{ + ASSERT(aAnchor); + CIkev2Acquire* Prev = NULL; + CIkev2Acquire* Elem = *aAnchor; + while ( Elem ) + { + if ( Elem->iId == aId ) + { + if ( aRemove ) + { + if ( Prev ) + Prev->iNext = Elem->iNext; + else *aAnchor = Elem->iNext; + } + break; + } + Prev = Elem; + Elem = Elem->iNext; + } + return Elem; +} + +CIkev2Acquire* CIkev2Acquire::GetNext(CIkev2Acquire** aAnchor, TBool aResponse) +{ + ASSERT(aAnchor); + CIkev2Acquire* Elem = *aAnchor; + while ( Elem ) + { + if ( Elem->SPI_In().Length() > 0 && (Elem->Response() == aResponse) ) + { + RemoveFromQue(Elem->Id(), aAnchor); + break; + } + Elem = Elem->iNext; + } + return Elem; +} + +TBool CIkev2Acquire::Responding(CIkev2Acquire** aAnchor) +{ + ASSERT(aAnchor); + CIkev2Acquire* Elem = *aAnchor; + while ( Elem ) + { + if ( Elem->Response() ) + { + return ETrue; + } + Elem = Elem->iNext; + } + return EFalse; +} + + +void CIkev2Acquire::PurgeQue(CIkev2Acquire** aAnchor) +{ + ASSERT(aAnchor); + CIkev2Acquire* Elem = *aAnchor; + while ( Elem ) + { + RemoveFromQue(Elem->Id(), aAnchor); + delete Elem; + Elem = *aAnchor; + } +} + +void CIkev2Acquire::SetFirst(CIkev2Acquire* aAcquire, CIkev2Acquire** aAnchor) + { + ASSERT(aAcquire && aAnchor); + aAcquire->iNext = *aAnchor; + *aAnchor = aAcquire; + } + +CIkev2Acquire* CIkev2Acquire::PeekFirst(CIkev2Acquire** aAnchor) + { + return *aAnchor; + } + +CIkev2Acquire* CIkev2Acquire::RemoveFromQue(TUint32 aId, CIkev2Acquire** aAnchor) + { + return CIkev2Acquire::Find(aId, aAnchor, ETrue); + } + +TUint32 CIkev2Acquire::Id() + { + return iId; + } + +TPtrC8 CIkev2Acquire::SPI_In() + { + return iSPIIn; + } + +TPtrC8 CIkev2Acquire::SPI_Out() + { + return iSPIOut; + } + +TPtrC8 CIkev2Acquire::SPI_ToBeRekeyed() + { + return iSPIToBeRekeyed; + } + +void CIkev2Acquire::SetSPI_In(const TDesC8& aSPI) + { + iSPIIn = aSPI; + } + +void CIkev2Acquire::SetSPI_Out(const TDesC8& aSPI) + { + iSPIOut = aSPI; + } + +void CIkev2Acquire::SetSPI_ToBeRekeyed(const TDesC8& aSPI) + { + iSPIToBeRekeyed = aSPI; + } + +TUint16 CIkev2Acquire::DHGroup() + { + return (TUint16)iDHGroup; + } + +void CIkev2Acquire::DHGroup(TUint16 aDHGroup) + { + iDHGroup = aDHGroup; + } + +TBool CIkev2Acquire::Transport() + { + return iTransport; + } + +void CIkev2Acquire::SetTransport() + { + iTransport = ETrue; + } + +TBool CIkev2Acquire::Response() + { + return iResponse; + } + +void CIkev2Acquire::SetResponse() + { + iResponse = ETrue; + } + +void CIkev2Acquire::SetHardLifetime(const TIpsecSALifetime& aHard ) + { + iHard = aHard; + } + +TIpsecSALifetime* CIkev2Acquire::HardLifetime() + { + return &iHard; + } + +void CIkev2Acquire::SetSoftLifetime(const TIpsecSALifetime& aSoft ) + { + iSoft = aSoft; + } + +TIpsecSALifetime* CIkev2Acquire::SoftLifetime() + { + return &iSoft; + } + +TUint8 CIkev2Acquire::ReplayWindow() + { + return (TUint8)iReplayWindow; + } + +void CIkev2Acquire::SetReplayWindow(TUint8 aReplayWindow) + { + iReplayWindow = (TInt)aReplayWindow; + } + +TUint32 CIkev2Acquire::Pid() + { + return iPfKeyPid; + } + +void CIkev2Acquire::SetPid(TUint32 aPfKeyPid) + { + iPfKeyPid = aPfKeyPid; + } + +TUint32 CIkev2Acquire::Seq() + { + return iPfKeySeq; + } + +void CIkev2Acquire::SetSeq(TUint32 aPfKeySeq) + { + iPfKeySeq = aPfKeySeq; + } + +void CIkev2Acquire::SetVirtualIp() + { + iForVirtualIp = ETrue; + } + +TBool CIkev2Acquire::ForVirtualIp() + { + return iForVirtualIp; + } + +TBool CIkev2Acquire::SrcSpecific() + { + return iSrcSpecific; + } + +void CIkev2Acquire::SetSrcSpecific(TBool aSrcSpecific) + { + iSrcSpecific = aSrcSpecific; + } + +TUint8 CIkev2Acquire::IpsecProtocol() + { + return (TUint8)iProtocol; + } + +void CIkev2Acquire::SetIpsecProtocol(TUint8 aProtocol) + { + iProtocol = (TInt)aProtocol; + } + +HBufC8* CIkev2Acquire::LocalId() + { + return iLocalId; + } + +HBufC8* CIkev2Acquire::RemoteId() + { + return iRemoteId; + } + +HBufC8* CIkev2Acquire::SA()const + { + return iSA; + } + +const CArrayFix& CIkev2Acquire::TS_i() + { + return *iTS_i; + } + +const CArrayFix& CIkev2Acquire::TS_r() + { + return *iTS_r; + } + +void CIkev2Acquire::ReplaceSA(HBufC8* aSA) + { + delete iSA; + iSA = aSA; + } + +void CIkev2Acquire::ReplaceTS_i(CArrayFix* aTS) + { + delete iTS_i; + iTS_i = aTS; + } + +void CIkev2Acquire::ReplaceTS_r(CArrayFix* aTS) + { + delete iTS_r; + iTS_r = aTS; + } + +void CIkev2Acquire::ReplaceLocalId(HBufC8* aId) + { + delete iLocalId; + iLocalId = aId; + } + +void CIkev2Acquire::ReplaceRemoteId(HBufC8* aId) + { + delete iRemoteId; + iRemoteId = aId; + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2deactivationtimer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2deactivationtimer.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Timer to trigger cancellation of session deletion. +* +*/ + + +#include "ikev2deactivationtimer.h" + +// Deactivation timeout value. +static const TUint KDeactivationTimeout = 2000000; //microseconds + +CIkev2DeactivationTimer* CIkev2DeactivationTimer::NewL(MIkev2DeactivationTimerCallback& aCallback) + { + CIkev2DeactivationTimer* self = new (ELeave) CIkev2DeactivationTimer(aCallback); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + + return self; + } + + +CIkev2DeactivationTimer::CIkev2DeactivationTimer(MIkev2DeactivationTimerCallback& aCallback) + : CTimer(EPriorityStandard), + iCallback(aCallback) + { + CActiveScheduler::Add(this); + } + +CIkev2DeactivationTimer::~CIkev2DeactivationTimer() + { + Cancel(); + } + +void CIkev2DeactivationTimer::IssueRequest() + { + After(KDeactivationTimeout); + } + + +void CIkev2DeactivationTimer::RunL() + { + iCallback.DeactivationTimeout(); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2expire.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2expire.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,95 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* CIkev2Expire. This class is used to handle PFKEY Expire primitives received +* from IPSec plug-in. +* +*/ +#include "ikev2expire.h" +#include "pfkeymsg.h" + +// +// CIkev2Expire +// +// This class is used to handle PFKEY Expire primitives received from +// Ipsec plug-in. +// + +CIkev2Expire* CIkev2Expire::NewL(const TPfkeyMessage& aPfkeyMessage) +{ + CIkev2Expire* Expire = new (ELeave)CIkev2Expire(); + TPtrC8 spiPtr(reinterpret_cast(&aPfkeyMessage.iSa.iExt->sadb_sa_spi), + sizeof(aPfkeyMessage.iSa.iExt->sadb_sa_spi)); + Expire->SetSPI(spiPtr); + Expire->SetProtocol(aPfkeyMessage.iBase.iMsg->sadb_msg_satype); + return Expire; +} + +void CIkev2Expire::Link(CIkev2Expire* aExpire, CIkev2Expire** aAnchor) +{ + ASSERT(aExpire && aAnchor); + aExpire->iNext = NULL; + CIkev2Expire* Last = *aAnchor; + if ( Last ) + { + while ( Last->iNext ) + { + Last = Last->iNext; + } + Last->iNext = aExpire; + } + else *aAnchor = aExpire; +} + +CIkev2Expire* CIkev2Expire::GetNext(CIkev2Expire** aAnchor) +{ + ASSERT(aAnchor); + CIkev2Expire* Elem = *aAnchor; + if ( Elem ) + *aAnchor = Elem->iNext; + return Elem; +} + +void CIkev2Expire::PurgeQue(CIkev2Expire** aAnchor) +{ + ASSERT(aAnchor); + CIkev2Expire* Elem = *aAnchor; + while ( Elem ) + { + *aAnchor = Elem->iNext; + delete Elem; + Elem = *aAnchor; + } +} + +TPtrC8 CIkev2Expire::SPI() + { + return iSPI; + } + +void CIkev2Expire::SetSPI(const TDesC8& aSPI) + { + iSPI = aSPI; + } + +TUint8 CIkev2Expire::Protocol() + { + return iProtocol; + } + +void CIkev2Expire::SetProtocol(TUint8 aProt) + { + iProtocol = aProt; + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2identity.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2identity.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include "ikev2identity.h" + +static const TUint16 KHeaderLength = 4; + +CIkeV2Identity* CIkeV2Identity::NewL(TUint8 aIdType, const TDesC8& aIdentity) + { + CIkeV2Identity* self = new (ELeave) CIkeV2Identity; + CleanupStack::PushL(self); + self->ConstructL(aIdType, aIdentity); + CleanupStack::Pop(self); + + return self; + } + + +void CIkeV2Identity::ConstructL(TUint8 aIdType, const TDesC8& aIdentity) + { + _LIT8(KReserverField, "\0\0\0"); + + iIdPayloadData = HBufC8::NewL(KHeaderLength + aIdentity.Length()); + TPtr8 idPayloadDataPtr = iIdPayloadData->Des(); + + idPayloadDataPtr.Append(&aIdType, sizeof(aIdType)); + idPayloadDataPtr.Append(KReserverField); + idPayloadDataPtr.Append(aIdentity); + } + + +CIkeV2Identity::~CIkeV2Identity() + { + delete iIdPayloadData; + } + + +TUint8 CIkeV2Identity::IdType() const + { + return (*iIdPayloadData)[0]; + } + + +TPtrC8 CIkeV2Identity::Identity() const + { + return iIdPayloadData->Mid(KHeaderLength); + } + +TPtrC8 CIkeV2Identity::PayloadData() const + { + return *iIdPayloadData; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2ipsecsadata.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2ipsecsadata.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 IPsec sa data +* +*/ + +#include "ikev2ipsecsadata.h" +#include "ikedebug.h" +#include "ikev2ipsecsarekeydata.h" +#include "ikecrypto.h" +#include "ikev2const.h" + +TIkeV2IpsecSAData::TIkeV2IpsecSAData(MIkeDebug& aDebug) +:iSPI_In(0), iSPI_Out(0), + iEncrAlg(0), iIntegAlg(0), + iSaType(0), iESN(0), + iCipherKeyLth(0), iIntegKeyLth(0), + iTransport(EFalse), iSrcSpecific(EFalse), + iRekeyData(NULL), iKeyMaterial(NULL), + iNext(NULL), iDebug(aDebug) + { + } + + +void TIkeV2IpsecSAData::Copy(const TIkeV2IpsecSAData& aSrc) + { + Mem::Copy((TUint8*)&iSPI_In, (TUint8*)&aSrc.iSPI_In, sizeof(TIkeV2IpsecSAData)); + iNext = NULL; + } + +/* +void TIkeV2IpsecSAData::StoreKeyMaterial(HBufC8* aKeyMaterial) + { + PurgeKeyMaterial(); + iKeyMaterial = aKeyMaterial; + } +*/ + +void TIkeV2IpsecSAData::PurgeKeyMaterial() + { + if ( iKeyMaterial ) + { + iKeyMaterial->Des().FillZ(); // Wipe out key material data from buffer + delete iKeyMaterial; + iKeyMaterial = NULL; + } + } + + +void TIkeV2IpsecSAData::DeleteRekeyData() + { + if ( iRekeyData ) + { + delete iRekeyData; + iRekeyData = NULL; + } + } + +void TIkeV2IpsecSAData::GenerateIpsecKeysL(const TDesC8& aSKd, + const TDesC8& aGPowIr, + const TDesC8& aNonceI, + const TDesC8& aNonceR, + TUint16 aPrfAlg) +{ + // + // Generate Ipsec keying material. + // Keying material is created as follows: KEYMAT = prf+(SK_d, Ni | Nr) + // If PFS used Keying material is: KEYMAT = prf+(SK_d, g^ir (new) | Ni | Nr ) + // + HBufC8* s = HBufC8::NewLC(aGPowIr.Length() + aNonceI.Length() + aNonceR.Length()); + TPtr8 sPtr = s->Des(); + // + // Append Nonce data into keymaterial work buffer S + // + sPtr = aGPowIr; + sPtr.Append(aNonceI); + sPtr.Append(aNonceR); + + TInt KeyMatLth = 0; + if ( iEncrAlg ) + { if ( iCipherKeyLth == 0) + iCipherKeyLth = IkeCrypto::AlgorithmInfo(IKEV2_ENCR, iEncrAlg, NULL); + KeyMatLth = 2*iCipherKeyLth; + } + if ( iIntegAlg ) + { + iIntegKeyLth = IkeCrypto::AlgorithmInfo(IKEV2_INTEG, iIntegAlg, NULL); + KeyMatLth += 2*iIntegKeyLth; + } + + PurgeKeyMaterial(); + iKeyMaterial = IkeCrypto::GenerateKeyingMaterialL(aSKd, *s, KeyMatLth, aPrfAlg); + CleanupStack::PopAndDestroy(s); +} + + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2ipsecsarekeydata.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2ipsecsarekeydata.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,148 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include "ikev2ipsecsarekeydata.h" + +_LIT8(KZeroDescriptor, ""); + +CIpsecSARekeyData* CIpsecSARekeyData::NewL(const TInt aReplayWindow, + const TIpsecSALifetime* aHard, + const TIpsecSALifetime* aSoft, + const CArrayFix& aTS_i, + const CArrayFix& aTS_r, + const TDesC8& aLocalId, const TDesC8& aRemoteId) + { + CIpsecSARekeyData* self = + new (ELeave)CIpsecSARekeyData(aReplayWindow, aHard, aSoft); + CleanupStack::PushL(self); + self->ConstructL(aTS_i, aTS_r, aLocalId, aRemoteId); + CleanupStack::Pop(); + return self; + } + + +CIpsecSARekeyData::CIpsecSARekeyData(const TInt aReplayWindow, + const TIpsecSALifetime* aHard, + const TIpsecSALifetime* aSoft) +:iReplayWindow(aReplayWindow), iHard(*aHard), iSoft(*aSoft), + iTS_i(0), iTS_r(0), iLocalId(0), iRemoteId(0) + { + } + + +void CIpsecSARekeyData::ConstructL(const CArrayFix& aTS_i, + const CArrayFix& aTS_r, + const TDesC8& aLocalId, const TDesC8& aRemoteId) + { + + iTS_i = new (ELeave) CArrayFixFlat(aTS_i.Count()); + for (TInt i = 0; i < aTS_i.Count(); i++) + { + iTS_i->AppendL(aTS_i[i]); + } + + iTS_r = new (ELeave) CArrayFixFlat(aTS_r.Count()); + for (TInt i = 0; i < aTS_r.Count(); i++) + { + iTS_r->AppendL(aTS_r[i]); + } + + iLocalId = aLocalId.AllocL(); + iRemoteId = aRemoteId.AllocL(); + } + + +CIpsecSARekeyData::~CIpsecSARekeyData() + { + delete iTS_i; + delete iTS_r; + delete iLocalId; + delete iRemoteId; + } + + +TInt CIpsecSARekeyData::ReplayWindow() const + { + return iReplayWindow; + } + + +TIpsecSALifetime CIpsecSARekeyData::HardLifetime() const + { + return iHard; + } + + +TIpsecSALifetime CIpsecSARekeyData::SoftLifetime() const + { + return iSoft; + } + +const TPtrC8 CIpsecSARekeyData::LocalId() const + { + if (iLocalId == NULL) + { + return KZeroDescriptor(); + } + else + { + return TPtrC8(*iLocalId); + } + } + + +const TPtrC8 CIpsecSARekeyData::RemoteId() const + { + if (iRemoteId == NULL) + { + return KZeroDescriptor(); + } + else + { + return TPtrC8(*iRemoteId); + } + } + + +CArrayFix* CIpsecSARekeyData::TsIL() const + { + __ASSERT_DEBUG(iTS_i != NULL, User::Invariant()); + return CopyTsL(*iTS_i); + } + + +CArrayFix* CIpsecSARekeyData::TsRL() const + { + __ASSERT_DEBUG(iTS_r != NULL, User::Invariant()); + return CopyTsL(*iTS_r); + } + + +CArrayFix* CIpsecSARekeyData::CopyTsL(const CArrayFix& aTS) const + { + CArrayFix* selectorList = new (ELeave) CArrayFixFlat(2); + CleanupStack::PushL(selectorList); + + for (TInt i = 0; i < aTS.Count(); ++i) + { + TIkeV2TrafficSelector selectorCopy(aTS[i]); + selectorList->AppendL(selectorCopy); + } + CleanupStack::Pop(selectorList); + return selectorList; + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2keepalive.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2keepalive.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,95 @@ +/* +* Copyright (c) 2003-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Common keep alive object +* +*/ + + +#include "ikev2keepalive.h" +#include "ikemsgheader.h" +#include "ikev2pluginsession.h" + +CIkeV2KeepAlive* CIkeV2KeepAlive::NewL(TInt DpdKeepAlive, MIkeV2DpdHeartBeatEventHandler& aHandler) +{ + CIkeV2KeepAlive* self = new (ELeave) CIkeV2KeepAlive(DpdKeepAlive, aHandler); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; +} + + +//Constructor +CIkeV2KeepAlive::CIkeV2KeepAlive(TInt aDpdKeepAlive, + MIkeV2DpdHeartBeatEventHandler& aHandler) +: CTimer(EPriorityStandard), iCallback(aHandler), iDpdKeepAlive(aDpdKeepAlive) +{ + __ASSERT_DEBUG(iDpdKeepAlive > 0, User::Invariant()); + CActiveScheduler::Add(this); +} + +//Destructor +CIkeV2KeepAlive::~CIkeV2KeepAlive() +{ + if (IsActive()) + Cancel(); +} + + +void CIkeV2KeepAlive::ConstructL() +{ + // + // If NAT keepalive timoeut allocate (and initialize) a TIkeXmitBfr data buffer for + // NAT keepalive. Allocate a data buffer for special "Echo request" + // keepalive message, if proprietary "Nokia NAT Traversal is used". + // Start keep alive timer + // + CTimer::ConstructL(); + + iRemainingTime = iDpdKeepAlive; + StartTimer(); +} + + +void CIkeV2KeepAlive::DoCancel() +{ + CTimer::DoCancel(); +} + +void CIkeV2KeepAlive::RunL() +{ + if ( iRemainingTime == 0 && iDpdKeepAlive) + { + iCallback.EventHandlerL(); + iRemainingTime = iDpdKeepAlive; + } + StartTimer(); +} + +void CIkeV2KeepAlive::StartTimer() +{ + + if ( iRemainingTime > KMaxTInt/1000000 ) //To avoid overflowing the Timer + { + iRemainingTime -= KMaxTInt/1000000; + After(KMaxTInt); + } + else //No overflow + { + if ( iRemainingTime ) + After(iRemainingTime*1000000); + iRemainingTime = 0; + } +} + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2message.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2message.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,1293 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include +#include +#include + +#include "ikev2message.h" +#include "ikev2const.h" +#include "ikecalist.h" +#include "ikecaelem.h" +#include "ikev2trafficselector.h" +#include "ikecrypto.h" +#include "ikev2identity.h" +#include "ikemsgheader.h" +#include "ikedebug.h" + +static const TUint8 KMessageIdFieldOffset = 20; + +static const TUint KIkePayloadGenericHeaderLength = 4; +static const TUint8 KLengthFieldOffset = 2; + +static const TUint32 KSha1Length = 20; +static const TUint32 KCertReqHeaderLength = 5; +static const TUint32 KCertHeaderLength = 5; +static const TUint32 KSaHeaderLength = 4; +static const TUint32 KKeHeaderLength = 8; +static const TUint32 KNonceHeaderLength = 4; +static const TUint32 KAuthHeaderLength = 8; +static const TUint32 KNotifyHeaderLength = 8; +static const TUint32 KConfigurationHeaderLength = 8; +static const TUint32 KVendorIdHeaderLength = 4; +static const TUint32 KDeleteHeaderLength = 8; +static const TUint32 KEapHeaderLength = 4; +static const TUint32 KTsHeaderLength = 8; +static const TUint32 KEncryptedHeaderLength = 4; + +_LIT8(KNonEspMarker, "\0\0\0\0"); + +CIkeV2Payload::CIkeV2Payload(TUint8 aPayloadType) +:iPayloadType(aPayloadType) + { + } + + +CIkeV2Payload::~CIkeV2Payload() + { + delete iPayloadData; + } + +TUint8 CIkeV2Payload::PayloadType() const + { + return iPayloadType; + } + + +TUint8 CIkeV2Payload::NextPayload() const + { + __ASSERT_DEBUG(iPayloadData->Length() >= KIkePayloadGenericHeaderLength, + User::Invariant()); + + return (*iPayloadData)[0]; + } + + +void CIkeV2Payload::SetNextPayload(TUint8 aNextPayload) + { + __ASSERT_DEBUG(iPayloadData->Length() >= KIkePayloadGenericHeaderLength, + User::Invariant()); + + TPtr8 payloadDataPtr(iPayloadData->Des()); + payloadDataPtr[0] = aNextPayload; + } + + +TUint16 CIkeV2Payload::PayloadLength() const + { + __ASSERT_DEBUG(iPayloadData->Length() >= KIkePayloadGenericHeaderLength, + User::Invariant()); + + return BigEndian::Get16(iPayloadData->Ptr() + KLengthFieldOffset); + } + + +void CIkeV2Payload::SetPayloadLength(TUint16 aLength) + { + __ASSERT_DEBUG(iPayloadData->Length() >= KIkePayloadGenericHeaderLength, + User::Invariant()); + const TUint KLengthPosition = 2; + + BigEndian::Put16(reinterpret_cast(&aLength), aLength); + TPtrC8 length(reinterpret_cast(&aLength), sizeof(aLength)); + + TPtr8 lengthPtr(iPayloadData->Des().MidTPtr(KLengthPosition, + length.Length())); + lengthPtr = length; + } + +TPtrC8 CIkeV2Payload::PayloadData() const + { + return TPtrC8(*iPayloadData); + } + + +CIkevV2CertReqPayload* CIkevV2CertReqPayload::NewL(const CIkeCaList& aCaList) + { + CIkevV2CertReqPayload* self = new (ELeave) CIkevV2CertReqPayload; + CleanupStack::PushL(self); + self->ConstructL(aCaList); + CleanupStack::Pop(self); + + return self; + } + + + +CIkevV2CertReqPayload::CIkevV2CertReqPayload() +:CIkeV2Payload(IKEV2_PAYLOAD_CR) + { + } + + +void CIkevV2CertReqPayload::ConstructL(const CIkeCaList& aCaList) + { + __ASSERT_DEBUG(aCaList.Count() > 0, User::Invariant()); + TUint16 length = (aCaList.Count() * KSha1Length) + KCertReqHeaderLength; + + iPayloadData = HBufC8::NewL(length); + TPtr8 payloadDataPtr(iPayloadData->Des()); + payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength); + payloadDataPtr.FillZ(); + + SetPayloadLength(length); + + TUint8 encoding = X509_CERTIFICATE_SIGN; + TPtrC8 encodingPtr(&encoding, sizeof(encoding)); + payloadDataPtr.Append(encodingPtr); + + for (TUint i = 0; i < aCaList.Count(); ++i) + { + payloadDataPtr.Append(aCaList[i]->KeyHash()); + } + + __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant()); + } + + +CIkevV2CertPayload* CIkevV2CertPayload::NewL(const TDesC8& aCertData) + { + CIkevV2CertPayload* self = new (ELeave) CIkevV2CertPayload; + CleanupStack::PushL(self); + self->ConstructL(aCertData); + CleanupStack::Pop(self); + + return self; + } + + +CIkevV2CertPayload::CIkevV2CertPayload() +:CIkeV2Payload(IKEV2_PAYLOAD_CERT) + { + + } + + +void CIkevV2CertPayload::ConstructL(const TDesC8& aCertData) + { + TUint16 length = aCertData.Length() + KCertHeaderLength; + + iPayloadData = HBufC8::NewL(length); + TPtr8 payloadDataPtr(iPayloadData->Des()); + payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength); + payloadDataPtr.FillZ(); + + SetPayloadLength(length); + + TUint8 encoding = X509_CERTIFICATE_SIGN; + TPtrC8 encodingPtr(&encoding, sizeof(encoding)); + payloadDataPtr.Append(encodingPtr); + payloadDataPtr.Append(aCertData); + + __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant()); + } + + +CIkevV2SaPayload* CIkevV2SaPayload::NewL(const TDesC8& aSaData) + { + CIkevV2SaPayload* self = new (ELeave) CIkevV2SaPayload; + CleanupStack::PushL(self); + self->ConstructL(aSaData); + CleanupStack::Pop(self); + + return self; + } + + +CIkevV2SaPayload::CIkevV2SaPayload() +:CIkeV2Payload(IKEV2_PAYLOAD_SA) + { + } + + +void CIkevV2SaPayload::ConstructL(const TDesC8& aSaData) + { + TUint16 length = aSaData.Length() + KSaHeaderLength; + + iPayloadData = HBufC8::NewL(length); + TPtr8 payloadDataPtr(iPayloadData->Des()); + payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength); + payloadDataPtr.FillZ(); + + SetPayloadLength(length); + + payloadDataPtr.Append(aSaData); + + __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant()); + } + + +CIkevV2KePayload* CIkevV2KePayload::NewL(TUint16 aDHGroup, const TDesC8& aKeData) + { + CIkevV2KePayload* self = new (ELeave) CIkevV2KePayload; + CleanupStack::PushL(self); + self->ConstructL(aDHGroup, aKeData); + CleanupStack::Pop(self); + + return self; + } + + +CIkevV2KePayload::CIkevV2KePayload() +:CIkeV2Payload(IKEV2_PAYLOAD_KE) + { + } + +void CIkevV2KePayload::ConstructL(TUint16 aDHGroup, const TDesC8& aKeData) + { + static const TUint8 KReservedFieldLength = 2; + + TUint16 length = aKeData.Length() + KKeHeaderLength; + + iPayloadData = HBufC8::NewL(length); + TPtr8 payloadDataPtr(iPayloadData->Des()); + payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength); + payloadDataPtr.FillZ(); + + SetPayloadLength(length); + + BigEndian::Put16(reinterpret_cast(&aDHGroup), aDHGroup); + TPtrC8 dhGroupPtr(reinterpret_cast(&aDHGroup), sizeof(aDHGroup)); + payloadDataPtr.Append(dhGroupPtr); + + //Leave reserved bytes zero + payloadDataPtr.SetLength(payloadDataPtr.Length() + KReservedFieldLength); + TPtr8 reservedBytes = payloadDataPtr.RightTPtr(KReservedFieldLength); + reservedBytes.FillZ(); + + payloadDataPtr.Append(aKeData); + + __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant()); + } + + +CIkevV2NoncePayload* CIkevV2NoncePayload::NewL(const TDesC8& aNonceData) + { + CIkevV2NoncePayload* self = new (ELeave) CIkevV2NoncePayload; + CleanupStack::PushL(self); + self->ConstructL(aNonceData); + CleanupStack::Pop(self); + + return self; + } + + +CIkevV2NoncePayload::CIkevV2NoncePayload() +:CIkeV2Payload(IKEV2_PAYLOAD_NONCE) + { + } + + +void CIkevV2NoncePayload::ConstructL(const TDesC8& aNonceData) + { + TUint16 length = aNonceData.Length() + KNonceHeaderLength; + + iPayloadData = HBufC8::NewL(length); + TPtr8 payloadDataPtr(iPayloadData->Des()); + payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength); + payloadDataPtr.FillZ(); + + SetPayloadLength(length); + + payloadDataPtr.Append(aNonceData); + + __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant()); + } + + +CIkevV2IdPayload::CIkevV2IdPayload(TUint8 aPayloadType) +:CIkeV2Payload(aPayloadType) + { + } + +void CIkevV2IdPayload::ConstructL(const CIkeV2Identity& aIdentity) + { + TPtrC8 idPayloadData = aIdentity.PayloadData(); + TUint32 length = idPayloadData.Length() + KIkePayloadGenericHeaderLength; + + iPayloadData = HBufC8::NewL(length); + TPtr8 payloadDataPtr(iPayloadData->Des()); + payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength); + payloadDataPtr.FillZ(); + + SetPayloadLength(length); + + payloadDataPtr.Append(idPayloadData); + + __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant()); + } + + +CIkevV2IdiPayload* CIkevV2IdiPayload::NewL(const CIkeV2Identity& aIdentity) + { + CIkevV2IdiPayload* self = new (ELeave) CIkevV2IdiPayload; + CleanupStack::PushL(self); + self->ConstructL(aIdentity); + CleanupStack::Pop(self); + return self; + } + + +CIkevV2IdiPayload::CIkevV2IdiPayload() +:CIkevV2IdPayload(IKEV2_PAYLOAD_ID_I) + { + } + + +CIkevV2IdrPayload* CIkevV2IdrPayload::NewL(const CIkeV2Identity& aIdentity) + { + CIkevV2IdrPayload* self = new (ELeave) CIkevV2IdrPayload; + CleanupStack::PushL(self); + self->ConstructL(aIdentity); + CleanupStack::Pop(self); + return self; + } + + +CIkevV2IdrPayload::CIkevV2IdrPayload() +:CIkevV2IdPayload(IKEV2_PAYLOAD_ID_R) + { + } + + +CIkeV2AuthPayload* CIkeV2AuthPayload::NewL(TUint8 aAuthMethod, const TDesC8& aAuthData) + { + CIkeV2AuthPayload* self = new (ELeave) CIkeV2AuthPayload; + CleanupStack::PushL(self); + self->ConstructL(aAuthMethod, aAuthData); + CleanupStack::Pop(self); + + return self; + } + + +CIkeV2AuthPayload::CIkeV2AuthPayload() +:CIkeV2Payload(IKEV2_PAYLOAD_AUTH) + { + } + + +void CIkeV2AuthPayload::ConstructL(TUint8 aAuthMethod, const TDesC8& aAuthData) + { + static const TUint8 KReservedFieldLength = 3; + + TUint32 length = aAuthData.Length() + KAuthHeaderLength; + + iPayloadData = HBufC8::NewL(length); + TPtr8 payloadDataPtr(iPayloadData->Des()); + payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength); + payloadDataPtr.FillZ(); + + SetPayloadLength(length); + + TPtrC8 authTypePtr(&aAuthMethod, sizeof(aAuthMethod)); + payloadDataPtr.Append(authTypePtr); + //Leave reserved bytes zero + payloadDataPtr.SetLength(payloadDataPtr.Length() + KReservedFieldLength); + TPtr8 reservedField = payloadDataPtr.RightTPtr(KReservedFieldLength); + reservedField.FillZ(); + + payloadDataPtr.Append(aAuthData); + + __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant()); + } + + +CIkeV2NotifyPayload* CIkeV2NotifyPayload::NewL(TUint8 aProtocolId, + const TDesC8& aSpi, + TUint16 aNotifyType, + const TDesC8& aNotifyData) + { + CIkeV2NotifyPayload* self = new (ELeave) CIkeV2NotifyPayload; + CleanupStack::PushL(self); + self->ConstructL(aProtocolId, aSpi, aNotifyType, aNotifyData); + CleanupStack::Pop(self); + + return self; + } + + +CIkeV2NotifyPayload::CIkeV2NotifyPayload() +:CIkeV2Payload(IKEV2_PAYLOAD_NOTIF) + { + } + + +void CIkeV2NotifyPayload::ConstructL(TUint8 aProtocolId, + const TDesC8& aSpi, + TUint16 aNotifyType, + const TDesC8& aNotifyData) + { + TUint32 length = aSpi.Length() + aNotifyData.Length() + KNotifyHeaderLength; + + iPayloadData = HBufC8::NewL(length); + TPtr8 payloadDataPtr(iPayloadData->Des()); + payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength); + payloadDataPtr.FillZ(); + + SetPayloadLength(length); + + TPtrC8 protocolIdPtr(&aProtocolId, sizeof(aProtocolId)); + TUint8 spiSize = aSpi.Length(); + TPtrC8 spiSizePtr(&spiSize, sizeof(spiSize)); + + BigEndian::Put16(reinterpret_cast(&aNotifyType), aNotifyType); + TPtrC8 notifyTypePtr(reinterpret_cast(&aNotifyType), sizeof(aNotifyType)); + + + payloadDataPtr.Append(protocolIdPtr); + payloadDataPtr.Append(spiSizePtr); + payloadDataPtr.Append(notifyTypePtr); + payloadDataPtr.Append(aSpi); + payloadDataPtr.Append(aNotifyData); + + __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant()); + } + + +CIkeV2ConfigurationPayload* CIkeV2ConfigurationPayload::NewL(TUint8 aCfgType, + const TDesC8& aConfigurationData) + { + CIkeV2ConfigurationPayload* self = new (ELeave) CIkeV2ConfigurationPayload; + CleanupStack::PushL(self); + self->ConstructL(aCfgType, aConfigurationData); + CleanupStack::Pop(self); + + return self; + } + + +CIkeV2ConfigurationPayload::CIkeV2ConfigurationPayload() +: CIkeV2Payload(IKEV2_PAYLOAD_CONFIG) + { + } + + +void CIkeV2ConfigurationPayload::ConstructL(TUint8 aCfgType, + const TDesC8& aConfigurationData) + { + static const TUint8 KReservedFieldLength = 3; + + TUint32 length = aConfigurationData.Length() + KConfigurationHeaderLength; + + iPayloadData = HBufC8::NewL(length); + TPtr8 payloadDataPtr(iPayloadData->Des()); + payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength); + payloadDataPtr.FillZ(); + + SetPayloadLength(length); + + TPtrC8 cfgTypePtr(reinterpret_cast(&aCfgType), sizeof(aCfgType)); + payloadDataPtr.Append(cfgTypePtr); + + //Leave reserved bytes zero + payloadDataPtr.SetLength(payloadDataPtr.Length() + KReservedFieldLength); + TPtr8 reservedField = payloadDataPtr.RightTPtr(KReservedFieldLength); + reservedField.FillZ(); + + payloadDataPtr.Append(aConfigurationData); + + __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant()); + } + + +CIkeV2VendorIdPayload* CIkeV2VendorIdPayload::NewL(const TDesC8& aVendorIdData) + { + CIkeV2VendorIdPayload* self = new (ELeave) CIkeV2VendorIdPayload; + CleanupStack::PushL(self); + self->ConstructL(aVendorIdData); + CleanupStack::Pop(self); + + return self; + } + + +CIkeV2VendorIdPayload::CIkeV2VendorIdPayload() +:CIkeV2Payload(IKEV2_PAYLOAD_VID) + { + } + + +void CIkeV2VendorIdPayload::ConstructL(const TDesC8& aVendorIdData) + { + TUint32 length = aVendorIdData.Length() + KVendorIdHeaderLength; + + iPayloadData = HBufC8::NewL(length); + TPtr8 payloadDataPtr(iPayloadData->Des()); + payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength); + payloadDataPtr.FillZ(); + + SetPayloadLength(length); + + payloadDataPtr.Append(aVendorIdData); + + __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant()); + } + + +CIkeV2DeletePayload* CIkeV2DeletePayload::NewL(TUint8 aProtocolId, + const CDesC8Array& aSpiList) + { + CIkeV2DeletePayload* self = new (ELeave) CIkeV2DeletePayload; + CleanupStack::PushL(self); + self->ConstructL(aProtocolId, aSpiList); + CleanupStack::Pop(self); + + return self; + } + + +CIkeV2DeletePayload::CIkeV2DeletePayload() +:CIkeV2Payload(IKEV2_PAYLOAD_DELETE) + { + } + + +void CIkeV2DeletePayload::ConstructL(TUint8 aProtocolId, const CDesC8Array& aSpiList) + { + TUint16 spiCount = aSpiList.Count(); + TUint8 spiLength = (spiCount > 0) ? aSpiList[0].Length() : 0; + TUint32 length = KDeleteHeaderLength + (spiCount * spiLength); + + iPayloadData = HBufC8::NewL(length); + TPtr8 payloadDataPtr(iPayloadData->Des()); + payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength); + payloadDataPtr.FillZ(); + + SetPayloadLength(length); + + TPtrC8 protocolIdPtr(&aProtocolId, sizeof(aProtocolId)); + TPtrC8 spiLengthPtr(&spiLength, sizeof(spiLength)); + + BigEndian::Put16(reinterpret_cast(&spiCount), spiCount); + TPtrC8 spiCountPtr(reinterpret_cast(&spiCount), sizeof(spiCount)); + + payloadDataPtr.Append(protocolIdPtr); + payloadDataPtr.Append(spiLengthPtr); + payloadDataPtr.Append(spiCountPtr); + + for (TInt i = 0; i < aSpiList.Count(); ++i) + { + const TDesC8& spi = aSpiList[i]; + __ASSERT_DEBUG(spi.Length() == spiLength, User::Invariant()); + payloadDataPtr.Append(spi); + } + + __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant()); + } + + +CIkeV2EapPayload* CIkeV2EapPayload::NewL(const TDesC8& aEapData) + { + CIkeV2EapPayload* self = new (ELeave) CIkeV2EapPayload; + CleanupStack::PushL(self); + self->ConstructL(aEapData); + CleanupStack::Pop(self); + + return self; + } + + +CIkeV2EapPayload::CIkeV2EapPayload() +:CIkeV2Payload(IKEV2_PAYLOAD_EAP) + { + } + + +void CIkeV2EapPayload::ConstructL(const TDesC8& aEapData) + { + TUint32 length = aEapData.Length() + KEapHeaderLength; + + iPayloadData = HBufC8::NewL(length); + TPtr8 payloadDataPtr(iPayloadData->Des()); + payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength); + payloadDataPtr.FillZ(); + SetPayloadLength(length); + + payloadDataPtr.Append(aEapData); + + __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant()); + } + + + +CIkeV2TsPayload::CIkeV2TsPayload(TUint aPayloadType) +:CIkeV2Payload(aPayloadType) + { + } + + +void CIkeV2TsPayload::ConstructL(const CArrayFix& aTsList) + { + //selector format: + // 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // ! TS Type !IP Protocol ID*| Selector Length | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Start Port* | End Port* | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // ! ! + // ~ Starting Address* ~ + // ! ! + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // ! ! + // ~ Ending Address* ~ + // ! ! + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + const TUint16 KIpv4SelectorLength = 2*4 + 2*4; //fixed selector header + 2*IPv4 address length + const TUint16 KIpv6SelectorLength = 2*4 + 2*16;//fixed selector header + 2*IPv6 address length + + TUint8 tsCount = aTsList.Count(); + __ASSERT_DEBUG(tsCount > 0, User::Invariant()); + + + TUint32 length = KTsHeaderLength; + + TUint i; + for (i = 0; i < aTsList.Count(); ++i) + { + if (aTsList[i].Type() == TS_IPV4_ADDR_RANGE) + { + length += KIpv4SelectorLength; //fixed selector header + 2*IPv4 address length + } + else + { + __ASSERT_DEBUG(aTsList[i].Type() == TS_IPV6_ADDR_RANGE, User::Invariant()); + length += KIpv6SelectorLength; //fixed selector header + 2*IPv6 address length + } + } + + iPayloadData = HBufC8::NewL(length); + TPtr8 payloadDataPtr(iPayloadData->Des()); + payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength); + payloadDataPtr.FillZ(); + + SetPayloadLength(length); + + const TPtrC8 tsCountPtr(&tsCount, sizeof(tsCount)); + payloadDataPtr.Append(tsCountPtr); + + _LIT(KReservedField, "\0\0\0"); + payloadDataPtr.Append(KReservedField); + + for (i = 0; i < aTsList.Count(); ++i) + { + TBuf8 selector; + selector.Zero(); + const TIkeV2TrafficSelector& selectorData = aTsList[i]; + TUint8 type = selectorData.Type(); + selector.Append(&type, sizeof(type)); + + TUint8 protocol = selectorData.ProtocolId(); + selector.Append(&protocol, sizeof(protocol)); + + TUint16 selectorLength = 0; + if (selectorData.Type() == TS_IPV4_ADDR_RANGE) + { + BigEndian::Put16(reinterpret_cast(&selectorLength), KIpv4SelectorLength); + } + else + { + BigEndian::Put16(reinterpret_cast(&selectorLength), KIpv6SelectorLength); + } + selector.Append(reinterpret_cast(&selectorLength), sizeof(selectorLength)); + + TInetAddr startAddress = selectorData.StartingAddress(); + TInetAddr endAddress = selectorData.EndingAddress(); + + TUint16 startPort = startAddress.Port(); + TUint16 endPort = endAddress.Port(); + + BigEndian::Put16(reinterpret_cast(&startPort), startPort); + BigEndian::Put16(reinterpret_cast(&endPort), endPort); + + selector.Append(reinterpret_cast(&startPort), sizeof(startPort)); + selector.Append(reinterpret_cast(&endPort), sizeof(endPort)); + + if (selectorData.Type() == TS_IPV4_ADDR_RANGE) + { + TUint32 start = 0; + TUint32 end = 0; + BigEndian::Put32(reinterpret_cast(&start), startAddress.Address()); + BigEndian::Put32(reinterpret_cast(&end), endAddress.Address()); + + selector.Append(reinterpret_cast(&start), sizeof(start)); + selector.Append(reinterpret_cast(&end), sizeof(end)); + } + else + { + TPtrC8 start(&startAddress.Ip6Address().u.iAddr8[0], 16); + TPtrC8 end(&endAddress.Ip6Address().u.iAddr8[0], 16); + selector.Append(start); + selector.Append(end); + } + payloadDataPtr.Append(selector); + } + + __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant()); + } + + +CIkeV2TsiPayload* CIkeV2TsiPayload::NewL(const CArrayFix& aTsList) + { + CIkeV2TsiPayload* self = new (ELeave) CIkeV2TsiPayload(); + CleanupStack::PushL(self); + self->ConstructL(aTsList); + CleanupStack::Pop(self); + + return self; + } + + +CIkeV2TsiPayload::CIkeV2TsiPayload() +:CIkeV2TsPayload(IKEV2_PAYLOAD_TS_I) + { + + } + + +CIkeV2TsrPayload* CIkeV2TsrPayload::NewL(const CArrayFix& aTsList) + { + CIkeV2TsrPayload* self = new (ELeave) CIkeV2TsrPayload(); + CleanupStack::PushL(self); + self->ConstructL(aTsList); + CleanupStack::Pop(self); + + return self; + } + + +CIkeV2TsrPayload::CIkeV2TsrPayload() +:CIkeV2TsPayload(IKEV2_PAYLOAD_TS_R) + { + } + + +CIkeV2EncryptedPayload* CIkeV2EncryptedPayload::NewL(TUint aBlockSize) + { + CIkeV2EncryptedPayload* self = new (ELeave) CIkeV2EncryptedPayload; + CleanupStack::PushL(self); + self->ConstructL(aBlockSize); + CleanupStack::Pop(self); + + return self; + } + + +CIkeV2EncryptedPayload::CIkeV2EncryptedPayload() +:CIkeV2TsPayload(IKEV2_PAYLOAD_ENCR) + { + } + + +void CIkeV2EncryptedPayload::ConstructL(TUint aBlockSize) + { + TUint32 length = aBlockSize + KEncryptedHeaderLength; + + iPayloadData = HBufC8::NewL(length); + TPtr8 payloadDataPtr(iPayloadData->Des()); + payloadDataPtr.SetLength(KIkePayloadGenericHeaderLength); + payloadDataPtr.FillZ(); + + SetPayloadLength(length); + payloadDataPtr.SetLength(length); + + TPtr8 Iv = payloadDataPtr.MidTPtr(KEncryptedHeaderLength); + Iv.SetLength(aBlockSize); + TRandom::RandomL(Iv); + + iBlockSize = aBlockSize; + + __ASSERT_DEBUG(PayloadLength() == iPayloadData->Length(), User::Invariant()); + } + +TUint CIkeV2EncryptedPayload::BlockSize() const + { + return iBlockSize; + } + +TPtrC8 CIkeV2EncryptedPayload::InitializationVector() const + { + return iPayloadData->Right(iBlockSize); + } + +void CIkeV2EncryptedPayload::SetContentLength(TUint16 aLength) + { + //Set the payload length to be: header + Iv + content + SetPayloadLength(aLength + iPayloadData->Length()); + } + +static const TUint KDefaultMessageSize = 4096; +static const TUint32 KIkeV2MsgHeaderLength = 28; +static const TUint8 KIkeV2Version = 2 << 4; + +CIkeV2Message* CIkeV2Message::NewL(const TDesC8& aInitiatorSpi, + const TDesC8& aResponderSpi, + TUint8 aExchangeType, + TBool aIntiator, + TBool aResponse, + TUint32 aMessageId, + MIkeDebug& aDebug) + { + CIkeV2Message* self = new (ELeave)CIkeV2Message(aDebug); + CleanupStack::PushL(self); + self->ConstructL(aInitiatorSpi, + aResponderSpi, + aExchangeType, + aIntiator, + aResponse, + aMessageId); + CleanupStack::Pop(self); + + return self; + } + + +CIkeV2Message::CIkeV2Message(MIkeDebug& aDebug) +:iDebug(aDebug), iModified(ETrue) + { + } + + +void CIkeV2Message::ConstructL(const TDesC8& aInitiatorSpi, + const TDesC8& aResponderSpi, + TUint8 aExchangeType, + TBool aIntiator, + TBool aResponse, + TUint32 aMessageId) + { + __ASSERT_DEBUG(aInitiatorSpi.Length() == 8, User::Invariant()); + __ASSERT_DEBUG(aResponderSpi.Length() == 8, User::Invariant()); + + iIkeV2MessageHeader = HBufC8::NewL(KDefaultMessageSize); + TPtr8 messageDataPtr = iIkeV2MessageHeader->Des(); + + + const TPtrC8 versionPtr(&KIkeV2Version, sizeof(TUint8)); + const TPtrC8 exchangeTypePtr(&aExchangeType, sizeof(TUint8)); + + TUint8 flags = (aIntiator) ? IKEV2_INITIATOR : 0; + flags |= (aResponse) ? IKEV2_RESPONSE_MSG : 0; + + + const TPtrC8 flagsPtr(&flags, sizeof(flags)); + BigEndian::Put32(reinterpret_cast(&aMessageId), aMessageId); + const TPtrC8 messageIdPtr(reinterpret_cast(&aMessageId), sizeof(TUint32)); + + TUint32 length; + BigEndian::Put32(reinterpret_cast(&length), KIkeV2MsgHeaderLength); + const TPtrC8 lengthPtr(reinterpret_cast(&length), sizeof(TUint32)); + + //Add SPIs + messageDataPtr.Append(aInitiatorSpi); + messageDataPtr.Append(aResponderSpi); + + //Left next payload as zero + TUint8 nextPayload = 0; + TPtrC8 nextPayloadPtr(&nextPayload, sizeof(nextPayload)); + messageDataPtr.Append(nextPayloadPtr); + + messageDataPtr.Append(versionPtr); + messageDataPtr.Append(exchangeTypePtr); + messageDataPtr.Append(flagsPtr); + messageDataPtr.Append(messageIdPtr); + messageDataPtr.Append(lengthPtr); + + __ASSERT_DEBUG(iIkeV2MessageHeader->Length() == KIkeV2MsgHeaderLength, User::Invariant()); + } + + +CIkeV2Message::~CIkeV2Message() + { + delete iIkeV2Datagram; + delete iIkeV2MessageHeader; + iPayloads.ResetAndDestroy(); + iPayloads.Close(); + } + + +TPtrC8 CIkeV2Message::InitiatorSpi()const + { + TUint KInitiatorSpiPosition = 0; + TUint KSpiLength = 8; + + return iIkeV2MessageHeader->Mid(KInitiatorSpiPosition, KSpiLength); + } + + +TPtrC8 CIkeV2Message::ResponderSpi() const + { + TUint KResponderSpiPosition = 8; + TUint KSpiLength = 8; + + return iIkeV2MessageHeader->Mid(KResponderSpiPosition, KSpiLength); + } + + +TUint8 CIkeV2Message::Flags() const + { + TUint KFlagsPosition = 19; + return (*iIkeV2MessageHeader)[KFlagsPosition]; + } + + +TUint32 CIkeV2Message::MessageId() const + { + __ASSERT_DEBUG(iIkeV2MessageHeader->Length() >= KIkeV2MsgHeaderLength, User::Invariant()); + const TUint8* messageIdPtr = iIkeV2MessageHeader->Ptr() + KMessageIdFieldOffset; + return BigEndian::Get32(messageIdPtr); + + } + + +void CIkeV2Message::AppendCertReqPayloadL(const CIkeCaList& aCaList) + { + __ASSERT_DEBUG(aCaList.Count() > 0, User::Invariant()); + + CIkevV2CertReqPayload* certReqPayload = CIkevV2CertReqPayload::NewL(aCaList); + AppendPayloadL(certReqPayload); + } + + +void CIkeV2Message::AppendCertPayloadL(const TDesC8& aCertificateData) + { + CIkevV2CertPayload* certPayload = CIkevV2CertPayload::NewL(aCertificateData); + AppendPayloadL(certPayload); + } + + +void CIkeV2Message::AppendSaPayloadL(const TDesC8& aSaData) + { + CIkevV2SaPayload* saPayload = CIkevV2SaPayload::NewL(aSaData); + AppendPayloadL(saPayload); + } + + +void CIkeV2Message::AppendKePayloadL(TUint16 aDHGroup, const TDesC8& aKeData) + { + CIkevV2KePayload* kePayload = CIkevV2KePayload::NewL(aDHGroup, aKeData); + AppendPayloadL(kePayload); + } + + +void CIkeV2Message::AppendNoncePayloadL(const TDesC8& aNonceData) + { + CIkevV2NoncePayload* noncePayload = CIkevV2NoncePayload::NewL(aNonceData); + AppendPayloadL(noncePayload); + } + + +void CIkeV2Message::AppendIdiPayloadL(const CIkeV2Identity& aIdentity) + { + CIkevV2IdiPayload* idiPayload = CIkevV2IdiPayload::NewL(aIdentity); + AppendPayloadL(idiPayload); + } + + +void CIkeV2Message::AppendIdrPayloadL(const CIkeV2Identity& aIdentity) + { + CIkevV2IdrPayload* idrPayload = CIkevV2IdrPayload::NewL(aIdentity); + AppendPayloadL(idrPayload); + } + +void CIkeV2Message::AppendAuthPayloadL(TUint8 aAuthMethod, const TDesC8& aAuthData) + { + CIkeV2AuthPayload* authPayload = CIkeV2AuthPayload::NewL(aAuthMethod, aAuthData); + AppendPayloadL(authPayload); + } + + +void CIkeV2Message::AppendNotifyPayloadL(TUint8 aProtocolId, + const TDesC8& aSpi, + TUint16 aNotifyType, + const TDesC8& aNotifyData) + { + CIkeV2NotifyPayload* notifyPayload = CIkeV2NotifyPayload::NewL(aProtocolId, aSpi, + aNotifyType, aNotifyData); + AppendPayloadL(notifyPayload); + } + +void CIkeV2Message::PrependCookieNotifyPayloadL(const TDesC8& aCookieData) + { + _LIT8(KZeroDesc, ""); + CIkeV2NotifyPayload* notifyPayload = CIkeV2NotifyPayload::NewL(0, KZeroDesc, + COOKIE, aCookieData); + + delete iIkeV2Datagram; + iIkeV2Datagram = NULL; + iModified = ETrue; + + if (iPayloads.Count() > 0) + { + notifyPayload->SetNextPayload(iPayloads[0]->PayloadType()); + } + + TInt err = iPayloads.Insert(notifyPayload, 0); + if (err != KErrNone) + { + delete notifyPayload; + User::Leave(err); + } + + SetNextPayload(notifyPayload->PayloadType()); + } + + +void CIkeV2Message::AppendConfigurationPayloadL(TUint8 aCfgType, + const TDesC8& aConfigurationData) + { + CIkeV2ConfigurationPayload* configPayload = + CIkeV2ConfigurationPayload::NewL(aCfgType, aConfigurationData); + AppendPayloadL(configPayload); + } + + +void CIkeV2Message::AppendVendorIdPayloadL(const TDesC8& aVendorIdData) + { + CIkeV2VendorIdPayload* vendorIdPayload = CIkeV2VendorIdPayload::NewL(aVendorIdData); + AppendPayloadL(vendorIdPayload); + } + +void CIkeV2Message::AppendDeletePayloadL(TUint8 aProtocolId, const CDesC8Array& aSpiList) + { + CIkeV2DeletePayload* deletePayload = CIkeV2DeletePayload::NewL(aProtocolId, aSpiList); + AppendPayloadL(deletePayload); + } + + +void CIkeV2Message::AppendEapPayloadL(const TDesC8& aEapData) + { + CIkeV2EapPayload* eapPayload = CIkeV2EapPayload::NewL(aEapData); + AppendPayloadL(eapPayload); + } + + +void CIkeV2Message::AppendTsiPayloadL(const CArrayFix& aTsList) + { + CIkeV2TsiPayload* tsPayload = CIkeV2TsiPayload::NewL(aTsList); + AppendPayloadL(tsPayload); + } + + +void CIkeV2Message::AppendTsrPayloadL(const CArrayFix& aTsList) + { + CIkeV2TsrPayload* tsPayload = CIkeV2TsrPayload::NewL(aTsList); + AppendPayloadL(tsPayload); + } + + +void CIkeV2Message::AppendEncryptedPayloadL(TUint aBlockSize) + { + __ASSERT_DEBUG(iPayloads.Count() == 0, User::Invariant()); + CIkeV2EncryptedPayload* encryptedPayload = CIkeV2EncryptedPayload::NewL(aBlockSize); + AppendPayloadL(encryptedPayload); + } + +void CIkeV2Message::PrepareIkeMessageDatagramL(TUint16 aEncryptionAlgorith, + const TDesC8& aEncryptionKey, + TUint16 aIntegrityAlgorithm, + const TDesC8& aIntegrityKey, +#ifdef _DEBUG + const TInetAddr& aSourceAddress, +#else + const TInetAddr& /*aSourceAddress*/, +#endif + const TInetAddr& aDestinationAddress) + { + __ASSERT_DEBUG(iPayloads.Count() > 0, User::Invariant()); + + if (iModified) + { + __ASSERT_DEBUG(iIkeV2Datagram == NULL, User::Invariant()); + + if (iPayloads[0]->PayloadType() == IKEV2_PAYLOAD_ENCR) + { + //Datagram is should be encrypted + //Calculate the length of the padding + CIkeV2EncryptedPayload* encryptedPayload = static_cast(iPayloads[0]); + TUint encryptedDataLength = 0; + for(TInt i = 1; i < iPayloads.Count(); ++i) + { + encryptedDataLength += iPayloads[i]->PayloadLength(); + } + + //If the data length is multiple of the blocksize, we add full block length + //of padding. Otherwise we just add padding enough to fill the block. + TUint8 paddingLength = encryptedPayload->BlockSize() - + encryptedDataLength % encryptedPayload->BlockSize(); + //The last octet of the padding tells the length of the padding. + //we just use that value to fill the entire padding. + TInt integrityCheckSumLength = 0; + IkeCrypto::AlgorithmInfo(IKEV2_INTEG, aIntegrityAlgorithm, &integrityCheckSumLength); + + + //The length of the whole datagram: + TUint32 datagramLength = iIkeV2MessageHeader->Length() + + encryptedPayload->PayloadLength() + + encryptedDataLength + + paddingLength + + integrityCheckSumLength; + + //Update header fields + SetLength(datagramLength); + encryptedPayload->SetContentLength((TUint16)(encryptedDataLength + + paddingLength + + integrityCheckSumLength)); + + //Allocate buffer, which has space for the whole datagram. (+ Non ESP marker) + HBufC8* datagram = HBufC8::NewLC(datagramLength + KNonEspMarker().Length()); + TPtr8 datagramPtr = datagram->Des(); + + datagramPtr = *iIkeV2MessageHeader; + datagramPtr.Append(encryptedPayload->PayloadData()); + + //buffer for data, which is encrypted + HBufC8* encryptionSource = HBufC8::NewLC(encryptedDataLength + + paddingLength); + TPtr8 encryptionSourcePtr = encryptionSource->Des(); + + for (TInt i = 1; i < iPayloads.Count(); ++i) + { + const CIkeV2Payload* pl = iPayloads[i]; + __ASSERT_DEBUG(pl->PayloadData().Length() == pl->PayloadLength(), User::Invariant()); + + encryptionSourcePtr.Append(pl->PayloadData()); + datagramPtr.Append(pl->PayloadData()); //This is because we want to trace the datagram + } + + + //Last byte of the padding has to be the length of the padding. + //We fillup the whole padding with this same number + TUint8 paddingValue = paddingLength - 1; + for (TInt i = 0; i < paddingLength; ++i) + { + encryptionSourcePtr.Append(&paddingValue, 1); + datagramPtr.Append(&paddingValue, 1); + } + + + datagramPtr.SetLength(datagram->Length() + integrityCheckSumLength); + TRACE_MSG(*datagram, aSourceAddress, aDestinationAddress, + (CIkePcapTrace::TEncryptionType)aEncryptionAlgorith); + datagramPtr.SetLength(datagram->Length() - integrityCheckSumLength); + + //Extracts the data, which is encrypted. + //(Excludes IKE hdr, Encrypted payload hdr and Iv) + TPtr8 encryptionBuffer = datagramPtr.MidTPtr(iIkeV2MessageHeader->Length() + + KEncryptedHeaderLength + + encryptedPayload->BlockSize()); + __ASSERT_DEBUG(encryptionBuffer.Length() == encryptionSource->Length(), User::Invariant()); + encryptionBuffer.SetLength(0); + IkeCrypto::EncryptL(*encryptionSource, encryptionBuffer, + encryptedPayload->InitializationVector(), + aEncryptionKey, aEncryptionAlgorith); + + CleanupStack::PopAndDestroy(encryptionSource); + + //Extracts the space for the checksum from the end of the buffer + TUint lengthWithoutItegrityCheckSum = datagramPtr.Length(); + datagramPtr.SetLength(lengthWithoutItegrityCheckSum + integrityCheckSumLength); + TPtr8 checksum = datagramPtr.MidTPtr(lengthWithoutItegrityCheckSum); + + //Extracts the source for the integrity checksum calculation + TPtrC8 integrityCheckSumSource = datagram->Left(lengthWithoutItegrityCheckSum); + IkeCrypto::IntegHMACL(integrityCheckSumSource, checksum, aIntegrityKey, aIntegrityAlgorithm); + + CleanupStack::Pop(datagram); + iIkeV2Datagram = datagram; + } + else + { + //calculate the length of unencrypted datagram + TUint datagramLength = iIkeV2MessageHeader->Length(); + for (TInt i = 0; i < iPayloads.Count(); ++i) + { + datagramLength += iPayloads[i]->PayloadLength(); + } + SetLength(datagramLength); + + iIkeV2Datagram = HBufC8::NewL(datagramLength + KNonEspMarker().Length()); + TPtr8 ikeV2DatargramPtr = iIkeV2Datagram->Des(); + ikeV2DatargramPtr.Append(*iIkeV2MessageHeader); + + for (TInt i = 0; i < iPayloads.Count(); ++i) + { + ikeV2DatargramPtr.Append(iPayloads[i]->PayloadData()); + } + TRACE_MSG(*iIkeV2Datagram, aSourceAddress, aDestinationAddress, + (CIkePcapTrace::TEncryptionType)aEncryptionAlgorith); + + } + + if (aDestinationAddress.Port() == FLOATED_IKE_PORT) + { + //insert non esp marker + iIkeV2Datagram->Des().Insert(0, KNonEspMarker); + } + iModified = EFalse; + } + + __ASSERT_DEBUG(!iModified && iIkeV2Datagram != NULL, User::Invariant()); + } + + +TPtrC8 CIkeV2Message::IkeMessageDatagram() const + { + __ASSERT_DEBUG(!iModified && iIkeV2Datagram != NULL, User::Invariant()); + return *iIkeV2Datagram; + } + + +void CIkeV2Message::AppendPayloadL(CIkeV2Payload* aPayload) + { + TInt err = iPayloads.Append(aPayload); + if (err != KErrNone) + { + delete aPayload; + User::Leave(err); + } + + if (iPayloads.Count() > 1) + { + iPayloads[iPayloads.Count() - 2]->SetNextPayload(aPayload->PayloadType()); + } + else + { + SetNextPayload(aPayload->PayloadType()); + } + + delete iIkeV2Datagram; + iIkeV2Datagram = NULL; + iModified = ETrue; + } + +void CIkeV2Message::SetLength(TUint32 aDatagramLength) + { + static const TUint KLengthFieldPosition = 6*4; + BigEndian::Put32(reinterpret_cast(&aDatagramLength), aDatagramLength); + TPtr8 lengthField = iIkeV2MessageHeader->Des().MidTPtr(KLengthFieldPosition, sizeof(aDatagramLength)); + lengthField = TPtrC8(reinterpret_cast(&aDatagramLength), sizeof(aDatagramLength)); + } + + +void CIkeV2Message::SetNextPayload(TUint8 aNextPayload) + { + const TUint KNextPayloadPosition = 16; + TPtr8 ikeHeaderPtr = iIkeV2MessageHeader->Des(); + ikeHeaderPtr[KNextPayloadPosition] = aNextPayload; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2messagesendqueue.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2messagesendqueue.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,236 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 IKE message send que. +* +*/ + +#include "ikev2messagesendqueue.h" +#include "ikemsgheader.h" +#include "ikedebug.h" + +_LIT8(KKeepaliveData, 0xff); + +CIkev2MessageSendQueue* CIkev2MessageSendQueue::NewL(MIkeDataInterface& aDataInterface, + const TInetAddr& aDestinationAddress, + TUint8 aDscp, + TUint aNatKeepAliveInterval, + MIkeDebug& aDebug) + { + CIkev2MessageSendQueue* self = new (ELeave) CIkev2MessageSendQueue(aDataInterface, + aDestinationAddress, + aDscp, + aNatKeepAliveInterval, + aDebug); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + + return self; + } + + +CIkev2MessageSendQueue::CIkev2MessageSendQueue(MIkeDataInterface& aDataInterface, + const TInetAddr& aDestinationAddress, + TUint8 aDscp, + TUint aNatKeepAliveInterval, + MIkeDebug& aDebug) +:CActive(EPriorityStandard), + iDataInterface(aDataInterface), + iNatKeepAliveInterval(aNatKeepAliveInterval), + iDestinationAddress(aDestinationAddress), + iDscp(aDscp), + iDebug(aDebug) + { + CActiveScheduler::Add(this); + + if (iNatKeepAliveInterval == 0) + { + iNatKeepAliveInterval = 120; + } + } + + +void CIkev2MessageSendQueue::ConstructL() + { + iSender = CIkev2Sender::NewL( iDataInterface, + *this); + User::LeaveIfError(iNatKeepaliveTimer.CreateLocal()); + } + + +CIkev2MessageSendQueue::~CIkev2MessageSendQueue() + { + Cancel(); + iNatKeepaliveTimer.Close(); + iSasBehindNat.Close(); + delete iSender; + iIkeMsgSendBuffer.Reset(); + iIkeMsgSendBuffer.Close(); + } + +void CIkev2MessageSendQueue::SendIkeMessageL(const TPtrC8 aIkeMsg, + TBool aFloatedPort) + { + Cancel(); + if (!iSender->IsActive()) + { + iIkeMsgInSending.Set(aIkeMsg); + TUint port = (aFloatedPort) ? FLOATED_IKE_PORT : IKE_PORT; + +#ifdef _DEBUG + TBuf<80> destAddr; + iDestinationAddress.Output(destAddr); + DEBUG_LOG3(_L("No sending active. Message sent immediately to %S:%d DSCP=%d."), &destAddr, port, iDscp); +#endif //_DEBUG + iDestinationAddress.SetPort(port); + iSender->SendIkeMsg(port, iDestinationAddress, iDscp, iIkeMsgInSending); + } + else + { + DEBUG_LOG(_L("Sending in progress, message added to send queue.")); + TIkeMsgWaitQueueObject waitObject = { aIkeMsg, aFloatedPort }; + User::LeaveIfError(iIkeMsgSendBuffer.Append(waitObject)); + } + } + + +void CIkev2MessageSendQueue::CancelSend(const TPtrC8& aIkeMsg) + { + DEBUG_LOG(_L("Sending of one datagram canceled.")); + if (aIkeMsg.Ptr() == iIkeMsgInSending.Ptr()) + { + __ASSERT_DEBUG(iSender->IsActive(), User::Invariant()); + //The NAT keepalive timer should not be active, because sending + //is in progress. + __ASSERT_DEBUG(!IsActive(), User::Invariant()); + iSender->Cancel(); + iIkeMsgInSending.Set(NULL, 0); + // Send next message from queue. + SendIkeMsgCompleted( KErrCancel ); + } + else + { + for (TUint i = 0; i < iIkeMsgSendBuffer.Count(); ++i) + { + if (iIkeMsgSendBuffer[i].iIkeMsg.Ptr() == aIkeMsg.Ptr()) + { + iIkeMsgSendBuffer.Remove(i); + break; + } + } + } + } + +void CIkev2MessageSendQueue::SendIkeMsgCompleted( TInt /*aStatus*/ ) + { + DEBUG_LOG(_L("Ike message send complete.")); + iIkeMsgInSending.Set(NULL, 0); + + if (iIkeMsgSendBuffer.Count() > 0) + { + TIkeMsgWaitQueueObject& waitObject = iIkeMsgSendBuffer[0]; + TUint port = (waitObject.iFloatedPort) ? FLOATED_IKE_PORT : 500; + iSender->SendIkeMsg(port, iDestinationAddress, iDscp, waitObject.iIkeMsg); + iIkeMsgSendBuffer.Remove(0); + iIkeMsgInSending.Set(waitObject.iIkeMsg); + } + else if (iSasBehindNat.Count() > 0 && iNatKeepAliveInterval > 0) + { + ArmKeepaliveTimer(); + } + } + + +void CIkev2MessageSendQueue::CancelAll() + { + iSender->Cancel(); + iIkeMsgSendBuffer.Reset(); + } + + +void CIkev2MessageSendQueue::NewSaBehindNatL(TUint aSaId) + { + DEBUG_LOG1(_L("CIkev2MessageSendQueue::NewSaBehindNatL: SaId=%d"), aSaId); + __ASSERT_DEBUG(iSasBehindNat.Find(aSaId) == KErrNotFound, User::Invariant()); + User::LeaveIfError(iSasBehindNat.Append(aSaId)); + if (!iSender->IsActive() && iNatKeepAliveInterval > 0) + { + //No sending acticve arm the nat keepalive timer. + ArmKeepaliveTimer(); + } + } + + +void CIkev2MessageSendQueue::SaBehindNatDeleted(TUint aSaId) + { + DEBUG_LOG1(_L("CIkev2MessageSendQueue::SaBehindNatDeleted: SaId=%d"), aSaId); + TInt index = iSasBehindNat.Find(aSaId); + __ASSERT_DEBUG(index >= 0, User::Invariant()); + iSasBehindNat.Remove(index); + if (iSasBehindNat.Count() == 0) + { + //Cancel keepalive timer + Cancel(); + } + } + +void CIkev2MessageSendQueue::RunL() + { + //Send the NAT keepalive + + __ASSERT_DEBUG(!iSender->IsActive(), User::Invariant()); + __ASSERT_DEBUG(iSasBehindNat.Count() > 0 && iNatKeepAliveInterval > 0, User::Invariant()); + + if (iRemainingTime == 0) + { + DEBUG_LOG(_L("Sending NAT keepalive")); + iSender->SendIkeMsg(FLOATED_IKE_PORT, iDestinationAddress, iDscp, KKeepaliveData); + } + else if (iRemainingTime > KMaxTInt/1000000) + { + iRemainingTime -= KMaxTInt/1000000; + iNatKeepaliveTimer.After(iStatus, KMaxTInt); + SetActive(); + } + else + { + iNatKeepaliveTimer.After(iStatus, iRemainingTime*1000000); + iRemainingTime = 0; + SetActive(); + } + } + +void CIkev2MessageSendQueue::DoCancel() + { + iNatKeepaliveTimer.Cancel(); + iRemainingTime = 0; + DEBUG_LOG(_L("Keepalive timer canceled")); + } + +void CIkev2MessageSendQueue::ArmKeepaliveTimer() + { + DEBUG_LOG(_L("CIkev2MessageSendQueue::ArmKeepaliveTimer")); + //Arm NAT keepalive timer. + if (iNatKeepAliveInterval > KMaxTInt/1000000 ) + { + iRemainingTime = iNatKeepAliveInterval - KMaxTInt/1000000; + iNatKeepaliveTimer.After(iStatus, KMaxTInt); + } + else + { + iRemainingTime = 0; + iNatKeepaliveTimer.After(iStatus, iNatKeepAliveInterval * 1000000); + } + SetActive(); + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2mobike.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2mobike.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,227 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 Mobility and Multihoming Protocol. +* +*/ + +#include +#include +#include "ikedebug.h" +#include "ikev2mobike.h" +#include "ikev2SAdata.h" +#include "ikemsgrec.h" +#include "ikev2payloads.h" +#include "ikev2const.h" +#include "ikev2Negotiation.h" +#include "ikev2plugin.h" +#include "ikev2natt.h" +#include "ikev2proposal.h" +#include "ikev2pluginsession.h" + +_LIT8(KZeroDesc, ""); + +TBool Ikev2MobIke::ProcessNotifysL(CIkev2Negotiation* aNegotiation, + const CArrayFixFlat& aNotifys, + TBool aRequest, TInt aExchange) +{ + __ASSERT_DEBUG(aNegotiation, User::Invariant()); + if ( !aNegotiation->iHdr.iIkeData->iUseMobIke ) + { + return EFalse; + } + + TInt MsgType; + TNotifPayloadIkev2* Payload; + TPtrC8 Cookie2(NULL,0); + TBool NatDetection = EFalse; + TBool Status = EFalse; + TInt Count = aNotifys.Count(); + TInt i = 0; + + while ( i < Count ) + { + + Payload = aNotifys.At(i); + MsgType = (TInt)Payload->GetMsgType(); + // + // Process possible MOBIKE Notify messages + // + switch ( MsgType ) + { + + case MOBIKE_SUPPORTED: + // + // Remote end supports MOBIKE protocol + // + aNegotiation->iHdr.iMobikeUsed = ETrue; + aNegotiation->iHdr.iFloatedPort = ETrue; // Floated port used for now + aNegotiation->iHdr.iDestinAddr.SetPort(FLOATED_IKE_PORT); + break; + + case ADDITIONAL_IPV4_ADDRESS: + case ADDITIONAL_IPV6_ADDRESS: + // + // Additional IP addresses Notify + // + if ( aNegotiation->iHdr.iMobikeUsed && (aExchange == INFORMATIONAL) ) + { + Status = ETrue; + } + break; + + case UPDATE_SA_ADDRESS: + // + // Peer informs about the IP address change + // + if ( aNegotiation->iHdr.iMobikeUsed && aRequest && (aExchange == INFORMATIONAL) ) + { + aNegotiation->iIkeV2PlugInSession.RemoteAddrChanged(&aNegotiation->iHdr, aNegotiation->iHdr.iDestinAddr); + Status = ETrue; + } + break; + + case COOKIE2: + // + // Peer informs about the IP address change + // + if ( aNegotiation->iHdr.iMobikeUsed && aRequest && (aExchange == INFORMATIONAL) ) + { + Cookie2.Set(Payload->NotifData(), Payload->NotifDataLength()); + Status = ETrue; + } + break; + + case NAT_PREVENTION: + // + // NAT Prevention Notify + // + if ( aNegotiation->iHdr.iMobikeUsed ) + { + if ( aExchange == INFORMATIONAL ) + Status = ETrue; + } + break; + + case UNACCPETABLE_ADDRESSES: + case NAT_PREVENTED: + if ( aNegotiation->iHdr.iMobikeUsed ) + { + if ( aExchange == INFORMATIONAL ) + Status = ETrue; + } + break; + + case NAT_DETECTION_SOURCE_IP: + case NAT_DETECTION_DESTINATION_IP: + if ( aNegotiation->iHdr.iMobikeUsed && (aExchange == INFORMATIONAL)) + { + NatDetection = ETrue; + Status = ETrue; + } + break; + + default: + break; + } + + i ++; + } + + if ( Status && aRequest && (aExchange == INFORMATIONAL) ) + { + // + // Build informational response to MOBIKE request + // + CIkeV2Message* ikeMsg = CIkeV2Message::NewL(aNegotiation->iHdr.SpiI(), + aNegotiation->iHdr.SpiR(), + INFORMATIONAL, + aNegotiation->iHdr.iInitiator, + ETrue, + aNegotiation->iHdr.ExpectedRequestId(), + aNegotiation->iDebug); + + ikeMsg->AppendEncryptedPayloadL(aNegotiation->iHdr.iCipherBlkLth); + + if ( Cookie2.Ptr() ) + { + // + // Peer is using COOKIE2. Return COOKIE2 payload data as such + // + ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, COOKIE, Cookie2); + } + if ( NatDetection ) + { + // + // Peer is using NAT_DETECTION_*_IP payloads. Build corresponding response + // + TBool NatDetectOk; + TInetAddr DummyIp; + DummyIp.SetAddress(KInetAddrNone); // 0.0.0.0 + TUint32 NATFlags = CIkev2NatT::CheckPeerNotifysL(aNotifys, DummyIp, aNegotiation->iHdr.iDestinAddr, FLOATED_IKE_PORT, + ikeMsg->InitiatorSpi(), ikeMsg->ResponderSpi(), + NatDetectOk); + if ( NatDetectOk ) + { + aNegotiation->iHdr.iNATFlags = NATFlags; + aNegotiation->GetNatStatus(NatDetectOk, aNegotiation->iHdr.iDestinAddr); + } + CIkev2NatT* NatNotify = CIkev2NatT::NewL(DummyIp, aNegotiation->iHdr.iDestinAddr, + FLOATED_IKE_PORT, + ikeMsg->InitiatorSpi(), ikeMsg->ResponderSpi()); + CleanupStack::PushL(NatNotify); + + ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, NAT_DETECTION_SOURCE_IP, + NatNotify->SourceNofify()); + ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, NAT_DETECTION_DESTINATION_IP, + NatNotify->DestinNofify()); + + CleanupStack::PopAndDestroy(NatNotify); + } + + aNegotiation->SendIkeMsgL(ikeMsg); + aNegotiation->iIkeV2PlugInSession.UpdateIkev2SAL(&aNegotiation->iHdr, NULL); + if ( (aNegotiation->iState != KStateIkeInfoRequest) && (aNegotiation->iState != KStateIkeDeleteRequest) && (aNegotiation->iState != KStateIkeDeleteResponse) ) + aNegotiation->iState = KStateIkeInfoResponse; + } + // + // else + // Currently there is no need to examine any MOBIKE Notify payloads + // present in Informational response + // + + return Status; +} + +TBool Ikev2MobIke::SendUpdateSaAddrNotifyL(CIkev2Negotiation* aNegotiation) +{ + ASSERT(aNegotiation); + + //we support only changing of our address. + CIkeV2Message* ikeMsg = CIkeV2Message::NewL(aNegotiation->iHdr.SpiI(), + aNegotiation->iHdr.SpiR(), + INFORMATIONAL, + aNegotiation->iHdr.iInitiator, + EFalse, + aNegotiation->iHdr.NextRequestId(), + aNegotiation->iDebug); + + ikeMsg->AppendEncryptedPayloadL(aNegotiation->iHdr.iCipherBlkLth); + ikeMsg->AppendNotifyPayloadL(IKEV2_PROT_NONE, KZeroDesc, UPDATE_SA_ADDRESS, KZeroDesc); + + aNegotiation->SendIkeMsgL(ikeMsg); + + aNegotiation->iState = KStateIkeInfoRequest; + + return ETrue; +} diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2natt.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2natt.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,145 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Class CIkev2NatT implements NAT Traversal functionality specified in IKEv2. +* +*/ +#include +#include "ikev2natt.h" +#include "ikev2SAdata.h" +#include "ikev2payloads.h" +#include "ikev2const.h" +#include "ikecrypto.h" + +CIkev2NatT* CIkev2NatT::NewL(const TInetAddr& aSourceAddr, const TInetAddr& aDestinationAddr, TUint16 aPort, + const TDesC8& aInitiatorSpi, const TDesC8& aResponderSpi) +{ + CIkev2NatT* self = new (ELeave)CIkev2NatT(); + CleanupStack::PushL(self); + self->ConstructL(aSourceAddr, aDestinationAddr, aPort, aInitiatorSpi, aResponderSpi); + CleanupStack::Pop(self); + + return self; +} + +void CIkev2NatT::ConstructL(const TInetAddr& aSourceAddr, const TInetAddr& aDestinationAddr, TUint16 aPort, + const TDesC8& aInitiatorSpi, const TDesC8& aResponderSpi) +{ + iSrcNotify = GenerateNatDetectionHashL(aInitiatorSpi, aResponderSpi, + aSourceAddr, aPort); + + iDstNotify = GenerateNatDetectionHashL(aInitiatorSpi, aResponderSpi, + aDestinationAddr, aPort); +} + +TUint32 CIkev2NatT::CheckPeerNotifysL(const CArrayFixFlat& aNotifys, + const TInetAddr& aLocalAddr, const TInetAddr& aRemoteAddr, TUint16 aPort, + const TDesC8& aInitiatorSpi, const TDesC8& aResponderSpi, TBool& aSupported) +{ + // + // Check does there exists NAT_DETECTION_SOURCE_IP and NAT_DETECTION_DESTINATION_IP + // Notify payload. If found compare payload data to local end NAT + // traversal data as follows: + // -- NAT_DETECTION_SOURCE_IP Notifys are examined against local Notify + // payload iDstIdentiy data: If no match found + // ==> Peer is behind NAT + // -- NAT_DETECTION_DESTINATION_IP Notify is examined against local Notify + // payload iSrcIdentiy data: If no match found + // ==> Local end behind NAT + // + aSupported = EFalse; + TInt Count = aNotifys.Count(); + + CIkev2NatT* RefObj = CIkev2NatT::NewL(aLocalAddr, aRemoteAddr, aPort, + aInitiatorSpi, aResponderSpi); + + TNotifPayloadIkev2* PeerNotify; + TUint32 PeerLth; + TBool SrcMatch = EFalse; + TBool DstMatch = EFalse; + TUint32 NatFlags = 0; + TInt i = 0; + + while ( i < Count ) + { + PeerNotify = aNotifys.At(i); + if ( (PeerNotify->GetMsgType() == NAT_DETECTION_SOURCE_IP) && !SrcMatch ) + { + NatFlags |= REMOTE_END_NAT; + PeerLth = TPayloadIkev2::Cast(PeerNotify)->GetLength() - (TUint32)(PeerNotify->Size() + PeerNotify->GetSPISize()); + const TPtrC8 peerNotify(PeerNotify->NotifData(), PeerLth); + if ( RefObj->DestinNofify().Compare(peerNotify) == 0) + { + SrcMatch = ETrue; + NatFlags &= ~REMOTE_END_NAT; + } + } + else if ( (PeerNotify->GetMsgType() == NAT_DETECTION_DESTINATION_IP) && !DstMatch ) + { + aSupported = ETrue; + NatFlags |= LOCAL_END_NAT; + PeerLth = TPayloadIkev2::Cast(PeerNotify)->GetLength() - (TUint32)(PeerNotify->Size() + PeerNotify->GetSPISize()); + const TPtrC8 peerNotify(PeerNotify->NotifData(), PeerLth); + if ( RefObj->SourceNofify().Compare(peerNotify) == 0 ) + { + DstMatch = ETrue; + NatFlags &= ~LOCAL_END_NAT; + } + } + i ++; + } + + delete RefObj; + return NatFlags; +} + +HBufC8* CIkev2NatT::GenerateNatDetectionHashL(const TDesC8& aInitiatorSpi, const TDesC8& aResponderSpi, + TInetAddr aIpAddress, TUint16 aPort ) const +{ + __ASSERT_DEBUG( aInitiatorSpi.Length() == IKEV2_SPI_SIZE, User::Invariant()); + __ASSERT_DEBUG( aResponderSpi.Length() == IKEV2_SPI_SIZE, User::Invariant()); + + // + // Calculate HASH = SHA1(SPIS | IP | Port) both for local- and remote IP address/port + // + TBuf8<64> hashInData; + + hashInData.Append(aInitiatorSpi); + hashInData.Append(aResponderSpi); + + if ( aIpAddress.Family() == KAfInet ) + { + TUint32 ipv4addr = ByteOrder::Swap32(aIpAddress.Address());//Put in network order + hashInData.Append(reinterpret_cast(&ipv4addr), sizeof(ipv4addr)); + } + else + { + if ( aIpAddress.IsV4Mapped() ) + { + aIpAddress.ConvertToV4(); // IPv4 format + TUint32 ipv4addr = ByteOrder::Swap32(aIpAddress.Address());//Put in network order + hashInData.Append(reinterpret_cast(&ipv4addr), sizeof(ipv4addr)); + } + else + { + const TUint8* addr = &aIpAddress.Ip6Address().u.iAddr8[0]; //Address in a bytestream + hashInData.Append(addr, 16); + } + } + + aPort = ByteOrder::Swap16(aPort); + hashInData.Append(reinterpret_cast(&aPort), sizeof(aPort)); + + return IkeCrypto::PrfL(hashInData, PRF_HMAC_SHA1); +} diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2negotiation.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2negotiation.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,4059 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2/IPSEC SA negotiation +* +*/ + +#include +#include + +#include "ikev2Negotiation.h" +#include "ikedebug.h" +#include "ikev2natt.h" +#include "ikev2mobike.h" +#include "ikev2proposal.h" +#include "ikev2SAdata.h" +#include "ikev2pluginsession.h" +#include "ikev2pfkey.h" +#include "ikev2config.h" +#include "ikev2EapInterface.h" +#include "ikev2payloads.h" +#include "ikev2const.h" +#include "ikemsgrec.h" +#include "ipsecproposal.h" +#include "ipsecselectors.h" +#include "ikepolparser.h" +#include "kmdapi.h" +#include "ikecaelem.h" +#include "ikecalist.h" +#include "ikepkiutils.h" +#include "vpnapidefs.h" +#include "kmdeventloggerif.h" +#include "ipsecsalist.h" +#include "ikev2message.h" +#include "ikev2identity.h" +#include "ikev2acquire.h" +#include "ikev2expire.h" +#include "ikev2ipsecsarekeydata.h" +#include "ikev2messagesendqueue.h" + +_LIT8(KIkev2PSKData, "Key Pad for IKEv2"); +_LIT8(KZeroDesc, ""); + +CIkev2Negotiation* CIkev2Negotiation::NewL(CIkev2PluginSession& aIkeV2PlugInSession, + CPFKeySocketIf& aPfKeySocketIf, + MKmdEventLoggerIf& aEventLogger, + CIkev2MessageSendQueue& aMessageSendQue, + MIkeDebug& aDebug, + CIkeData* aIkeData, + TUint32 aVpnIapId, + TUint32 aSaId, + TInetAddr aPhysicalInterfaceAddress, + TInetAddr aRemoteAddress) + { + + CIkev2Negotiation* self = new (ELeave) CIkev2Negotiation(aIkeV2PlugInSession, aPfKeySocketIf, + aEventLogger, aMessageSendQue, + aDebug, aSaId); + CleanupStack::PushL(self); + self->ConstructL(); + + self->iHdr.iIkeData = aIkeData; + self->iHdr.iVpnIapId = aVpnIapId; + self->iProcessEvents = ETrue; + self->iHdr.iRemoteAddr = aRemoteAddress; + self->iHdr.iRemoteAddr.SetPort(IKE_PORT); + + // + // Get IP address information for IKE SA negotiation + // Remote address is taken from current IKE policy data (CIkeData) + // Local address is resolved via IKE policy using policy handle + // + if ( self->iHdr.iRemoteAddr.IsUnspecified() ) + { + self->iHdr.iRemoteAddr = self->iHdr.iIkeData->iAddr; + self->iHdr.iRemoteAddr.SetPort(IKE_PORT); + } + self->iHdr.iDestinAddr = self->iHdr.iRemoteAddr; + self->iHdr.iLocalAddr = aPhysicalInterfaceAddress; + TInt Scope = self->iHdr.iRemoteAddr.Scope(); + if ( Scope ) + self->iHdr.iLocalAddr.SetScope(Scope); // Set local scope same with remote scope + + CleanupStack::Pop(self); + return self; + } + + +CIkev2Negotiation* CIkev2Negotiation::NewL(CIkev2PluginSession& aIkeV2PlugInSession, + CPFKeySocketIf& aPfKeySocketIf, + MKmdEventLoggerIf& aEventLogger, + CIkev2MessageSendQueue& aMessageSendQue, + MIkeDebug& aDebug, + TIkev2SAData& aIkev2SAdata) + { + CIkev2Negotiation* self = new (ELeave) CIkev2Negotiation(aIkeV2PlugInSession, aPfKeySocketIf, + aEventLogger, aMessageSendQue, + aDebug, aIkev2SAdata.SaId()); + CleanupStack::PushL(self); + self->ConstructL(); + + self->iHdr.Copy(aIkev2SAdata); + self->iState = KStateIkeSaCompleted; + + CleanupStack::Pop(self); + return self; + } + + +CIkev2Negotiation::CIkev2Negotiation(CIkev2PluginSession& aIkeV2PlugInSession, CPFKeySocketIf& aPfKeySocketIf, + MKmdEventLoggerIf& aEventLogger, CIkev2MessageSendQueue& aMessageSendQue, + MIkeDebug& aDebug, TUint32 aSaId) +: iChild(aDebug), iIkeV2PlugInSession(aIkeV2PlugInSession), iPfKeySocketIf(aPfKeySocketIf), + iEventLogger(aEventLogger), iMessageSendQue(aMessageSendQue),iDebug(aDebug), iDHGroupGuess(1) + { + DEBUG_LOG1(_L("CIkev2Negotiation::CIkev2Negotiation: 0x%08x"), this); + + iHdr.SetSaId(aSaId); + iHdr.iWindowSize = DEF_MSG_ID_WINDOW; + } + + +void CIkev2Negotiation::ConstructL() + { + iTimer = CIkev2RetransmitTimer::NewL(*this); + iSpiRetriever = CIpsecSaSpiRetriever::NewL(*this, iPfKeySocketIf); + + iIkeV2PlugInSession.LinkNegotiation(this); // <- takes ownership of this + iProcessEvents = ETrue; + } + + +CIkev2Negotiation::~CIkev2Negotiation() + { + + delete iSpiRetriever; + // Turn off event processing to prevent EAPVPNIF event + iProcessEvents = EFalse; + delete iTimer; + + DEBUG_LOG1(_L("CIkev2Negotiation::~CIkev2Negotiation: 0x%08x"), this); + iIkeV2PlugInSession.RemoveNegotiation(this); + + iHdr.CleanUp(); + + // + // Purge Acquire, Expire and Info message queues + // + CIkev2Acquire::PurgeQue(GetAcquireQue()); + CIkev2Expire::PurgeQue(GetExpireQue()); + + delete iPeerCert; + delete iSavedSaInit; + delete iProposedSA; + delete iDHKeys; + delete iDHPublicPeer; + delete iNonce_I; + delete iNonce_R; + delete iAuthMsgInit; + delete iAuthMsgResp; + delete iRemoteIdentity; + delete iLocalIdentity; + delete iNatNotify; + delete iConfigMode; + delete iEapPlugin; + delete iPkiService; + delete iPresharedKey; + delete iChildSaRequest; + } + +void CIkev2Negotiation::StartIkeSANegotiationL() + { + __ASSERT_DEBUG(iChildSaRequest == NULL, User::Invariant()); + + //This method should be called only if we have IA in use. + //Otherwise the negotiation should start with ProcessAcquire + __ASSERT_DEBUG(iHdr.iIkeData->iUseInternalAddr, User::Invariant()); + + // + // This method is called when an IKE SA negotiation is started due + // a RKMD::Activate() request with policy that uses IA. + // + iHdr.iInitiator = ETrue; + LoadEapPluginL(); + + GetNonceDataL(ETrue); + + CIkev2Acquire* Acquire = IpsecSelectors::BuildVirtualAcquireL(iIkeV2PlugInSession); + CleanupStack::PushL(Acquire); + + if ( !InitPkiServiceL() ) + { + //No PkiService Needed. + //Continue by requesting SPI for IPsecSA. + CIkev2Acquire::Link(Acquire, GetAcquireQue()); + // + // Get SPI for inbound SA with PFKEY GETSPI primitive + // + GetIpsecSPI(Acquire); + } + else + { + iChildSaRequest = Acquire; + } + CleanupStack::Pop(Acquire); + } + +TBool CIkev2Negotiation::StartRespondingL(const ThdrISAKMP& aIkeMessage) + { + // + // This method is called when local end is going to ACT as a + // responder of an IKE SA negotiation. + // Initialize PKI service usage, if needed. Because PKI service + // initialisation is an asynchronous operation we must take a copy + // of incoming IKE message from where it is processed when PKI + // service initialisation is completed. + // + TBool Status( InitPkiServiceL() ); + if ( Status ) + { + TInt MsgLth = (TInt)aIkeMessage.GetLength(); + delete iSavedSaInit; + iSavedSaInit = NULL; + iSavedSaInit = HBufC8::NewL(MsgLth); + iSavedSaInit->Des().Copy((TUint8*)&aIkeMessage, MsgLth); + } + return !Status; + } + +void CIkev2Negotiation::StartIkeSADeleteL() +{ + // + // This method is called when an IKE SA shall be deleted either due + // IKE SA timeout or due a RKMD::Deactivate() request + // + BuildDeleteRequestL(NULL); +} + + +void CIkev2Negotiation::IkeSaCompletedL() +{ + + // + // This method is when an IKE SA negotiation has been succesfully + // completed. + // The following actions are taken: + // -- Get Virtual IP from iConfigMode object, if present and + // modify IKE SA lifetime if Virtual Ip expiration time is + // shorter than configured iKE SA lifetime + // -- Create a new IKE SA object, if not a rekeyd IKE SA + // -- If activation going, call IkeSaCompleted method in plug-in + // + TVPNAddress VirtualIp; + if ( iConfigMode ) + { + VirtualIp = iConfigMode->VirtualIp(); + iHdr.StoreVirtualIp(VirtualIp.iVPNIfAddr); + TUint32 ExpireTime = iConfigMode->ExpireTime(); + if ( ExpireTime && (ExpireTime < iHdr.iLifetime) ) + iHdr.iLifetime = ExpireTime; + } + + if(!iIkeV2PlugInSession.FindIkev2SA(iHdr.SaId(), KSaStateNotDefined, KSaStateNotDefined)) + { + iIkeV2PlugInSession.CreateIkev2SAL(iHdr); + } + + iIkeV2PlugInSession.IkeSaCompleted(KErrNone, VirtualIp); + + iEventLogger.LogEvent(MKmdEventLoggerIf::KLogInfo, R_VPN_MSG_VPN_GW_AUTH_OK, KErrNone, + iHdr.iVpnIapId, &iHdr.iRemoteAddr); + iEventLogger.LogEvent(MKmdEventLoggerIf::KLogInfo, R_VPN_MSG_ADDR_INFO_FOR_VPN_AP, + iHdr.iNATFlags, iHdr.iVpnIapId, + (!VirtualIp.iVPNIfAddr.IsUnspecified() ? &(VirtualIp.iVPNIfAddr) : NULL)); + + if ( iChildSaRequest ) + { + IpsecSANegotiatedL(); + } + if ( RequestsPending() ) + { + ContinueIkeNegotiationL(); + } + else + { + if ( !iHdr.iInitiator ) + { + iIkeV2PlugInSession.StopResponding(); + delete this; // Current negotiation can be deleted + } + else iStopped = ETrue; + } +} + +void CIkev2Negotiation::IkeSaFailed(TInt Status) + { + // + // This method is when a IKE SA negotiation has failed + // The following actions are taken: + // + + TVPNAddress dummyVirtualIp; + + iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest); + + if ( !iHdr.iInitiator ) + iIkeV2PlugInSession.StopResponding(); + + if ( (iSendAttempt <= KMaxSendAttemps ) && + ((iState == KStateIkeSaEapStarted) || + (iState == KStateIkeSaEapGoing))) + iDeleteIkeSA = ETrue; + else iStopped = ETrue; + + iEventLogger.LogEvent(MKmdEventLoggerIf::KLogError, R_VPN_MSG_REAL_IAP_ACT_FAILED, Status, + iHdr.iVpnIapId, &iHdr.iRemoteAddr); + + iIkeV2PlugInSession.IkeSaCompleted(Status, dummyVirtualIp); + } + +void CIkev2Negotiation::IpsecSANegotiatedL() +{ + // + // This method is when an Ipsec SA negotiation has been succesfully + // completed. + // -- Update Ipsec SADB using PFKEY Update and Add primitives + // -- Find a new IKE SA object and queue Ipsec SA data into it + // -- Try to start a new exchange from queue, if there is nothing + // to start in queues mark current negotiation stopped + // + iChild.iSrcSpecific = iChildSaRequest->SrcSpecific(); + Ikev2Pfkey::UpdateIpsecSaDataBaseL(iHdr, iChild, iIkeV2PlugInSession, *iChildSaRequest); + + CIpsecSARekeyData* rekeyData = + CIpsecSARekeyData::NewL(iChildSaRequest->ReplayWindow(), + iChildSaRequest->HardLifetime(), + iChildSaRequest->SoftLifetime(), + iChildSaRequest->TS_i(), + iChildSaRequest->TS_r(), + *iChildSaRequest->LocalId(), + *iChildSaRequest->RemoteId()); + + iChild.PurgeKeyMaterial(); // Ipsec Keymaterial not saved into IKE SA + iChild.DeleteRekeyData(); + iChild.iRekeyData = rekeyData; + + iIkeV2PlugInSession.UpdateIkev2SAL(&iHdr, &iChild); + + delete iChildSaRequest; + iChildSaRequest = NULL; + + if ( RequestsPending() ) + ContinueIkeNegotiationL(); + else + { if ( iState == KStateIkeChildSAResponse ) + delete this; + else iStopped = ETrue; + } +} + + +void CIkev2Negotiation::ProcessIkeMessageL(const ThdrISAKMP& aIkeMessage, + const TInetAddr& aRemote, + TUint16 aLocalPort) + { + // + // Start to process received IKE message by constructing a + // CIkev2Payloads object. CIkev2Payloads construction takes also + // care of the decryption of an Encrypted payload if present. + // + TBool Status( ETrue ); + + CIkev2Payloads* IkeMsg = CIkev2Payloads::NewL(aIkeMessage, iHdr); + CleanupStack::PushL(IkeMsg); + + DEBUG_LOG2(_L("Process IKE message, SAID=%d, Msg ID=%d"), + iHdr.SaId(), aIkeMessage.GetMessageId()); + if ( IkeMsg->Status() ) + { + // + // An error occurred during IKE message parsing + // + SetNotifyCode(IkeMsg->Status()); + DEBUG_LOG1(_L("Error in parsing of received IKE message: %d"), IkeMsg->Status()); + + if ( !iHdr.iInitiator && iState == KStateIdle ) + { + iStopped = ETrue; // Negotiation object shall be released + } + else + { + CheckNotifyCodeL(IkeMsg); + } + CleanupStack::PopAndDestroy(IkeMsg); // IkeMsg + return; + } + + if ( (iHdr.iNATFlags & (REMOTE_END_NAT + MOBIKE_USED)) && + IkeMsg->Encrypted() ) + { + // + // Received IKE message contains Encrypted payload. Save source + // IP as new destination IP to negotiation object + // + iHdr.iDestinAddr = aRemote; + iHdr.iDestinAddr.SetPort(FLOATED_IKE_PORT); + } + + TPtrC8 ikeMsgDes((TUint8*)&aIkeMessage, aIkeMessage.GetLength()); + + TInetAddr localAddr(iHdr.iLocalAddr); + localAddr.SetPort(aLocalPort); + TRACE_MSG(ikeMsgDes, aRemote, localAddr, + (CIkePcapTrace::TEncryptionType)iHdr.iEncrAlg); + + // + // Process received IKE message according to Exchange type + // + switch ( aIkeMessage.GetExchange() ) + { + case IKE_SA_INIT: + DEBUG_LOG(_L("IKE_SA_INIT message received")); + Status = ProcessIkeSaInitL(IkeMsg, aRemote); + if ( !Status ) + IkeSaFailed(KKmdIkeNegotFailed); + break; + + case IKE_AUTH: + DEBUG_LOG(_L("IKE_AUTH message received")); + Status = ProcessIkeAuthL(IkeMsg); + if ( !Status ) + IkeSaFailed(KKmdIkeAuthFailedErr); + break; + + case CREATE_CHILD_SA: + DEBUG_LOG(_L("CREATE_CHILD_SA message received")); + Status = ProcessChildSaL(IkeMsg); + break; + + case INFORMATIONAL: + DEBUG_LOG(_L("INFORMATION message received")); + Status = ProcessInfoMsgL(IkeMsg); + break; + + default: + DEBUG_LOG(_L("UNKNOWN message received\n")); + Status = EFalse; // Negotiation object shall be released + break; + } + + if ( !Status ) + { + if ( iDeleteIkeSA ) + { + // + // Used IKE SA shall be deleted due the fatal error occurred. + // + iDeleteIkeSA = EFalse; + iIkeV2PlugInSession.DeleteIkev2SA(iHdr.SaId()); + BuildDeleteRequestL(NULL); + } + else + { + CheckNotifyCodeL(IkeMsg); + } + } + CleanupStack::PopAndDestroy(IkeMsg); +} + +void CIkev2Negotiation::ProcessAcquireL(const TPfkeyMessage &aPfkeyMsg) + { + // + // Process received PFKEY Acquire primitive + // There is now the following possibilities: + // -- There already exists an IKE SA so new IPSEC SA is negotiated + // using IKE_CHILD_SA exchange + // -- The is no IKE SA yet. + // IPSEC SA can be negotiated concatenated during IKE_AUTH. + // If Virtual IP is specified, the CP payload is used to get + // that virtual IP address. + // + CIkev2Acquire* Acquire = CIkev2Acquire::NewL(aPfkeyMsg, iIkeV2PlugInSession.GetSAId(), + GetLocalAddr(), + Ikev2Proposal::GetDHGroup(iHdr.iIkeData->iGroupDesc_II), ImplicitChildSa()); + + if ( iState == KStateIdle ) + { + CleanupStack::PushL(Acquire); + LoadEapPluginL(); + iHdr.iInitiator = ETrue; + GetNonceDataL(ETrue); // For IKE SA + if ( iHdr.iIkeData->iUseInternalAddr ) + { + CArrayFix* TsI = new (ELeave) CArrayFixFlat(1); + CleanupStack::PushL(TsI); + + TInetAddr StartIp; + TInetAddr EndIp; + StartIp.SetAddress(KInetAddrNone); // 0.0.0.0 + StartIp.SetPort(0); + EndIp.SetAddress(KInetAddrAll); // 255.255.255.255 + EndIp.SetPort(0xffff); + + TIkeV2TrafficSelector ts(StartIp, EndIp, + aPfkeyMsg.iDstAddr.iExt->sadb_address_proto); + TsI->AppendL(ts); + CleanupStack::Pop(TsI); + Acquire->ReplaceTS_i(TsI); + Acquire->SetVirtualIp(); + } + + if ( InitPkiServiceL() ) + { + // Store Acquire to wait PKI service init + iChildSaRequest = Acquire; + CleanupStack::Pop(Acquire); + return; + } + CleanupStack::Pop(Acquire); + } + CIkev2Acquire::Link(Acquire, GetAcquireQue()); + GetIpsecSPI(Acquire); + } + + +void CIkev2Negotiation::ProcessExpireL(const TPfkeyMessage &aPfkeyMsg) + { + // + // Process received PFKEY Expire primitive + // Try to find first IPSEC SA data from the "parent" IKE SA and set + // inbound SA to zero in TIpsecSAData + // + TPtrC8 spi(reinterpret_cast(&aPfkeyMsg.iSa.iExt->sadb_sa_spi), + sizeof(aPfkeyMsg.iSa.iExt->sadb_sa_spi)); + + TIkeV2IpsecSAData* SaData = + iIkeV2PlugInSession.FindIpsecSAData(iHdr.SaId(), spi, ETrue); + if ( !SaData ) + { + DEBUG_LOG(_L("PFKEY Expire received but no SA data found, stop negotiation")); + + iStopped = ETrue; + return; + } + SaData->iSPI_In.Zero(); + CIkev2Expire* Expire = CIkev2Expire::NewL(aPfkeyMsg); + CIkev2Expire::Link(Expire, GetExpireQue()); + + ContinueIkeNegotiationL(); +} + +void CIkev2Negotiation::StartIpsecSaRekeyingL(const TPfkeyMessage &aPfkeyMsg) +{ + + TPtrC8 spi(reinterpret_cast(&aPfkeyMsg.iSa.iExt->sadb_sa_spi), + sizeof(aPfkeyMsg.iSa.iExt->sadb_sa_spi)); + TIkeV2IpsecSAData* SaData = + iIkeV2PlugInSession.FindIpsecSAData(iHdr.SaId(), spi, ETrue); + if ( !SaData ) + { + DEBUG_LOG(_L("No IPSec SA data found, stop rekeying")); + iStopped = ETrue; + return; + } + + iStopped = ETrue; + + CArrayFix* tsIArray = SaData->iRekeyData->TsIL(); + CleanupStack::PushL(tsIArray); + + CArrayFix* tsRArray = SaData->iRekeyData->TsRL(); + CleanupStack::PushL(tsRArray); + + __ASSERT_DEBUG(tsIArray->Count() > 0, User::Invariant()); + __ASSERT_DEBUG(tsRArray->Count() > 0, User::Invariant()); + + TIkeV2TrafficSelector tsI = (*tsIArray)[0]; + TIkeV2TrafficSelector tsR = (*tsRArray)[0]; + + CleanupStack::PopAndDestroy(tsRArray); + CleanupStack::PopAndDestroy(tsIArray); + + + TInetAddr localSelector; + TInetAddr localSelectorMask; + + TInetAddr remoteSelector; + TInetAddr remoteSelectorMask; + + if (iHdr.iInitiator) + { + localSelector = tsI.StartingAddress(); + localSelectorMask = tsI.Mask(); + + remoteSelector = tsR.StartingAddress(); + remoteSelectorMask = tsR.Mask(); + } + else + { + localSelector = tsR.StartingAddress(); + localSelectorMask = tsR.Mask(); + + remoteSelector = tsI.StartingAddress(); + remoteSelectorMask = tsI.Mask(); + } + + CIpsecSaSpecList* SaList = iIkeV2PlugInSession.GetIPsecSaSpecListL(localSelector, localSelectorMask, //local address/port info + remoteSelector, remoteSelectorMask, + aPfkeyMsg.iDstAddr.iExt->sadb_address_proto); + + + CleanupStack::PushL(SaList); + __ASSERT_DEBUG(SaList != NULL, User::Invariant()); + __ASSERT_DEBUG(SaList->Count() > 0, User::Invariant()); + iStopped = EFalse; + + const TIpsecSaSpec& saSpec = SaList->At(0); + + CIkev2Acquire* Acquire = CIkev2Acquire::NewL(aPfkeyMsg, iIkeV2PlugInSession.GetSAId(), GetLocalAddr(), + Ikev2Proposal::GetDHGroup(iHdr.iIkeData->iGroupDesc_II), ImplicitChildSa(), + &saSpec, SaData->iRekeyData); + CleanupStack::PopAndDestroy(SaList); //SaList + + Acquire->SetSPI_ToBeRekeyed(spi); + + if ( iState == KStateIdle ) + { + CleanupStack::PushL(Acquire); + LoadEapPluginL(); + iHdr.iInitiator = ETrue; + GetNonceDataL(ETrue); // For IKE SA + if ( iHdr.iIkeData->iUseInternalAddr ) + { + CArrayFix* TsI = new (ELeave) CArrayFixFlat(1); + CleanupStack::PushL(TsI); + + TInetAddr StartIp; + TInetAddr EndIp; + StartIp.SetAddress(KInetAddrNone); // 0.0.0.0 + StartIp.SetPort(0); + EndIp.SetAddress(KInetAddrAll); // 255.255.255.255 + EndIp.SetPort(0xffff); + + TIkeV2TrafficSelector ts(StartIp, EndIp, + aPfkeyMsg.iDstAddr.iExt->sadb_address_proto); + TsI->AppendL(ts); + Acquire->ReplaceTS_i(TsI); + CleanupStack::Pop(TsI); + Acquire->SetVirtualIp(); + } + + if ( InitPkiServiceL() ) + { + iChildSaRequest = Acquire; // Store Acquire to wait PKI service init + CleanupStack::Pop(Acquire); + return; + } + CleanupStack::Pop(Acquire); + } + CIkev2Acquire::Link(Acquire, GetAcquireQue()); + GetIpsecSPI(Acquire); +} + +void CIkev2Negotiation::GetIpsecSPI(CIkev2Acquire* aAcquire) + { + ASSERT(aAcquire); + // + // Get SPI for inbound SA with PFKEY GETSPI primitive + // + TInetAddr DstAddr; + if ( aAcquire->SrcSpecific() ) + DstAddr = iHdr.iLocalAddr; + else DstAddr.Init(0); + DstAddr.SetPort(0); + TInetAddr SrcAddr = iHdr.iRemoteAddr; + SrcAddr.SetPort(0); + + iSpiRetriever->GetIpsecSaSpi(aAcquire->Id(), + aAcquire->IpsecProtocol(), + SrcAddr, DstAddr); + } + + +void CIkev2Negotiation::IpsecSaSpiRetrieved(TUint32 aSpiRequestId, + TInt aStatus, + TUint32 aSpi) + { + if (aStatus == KErrNone) + { + TRAP(aStatus, IpsecSaSpiRetrievedL(aSpiRequestId, aSpi)); + } + + if (aStatus != KErrNone) + { + //Leave that we have not been able to handle + //above layers. We bail out and report error. + iIkeV2PlugInSession.DeleteIkev2SA(iHdr.SaId()); + iIkeV2PlugInSession.IkeSaDeleted(aStatus); + delete this; + } + } + +void CIkev2Negotiation::CancelOperation() + { + if ( iTimer != NULL ) + { + iTimer->Cancel(); + } + if ( iSpiRetriever != NULL ) + { + iSpiRetriever->Cancel(); + } + } + +void CIkev2Negotiation::IpsecSaSpiRetrievedL(TUint32 aSpiRequestId, TUint32 aSpi) + { + DEBUG_LOG(_L("CIkev2Negotiation::SpiRetrievedL")); + + // + // Ipsec SPI received. Find an Acquire object for received SPI and + // save SPI into found object. + // + CIkev2Acquire* Acquire = CIkev2Acquire::Find(aSpiRequestId, GetAcquireQue()); + __ASSERT_DEBUG(Acquire, User::Invariant()); + + TPtrC8 spiPtr(reinterpret_cast(&aSpi), sizeof(aSpi)); + Acquire->SetSPI_In(spiPtr); + // + // Ipsec SPI received. Find an Acquire object for received SPI and + // save SPI into found object. + // + ContinueIkeNegotiationL(); + } + +void CIkev2Negotiation::ContinueIkeNegotiationL() +{ + // + // This method takes actions according to current state (iState) of + // the negotiation. + // + CIkev2Acquire* Acquire; + CIkev2Expire* Expire; + + switch ( iState ) + { + case KStateIdle: + // + // Start IKE_SA_INIT exchange + // + StartIkeSaInitL(); + break; + + case KStateIkeSaAuthWaitSpi: + { + // + // Complete IKE_AUTH exchange (with concatenated Child SA) + // + iChildSaRequest = CIkev2Acquire::GetNext(GetAcquireQue(), ETrue); + + DEBUG_LOG(_L("CIkev2Negotiation::ContinueIkeNegotiationL")); + DEBUG_LOG1(_L("iChildSaRequest is %d"), (TInt)iChildSaRequest); + + SendIkeAuthMessageL(); + } + break; + + case KStateIkeSaCompleted: + // + // There is no activity going on this negotiation + // If there is something in request queues start process + // them in the following order: + // -- Check if there is something in info queue (NIY) + // -- Check if there is something in expire queue (NIY) + // -- Check if there is ready responses in acquire queue + // -- Check if there is ready request in acquire queue + // + Expire = CIkev2Expire::GetNext(GetExpireQue()); + if ( Expire ) + { + CleanupStack::PushL(Expire); + BuildDeleteRequestL(Expire); + CleanupStack::PopAndDestroy(Expire); + } + else + { + Acquire = CIkev2Acquire::GetNext(GetAcquireQue(), ETrue); + if ( Acquire ) + { + BuildChildSAMessageL(Acquire, EFalse); + } + else + { + Acquire = CIkev2Acquire::GetNext(GetAcquireQue(), EFalse); + BuildChildSAMessageL(Acquire, ETrue); + } + } + break; + + default: + break; + } +} + +void CIkev2Negotiation::StartIkeSaInitL() + { + // + // Create Initiator SPI for the new IKE SA + // + CreateIkeSPI(iHdr.SpiI()); + + // + // Get required peer identity from policy (IDr) + // + iRemoteIdentity = Ikev2Proposal::GetRemoteIdentityL(iHdr.iIkeData); + + __ASSERT_ALWAYS(iHdr.iInitiator, User::Invariant()); + // + // Build and send the first IKE_SA_INIT message (request) + // HDR, SAi1, KEi, Ni, N[NAT_SRC], N[NAT_DST] + // + CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), + iHdr.SpiR(), + IKE_SA_INIT, + iHdr.iInitiator, + EFalse, + iHdr.NextRequestId(), + iDebug); + CleanupStack::PushL(ikeMsg); + + HBufC8* saBfr = Ikev2Proposal::FromPolicyToProposaL(iHdr, iSPI_Rekey, iDHGroupGuess); + CleanupStack::PushL(saBfr); + ikeMsg->AppendSaPayloadL(*saBfr); + CleanupStack::Pop(saBfr); + SetProposedSa(saBfr); + + AppendKEPayloadL(*ikeMsg, iHdr.iDHGroup); + ikeMsg->AppendNoncePayloadL(*iNonce_I); + if ( !iHdr.iIkeData->iUseNatProbing ) + { + delete iNatNotify; + iNatNotify = NULL; + + TInetAddr LocalIp; + if ( iHdr.iIkeData->iUseMobIke ) + LocalIp.SetAddress(KInetAddrNone); + else LocalIp = iHdr.iLocalAddr; + iNatNotify = CIkev2NatT::NewL( + LocalIp, iHdr.iRemoteAddr, IKE_PORT, ikeMsg->InitiatorSpi(), ikeMsg->ResponderSpi()); + + ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, NAT_DETECTION_SOURCE_IP, + iNatNotify->SourceNofify()); + ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, NAT_DETECTION_DESTINATION_IP, + iNatNotify->DestinNofify()); + } + CleanupStack::Pop(ikeMsg); + + SendIkeMsgL(ikeMsg); + iState = KStateIkeSaInitRequest; + } + +void CIkev2Negotiation::SendIkeAuthMessageL() +{ + // + // Build and send IKE_AUTH message + // IKE_AUTH message sent by the initiator is the following: + // HDR(A,B), SK {IDi, [CERT] [CERTREQ], [IDr], [AUTH], [CP], [SAi2, + // TSi, TSr]} + // IKE_AUTH message sent by the responder is the following: + // HDR(A,B), SK {IDr, [CERT,] AUTH, [CP], [SAr2, TSi, TSr]} + // CERT and CERTREQ payloads are added into message on when needed. + // AUTH payload is missing from initiators message when EAP in use. + // IPSEC SA:s are not always negotiated within IKE_AUTH messages. + // In this sitution SAx2, TSi and TSr payloads shall be missing. + // CP payload is used the Virtual IP address (secure network DNS + // IP:s) for client Virtual IP interface. + // Initiators CP payload shall contain CFG_REQUEST and and + // responders CP payload CFG_REPLY. + // When CP payload is used IKE_AUTH message MUST always contain + // IPSEC SA negotiation payloads within. + // In case INITIAL_CONTACT is used, the first IKE_AUTH request on given + // IKE SA contains INITIAL_CONTACT Notification Payload that is added in + // the end of the IKE_AUTH message. + // + + if ( !iLocalIdentity ) + { + // + // Own identity does not exists yet. Do not build IKE_AUTH + // message now + // + iState = KStateIkeWaitingId; + return; + } + + TUint32 MsgId = (iHdr.iInitiator) ? iHdr.NextRequestId() : iHdr.ExpectedRequestId(); + CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), + iHdr.SpiR(), + IKE_AUTH, + iHdr.iInitiator, + !iHdr.iInitiator, //Initiator sends only requests + MsgId, + iDebug); + CleanupStack::PushL(ikeMsg); + + ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth); + + __ASSERT_DEBUG(iLocalIdentity != NULL, User::Invariant()); + if (iHdr.iInitiator) + { + ikeMsg->AppendIdiPayloadL(*iLocalIdentity); + } + else + { + ikeMsg->AppendIdrPayloadL(*iLocalIdentity); + } + + if ( iPkiService && + iPkiService->UserCertificateData().Length() > 0) + { + ikeMsg->AppendCertPayloadL(iPkiService->UserCertificateData()); + } + + if ( iPkiService && + iPkiService->I2CertificateData().Length() > 0) + { + ikeMsg->AppendCertPayloadL(iPkiService->I2CertificateData()); + } + + if ( iPkiService && + iPkiService->I1CertificateData().Length() > 0) + { + ikeMsg->AppendCertPayloadL(iPkiService->I1CertificateData()); + } + + if ( iHdr.iInitiator && iHdr.iIkeData->iInitialContact ) + { + ikeMsg->AppendNotifyPayloadL(IKEV2_PROT_NONE, KZeroDesc, INITIAL_CONTACT, KZeroDesc); + } + + + if ( iHdr.iInitiator && iPkiService != NULL && iPkiService->CaList().Count() > 0) + { + ikeMsg->AppendCertReqPayloadL(iPkiService->CaList()); + } + + if ( iHdr.iInitiator && iRemoteIdentity ) + { + // + // Add IDr payload + // + ikeMsg->AppendIdrPayloadL(*iRemoteIdentity); + } + if ( !iEapPlugin ) + { + HBufC8* authData = NULL; + if ( iHdr.iInitiator ) + { + authData = SignAuthDataL(*iAuthMsgInit, (TUint8)iHdr.iAuthMethod); + } + else + { + authData = SignAuthDataL(*iAuthMsgResp, (TUint8)iHdr.iAuthMethod); + } + CleanupStack::PushL(authData); + ikeMsg->AppendAuthPayloadL(iHdr.iAuthMethod, *authData); + CleanupStack::PopAndDestroy(authData); + } + if ( iHdr.iIkeData->iUseMobIke ) + { + // + // Add MOBIKE_SUPPORTED notify payload + // + ikeMsg->AppendNotifyPayloadL(IKEV2_PROT_NONE, + KZeroDesc, + MOBIKE_SUPPORTED, + KZeroDesc); + } + + + // + // Add Child SA and Traffic selector payloads into IKE_AUTH message + // if required + // + if ( iChildSaRequest ) + { + iChild.iSPI_In = iChildSaRequest->SPI_In(); + iChildSaRequest->AddIpsecSpiToSa(iChild.iSPI_In); + if ( iChildSaRequest->ForVirtualIp() ) + { + // + // As Virtual Ip from peer SGW using Config Payload + // Build CP request data by constructing CIkev2Config Object + // + if ( !iConfigMode ) + iConfigMode = CIkev2Config::NewL(iChildSaRequest); + + ikeMsg->AppendConfigurationPayloadL(iConfigMode->CpType(), iConfigMode->Cp()); + } + ikeMsg->AppendSaPayloadL(*iChildSaRequest->SA()); + + ikeMsg->AppendTsiPayloadL(iChildSaRequest->TS_i()); + ikeMsg->AppendTsrPayloadL(iChildSaRequest->TS_r()); + } + + CleanupStack::Pop(ikeMsg); + SendIkeMsgL(ikeMsg); + + if ( iHdr.iInitiator ) + { + if ( iEapPlugin ) + iState = KStateIkeSaEapStarted; + else iState = KStateIkeSaAuthRequest; + } + else + { + iState = KStateIkeSaCompleted; + IkeSaCompletedL(); + } + +} + +void CIkev2Negotiation::SendKeepAliveMsgL() + { + CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), + iHdr.SpiR(), + INFORMATIONAL, + iHdr.iInitiator, + EFalse, + iHdr.NextRequestId(), + iDebug); + + ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth); + SendIkeMsgL(ikeMsg); + iState = KStateIkeInfoRequest; + + DEBUG_LOG(_L("CIkev2Negotiation::SendKeepAliveMsgL")); + } + + +void CIkev2Negotiation::BuildChildSAMessageL( + CIkev2Acquire* aAcquire, TBool aInitiator) + { + ASSERT(aAcquire); + // + // Build and send CREATE_CHILD_SA message + // CREATE_CHILD_SA request message sent is the following: + // HDR(A,B), SK {[N], SA, Ni, [KEi], [TSi, TSr]} + // CREATE_CHILD_SA response message is the following: + // HDR(A,B), SK {SA, Nr, [KEi], [TSi, TSr]} + // + iChild.iSPI_In = aAcquire->SPI_In(); + iChildSaRequest = aAcquire; + //TPayloadIkev2* PreviousPayload; + //TPayloadIkev2* EncrPayload; + GetNonceDataL(aInitiator); + aAcquire->AddIpsecSpiToSa(aAcquire->SPI_In()); + + TUint32 MsgId = (aInitiator) ? iHdr.NextRequestId() : iHdr.ExpectedRequestId(); + + CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), + iHdr.SpiR(), + CREATE_CHILD_SA, + iHdr.iInitiator, + !aInitiator, + MsgId, + iDebug); + + ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth); + + if (aInitiator && aAcquire->SPI_ToBeRekeyed().Length() > 0) + { + ikeMsg->AppendNotifyPayloadL(aAcquire->IpsecProtocol(), + aAcquire->SPI_ToBeRekeyed(), + REKEY_SA, KZeroDesc); + } + ikeMsg->AppendSaPayloadL(*aAcquire->SA()); + + if ( aInitiator ) + { + ikeMsg->AppendNoncePayloadL(*iNonce_I); + } + else + { + ikeMsg->AppendNoncePayloadL(*iNonce_R); + } + + delete iDHKeys; // Delete old DH object + iDHKeys = NULL; + if ( aAcquire->DHGroup() ) + { + AppendKEPayloadL(*ikeMsg, aAcquire->DHGroup()); + } + ikeMsg->AppendTsiPayloadL(aAcquire->TS_i()); + ikeMsg->AppendTsrPayloadL(aAcquire->TS_r()); + + SendIkeMsgL(ikeMsg); + + if ( aInitiator ) + { + iState = KStateIkeChildSARequest; + } + else + { + if (iDHKeys && iDHPublicPeer) + { + HBufC8* g_ir = iDHKeys->ComputeAgreedKeyL(iDHPublicPeer->Des()); + CleanupStack::PushL(g_ir); + + iChild.GenerateIpsecKeysL(iHdr.iSK_d, *g_ir, + *iNonce_I, *iNonce_R, iHdr.iPRFAlg); + + g_ir->Des().FillZ(); // Wipe out shared secret value from buffer + CleanupStack::PopAndDestroy(); //g_ir + } + else + { + iChild.GenerateIpsecKeysL(iHdr.iSK_d, KZeroDesc, + *iNonce_I, *iNonce_R, iHdr.iPRFAlg); + } + + IpsecSANegotiatedL(); + iState = KStateIkeChildSAResponse; + } +} + +void CIkev2Negotiation::BuildDeleteRequestL(CIkev2Expire* aExpire) +{ + // + // Build and send INFORMATIONAL exchange message with delete payload + // HDR(A,B), SK {D} + // If CIkev2Expire object defined, build a Delete payload with Ipsec + // SPI and protocl stored into CIkev2Expire object. If no CIkev2Expire build + // Delete payload for IKE SA. + // + CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), + iHdr.SpiR(), + INFORMATIONAL, + iHdr.iInitiator, + EFalse, + iHdr.NextRequestId(), + iDebug); + + ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth); + + CDesC8Array* spiArray = new (ELeave) CDesC8ArrayFlat(2); + CleanupStack::PushL(spiArray); + if ( aExpire ) + { + spiArray->AppendL(aExpire->SPI()); + ikeMsg->AppendDeletePayloadL(aExpire->Protocol(), *spiArray); + } + else + { + ikeMsg->AppendDeletePayloadL(IKEV2_PROTOCOL, *spiArray); + } + CleanupStack::PopAndDestroy(spiArray); + + SendIkeMsgL(ikeMsg); + DEBUG_LOG(_L("CIkev2Negotiation::BuildDeleteRequestL() Delete send OK")); + + if ( aExpire ) + { + iState = KStateChildDeleteRequest; + } + else + { + iState = KStateIkeDeleteRequest; + } +} + +void CIkev2Negotiation::BuildIkeSaRekeyMsgL(TBool aRequest) +{ + // + // Build and send CHILD_SA exchange message which contains IKE SA + // rekey message (either request or response) + // HDR, SA, Nonce, KE + // + HBufC8* SaBfr; + HBufC8* Nonce; + TUint32 MsgId; + + if ( aRequest ) + { + // Get a new SA Id for rekeyed IKE SA + iSAid_Rekey = iIkeV2PlugInSession.GetSAId(); + CreateIkeSPI(iSPI_Rekey, ETrue); + SaBfr = Ikev2Proposal::FromPolicyToProposaL(iHdr, iSPI_Rekey, iDHGroupGuess, ETrue); + SetProposedSa(SaBfr); // Save SA payload buffer + GetNonceDataL(ETrue); + Nonce = iNonce_I; + MsgId = iHdr.NextRequestId(); + } + else + { + SaBfr = PeekProposedSa(); + Ikev2Proposal::ChangeSpiInProposal(SaBfr, iSPI_Rekey); + GetNonceDataL(EFalse); + Nonce = iNonce_R; + MsgId = iHdr.ExpectedRequestId(); + } + + CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), + iHdr.SpiR(), + CREATE_CHILD_SA, + iHdr.iInitiator, + !aRequest, + MsgId, + iDebug); + + ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth); + ikeMsg->AppendSaPayloadL(*SaBfr); + ikeMsg->AppendNoncePayloadL(*Nonce); + AppendKEPayloadL(*ikeMsg, iHdr.iDHGroup); + + SendIkeMsgL(ikeMsg); + + if ( aRequest ) + { + iState = KStateIkeSARekeyRequest; + } +} + +void CIkev2Negotiation::CheckNotifyCodeL(CIkev2Payloads* aIkeMsg) + { + ASSERT(aIkeMsg); + // + // Some error has occurred during incoming IKE message handling + // Build an error response with specified Notify message type + // + TInt MsgType( GetNotifyCode() ); + + if ( MsgType ) + { + // + // Build and error response/request with Notify payload + // If received message with error condition is a request + // Notify payload is transmitted in the response IKE message + // of ongoing exchange (with erronous request message id) + // If received message with error conditions is a response + // an informational exchange is initiated with Notify payload + // + CIkeV2Message* XmitHdr = NULL; + TBool Response(aIkeMsg->GetIkeMsg()->GetFlags() & IKEV2_RESPONSE_MSG); + if ( Response ) + { + iState = KStateIkeInfoRequest; + TUint32 MsgId = aIkeMsg->GetIkeMsg()->GetMessageId(); + XmitHdr = CIkeV2Message::NewL(iHdr.SpiI(), + iHdr.SpiR(), + INFORMATIONAL, + iHdr.iInitiator, + EFalse, + MsgId, + iDebug); + + } + else + { + XmitHdr = CIkeV2Message::NewL(iHdr.SpiI(), + iHdr.SpiR(), + aIkeMsg->GetIkeMsg()->GetExchange(), + iHdr.iInitiator, + ETrue, + iHdr.ExpectedRequestId(), + iDebug); + } + + if (aIkeMsg->Encrypted()) + { + XmitHdr->AppendEncryptedPayloadL(iHdr.iCipherBlkLth); + } + + TInt notifyDataLength = 0; + TUint8* notifyData = NotifyData(notifyDataLength); + + if (notifyDataLength == 0) + { + XmitHdr->AppendNotifyPayloadL(IKEV2_PROT_NONE, KZeroDesc, MsgType, KZeroDesc); + } + else + { + TPtrC8 notifyDataPtrC(notifyData, notifyDataLength); + XmitHdr->AppendNotifyPayloadL(IKEV2_PROT_NONE, KZeroDesc, MsgType, notifyDataPtrC); + iNotifyDataLth = 0; //Reset notifydata + } + + SendIkeMsgL(XmitHdr); + + iEventLogger.LogEvent(MKmdEventLoggerIf::KLogError, R_VPN_MSG_SENT_ERROR_RESPONSE, + MsgType, iHdr.iVpnIapId, &iHdr.iRemoteAddr); + } + } + + +void CIkev2Negotiation::GetNatStatus(TBool aSupported, const TInetAddr& aRemote) +{ + // + // Examine NAT discovery status (from iHdr.iNATFlags) and set + // floated port usage indicator, if required. + // + if ( aSupported ) + { + if ( iHdr.iNATFlags & (REMOTE_END_NAT + LOCAL_END_NAT) ) + { + if ( iHdr.iNATFlags & REMOTE_END_NAT ) + { + // + // Remote end is behind NAT. Save current source IP to be + // used as further destination address. + // When remote and is behind NAT it is supposed that it + // must be pure mapping between public- and private IP + // addresses (remote NAPT is NOT supported) + // + DEBUG_LOG(_L("Remote end is behind NAT")); + iHdr.iDestinAddr = aRemote; // Remote end behind NAT, use current source IP as destin + } + + if ( iHdr.iNATFlags & LOCAL_END_NAT ) + { + DEBUG_LOG(_L("NAT discovery result: Local end is behind NAT")); + } + iHdr.iFloatedPort = ETrue; + iHdr.iDestinAddr.SetPort(FLOATED_IKE_PORT); + } + else + { + if ( iHdr.iMobikeUsed ) + { + iHdr.iFloatedPort = ETrue; + iHdr.iDestinAddr.SetPort(FLOATED_IKE_PORT); + } + DEBUG_LOG(_L("NAT discovery result: There is no NAT between negotiating ends")); + } + } + else + { + DEBUG_LOG(_L("NAT discovery operation failed")); + } +} + +void CIkev2Negotiation::CreateIkeSPI(TIkeSPI& aSPI, TBool aRekey) +{ + // + // Create IKE SPI for local end. + // The SPI value is created from the following "parameters" in + // IKEv2 negotiation object: + // - The first 4 octets of SPI value are the SAId (32 bit value) + // - The last 4 octets of SPI contains "pseudo random" value: + // X = (SAId + negotiation object pointer) >> (SAId & 3) + // + TUint32 SpiValue1; + TUint32 SpiValue2; + if ( aRekey ) + SpiValue1 = iSAid_Rekey; + else SpiValue1 = iHdr.SaId(); + Mem::Copy((TUint8*)&SpiValue2, (TUint8*)this, 4); + SpiValue2 = (SpiValue2 + SpiValue1) >> (SpiValue1 & 3); + PUT32(aSPI.Ptr(), SpiValue1); + PUT32((aSPI.Ptr() + 4), SpiValue2); + aSPI.SetLength(IKEV2_SPI_SIZE); +} + +void CIkev2Negotiation::LoadEapPluginL() +{ + // + // If EAP configured in policy, construct EAP interface object to + // communicate EAP ECOM plug-in + // If consruction causes an error, stop negotiation request + // + iHdr.iEAPType = iHdr.iIkeData->iEAPProtocol; + if ( !iEapPlugin && iHdr.iEAPType ) + { + iEapPlugin = CIkev2EapIf::NewL(*this, (TUint8)iHdr.iEAPType, iHdr.iIkeData, iDebug); + TInt Status = iEapPlugin->Status(); + if ( Status != KErrNone ) + { + iStopped = ETrue; + } + else iEapPlugin->QueryIdentity(); + } +} + +TBool CIkev2Negotiation::InitPkiServiceL() +{ + DEBUG_LOG(_L("-> CIkev2Negotiation::InitPkiServiceL")); + // + // If EAP configured in policy, construct EAP interface object to + // communicate EAP ECOM plug-in + // If consruction causes an error, return corresponding error code + // to stop negotiation request + // + TBool Status = EFalse; + if ( !iPkiService && Ikev2Proposal::PkiServiceNeeded(iHdr.iIkeData) ) + { + iPkiService = CIkeV2PkiService::NewL(*this, iDebug); + + if (iHdr.iIkeData->iCAList->Count() == 0) + { + User::Leave(KVpnErrInvalidCaCertFile); + } + + iPkiService->InitIkeV2PkiService(iHdr.iIkeData); + iState = KStateIkeInitPkiService; + Status = ETrue; + } + + DEBUG_LOG(_L("<- CIkev2Negotiation::InitPkiServiceL")); + return Status; +} + + +void CIkev2Negotiation::SendIkeMsgL(CIkeV2Message* aMsg) +{ + ASSERT(aMsg); + + TPtrC8 encryptionKey; + TPtrC8 integrityKey; + if ( iHdr.iInitiator ) + { + encryptionKey.Set(iHdr.iSK_ei); + integrityKey.Set(iHdr.iSK_ai); + } + else + { + encryptionKey.Set(iHdr.iSK_er); + integrityKey.Set(iHdr.iSK_ar); + } + + TInetAddr sourceAddr(iHdr.iLocalAddr); + if (iHdr.iFloatedPort) + { + sourceAddr.SetPort(FLOATED_IKE_PORT); + } + else + { + sourceAddr.SetPort(IKE_PORT); + } + aMsg->PrepareIkeMessageDatagramL(iHdr.iEncrAlg, encryptionKey, + iHdr.iIntegAlg, integrityKey, + sourceAddr, iHdr.iDestinAddr); + iMessageSendQue.SendIkeMessageL(aMsg->IkeMessageDatagram(), iHdr.iFloatedPort); + + if (aMsg->Flags() & IKEV2_RESPONSE_MSG ) + { + iHdr.SaveRespMsg(aMsg); + iHdr.iRespRetryCount = 0; + } + else + { + iSendAttempt = 1; + iTimer->Cancel(); + iTimer->IssueRequest(iSendAttempt); // Start retry timer + + iHdr.SaveRequestMsg(aMsg); + } +} + +void CIkev2Negotiation::RetransmitRequest() + { + TRAPD(err, DoRetransmitL(EFalse)); + if ( err != KErrNone ) + { + iIkeV2PlugInSession.IkeSaDeleted( err ); + } + } + +void CIkev2Negotiation::DoRetransmitL(TBool aResponse) +{ + if ( aResponse ) + { + // + // Peer has retransmitted a request, retransmit last response + // message saved. + // + if ( iHdr.iLastResponse && (iHdr.iRespRetryCount <= KMaxSendAttemps) ) + { + iHdr.iRespRetryCount ++; + //iHdr.iLastResponse = NULL; + DEBUG_LOG3(_L("IKE response message rexmitted on SAId: %d , Retry: %d , State: %d"), iHdr.SaId(), iHdr.iRespRetryCount, iState ); + + iMessageSendQue.SendIkeMessageL(iHdr.iLastResponse->IkeMessageDatagram(), + iHdr.iFloatedPort); + } + else iStopped = ETrue; + } + else + { + // + // No response received to a transmitted IKE request message + // Retransmit message if retry count not exhausted + // + DEBUG_LOG(_L("No response received for transmitted IKE request.")); + + iSendAttempt++; + iMessageSendQue.CancelSend(iHdr.iLastRequest->IkeMessageDatagram()); + + if ( iSendAttempt <= KMaxSendAttemps ) + { + DEBUG_LOG3(_L("IKE Message rexmitted on SAId: %d , State: %d , Retry: %d"),iHdr.SaId(), iState, iSendAttempt ); + iMessageSendQue.SendIkeMessageL(iHdr.iLastRequest->IkeMessageDatagram(), + iHdr.iFloatedPort); + iTimer->IssueRequest(iSendAttempt); // Restart retry timer + } + else + { + DEBUG_LOG3(_L("Transmit retry count reached on SAId: %d , State: %d , retry: %d"),iHdr.SaId(), iState, iSendAttempt ); + if ( iState < KStateIkeSaCompleted ) + { + IkeSaFailed(KKmdIkeNegotFailed); // IKE SA negotiation going + } + else + { + iIkeV2PlugInSession.DeleteIkev2SA(iHdr.SaId()); + iIkeV2PlugInSession.IkeSaDeleted(KKmdIkeNoResponseErr); //IKE SA deletion going + delete this; + } + } + } + } + + +void CIkev2Negotiation::IkeV2PkiInitCompleteL(TInt aStatus) + { + + DEBUG_LOG(_L("-> CIkev2Negotiation::IkeV2PkiInitCompleteL")); + // + // The implementation for class MPkiServiceComplete virtual function + // This method is called when a PKI service operation is + // completed. + // + + __ASSERT_ALWAYS( iPkiService != NULL, User::Invariant()); + __ASSERT_ALWAYS(iState == KStateIkeInitPkiService, User::Invariant()); + + switch(aStatus) + { + case KErrNone: + // + // PKI service object has been constructed + // Start IKE_SA_INIT exchange + // + iState = KStateIdle; + if ( iChildSaRequest ) + { + CIkev2Acquire* Acquire = iChildSaRequest; + iChildSaRequest = NULL; + CIkev2Acquire::Link(Acquire, GetAcquireQue()); + GetIpsecSPI(Acquire); + } + else if ( iSavedSaInit ) + { + TPtr8 IkeMsg(iSavedSaInit->Des()); + const ThdrISAKMP* IkeMessage = ThdrISAKMP::Ptr(IkeMsg); + ProcessIkeMessageL(*IkeMessage, iHdr.iRemoteAddr, IKE_PORT); + if ( Stopped() ) + delete this; + } + break; + case KErrNotFound: + DEBUG_LOG(_L("IKEv2 CA certificate retrieve failed. Certificate not found")); + IkeSaFailed(KVpnErrInvalidCaCertFile); + break; + default: + { + DEBUG_LOG1(_L("IKEv2 CA certificate retrieve failed (%d)"), aStatus); + IkeSaFailed(aStatus); + } + break; + } + + DEBUG_LOG(_L("<- CIkev2Negotiation::IkeV2PkiInitCompleteL")); + } + + +void CIkev2Negotiation::SendEapDataL(HBufC8* aEapData) +{ + // + // Send an IKE containing an EAP payload (within Encrypted Payload) + // The entire EAP payload data is provided in aEapData buffer + // + CleanupStack::PushL(aEapData); + if ( iState == KStateIkeSaEapGoing ) + { + __ASSERT_DEBUG(iHdr.iInitiator, User::Invariant()); + + CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), iHdr.SpiR(), + IKE_AUTH, + iHdr.iInitiator, + EFalse, + iHdr.NextRequestId(), + iDebug); + CleanupStack::PushL(ikeMsg); + ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth); + ikeMsg->AppendEapPayloadL(*aEapData); + CleanupStack::Pop(ikeMsg); + SendIkeMsgL(ikeMsg); + } + CleanupStack::PopAndDestroy(aEapData); +} + +void CIkev2Negotiation::EapEventL(TInt aEvent) + { + // See whether the object is accepting any events + // (it is, by default, but will not take events during destruction phase) + if (!iProcessEvents) + { + return; + } + // + // An event idicated by the EAP plugin process event according to + // event type + // + switch ( aEvent ) + { + case KEapEventSuccess: + if ( (iState == KStateIkeSaEapGoing) || (iState == KStateIkeSaEapStarted) ) + { + // + // EAP auhtentication succeeded. + // Build IKE message HDR, SK {AUTH} + // + __ASSERT_DEBUG( iHdr.iInitiator, User::Invariant()); + + CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), iHdr.SpiR(), + IKE_AUTH, + iHdr.iInitiator, + EFalse, + iHdr.NextRequestId(), + iDebug); + CleanupStack::PushL(ikeMsg); + ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth); + + + HBufC8* authData = SignAuthDataL(*iAuthMsgInit, (TUint8)iHdr.iAuthMethod); + CleanupStack::PushL(authData); + ikeMsg->AppendAuthPayloadL(iHdr.iAuthMethod, *authData); + CleanupStack::PopAndDestroy(authData); + + CleanupStack::Pop(ikeMsg); + SendIkeMsgL(ikeMsg); + iState = KStateIkeSaAuthRequest; + iEapCompleted = ETrue; + } + break; + + case KEapEventGetIdentity: + GetOwnIdentityL(ETrue); // Gets the Identity from EAP plugin + if ( iState == KStateIkeWaitingId ) + { + // + // Identity data provided by the EAP plug-in + // Complete local signed data and send the first + // IKE_AUTH message + // + AddIdToSignedDataL(ETrue, iAuthMsgInit, iLocalIdentity->PayloadData()); + SendIkeAuthMessageL(); + } + break; + + case KEapEventGetPSK: + if ( iState == KStateIkeSaEapGoing ) + { + // + // Preshared key provided by the EAP plug-in + // Get key data and link it into negotiation object + // + iPresharedKey = iEapPlugin->MSK(); + } + break; + + default: // = KEapEventFailed + // + // EAP authentication is failed. Stop negotiation + // + IkeSaFailed(KKmdIkeAuthFailedErr); // IKE SA negotiation going + break; + } + } + +TBool CIkev2Negotiation::ProcessIkeSaInitL(CIkev2Payloads* aIkeMsg, const TInetAddr& aRemote) +{ + ASSERT(aIkeMsg); + // + // Process IKE message of exchange type IKE_SA_INIT + // + ThdrISAKMP* IkeHdr = aIkeMsg->GetIkeMsg(); // IKE Message fixed header + TBool Response = IkeHdr->GetFlags() & IKEV2_RESPONSE_MSG; + TBool Initiator = IkeHdr->GetFlags() & IKEV2_INITIATOR; + TUint32 MsgId = IkeHdr->GetMessageId(); + + if ( iHdr.iInitiator ) + { + if ( Initiator ) { + DEBUG_LOG1(_L("IKEv2 Message with Orig_Init-bit in wrong state: %d"), iState); + return ETrue; + } + if ( !Response ) + { + DEBUG_LOG1(_L("IKEv2 Message is not response; state: %d"), iState); + return ETrue; + } + if ( MsgId != iHdr.ExpectedResponseId() ) + { + DEBUG_LOG1(_L("Wrong message id in response; state: %d"), iState); + return ETrue; + } + + if (iState == KStateIkeSaInitRequest) + { + //record responder SPI + aIkeMsg->GetIkeMsg()->GetSPI_R(iHdr.SpiR()); + + // + // Received message should be a response to a + // IKE_SA_INIT request transmitted. + // + if (IkeHdr->GetPayload() == IKEV2_PAYLOAD_NOTIF) + { + return ProcessNotifyPayloadsL(*aIkeMsg->iNotifs, EFalse, IKE_SA_INIT); + } + // + // Response message should be format: + // HDR(A,B), SAr1, KEr, Nr, [CERTREQ] + // + if ( !CheckPayloadsOrder(aIkeMsg, IKE_SA_INIT, ETrue) ) + { + DEBUG_LOG1(_L("Erroneous IKE_SA_INIT response: %d"), iState); + return EFalse; + } + if ( !Ikev2Proposal::VerifySaResponseL(iHdr, iChild, *PeekProposedSa(), *aIkeMsg) ) + { + DEBUG_LOG1(_L("Unaccepted SA content in IKE_SA_INIT response: %d"),iState); + return EFalse; + } + if ( aIkeMsg->iNonce->PlDataLen() < IKEV2_MIN_NONCE_SIZE ) + { + DEBUG_LOG1(_L("Nonce data too short %d"), iState); + return EFalse; + } + + if ( iNatNotify ) + { + TBool Supported; + TInetAddr LocalIp; + if ( iHdr.iIkeData->iUseMobIke ) + LocalIp.SetAddress(KInetAddrNone); + else LocalIp = iHdr.iLocalAddr; + +#ifdef _DEBUG + TBuf<80> debugBuf; + DEBUG_LOG(_L("Calculating NAT detection:")); + LocalIp.Output(debugBuf); + DEBUG_LOG2(_L("LocalIp %S:%d"), &debugBuf, IKE_PORT); + iHdr.iRemoteAddr.Output(debugBuf); + DEBUG_LOG2(_L("RemoteIp %S:%d"), &debugBuf, IKE_PORT); +#endif + + iHdr.iNATFlags = CIkev2NatT::CheckPeerNotifysL(*aIkeMsg->iNotifs, LocalIp, iHdr.iRemoteAddr, IKE_PORT, + iHdr.SpiI(), iHdr.SpiR(), Supported); + GetNatStatus(Supported, aRemote); + } + + delete iNonce_R; + iNonce_R = NULL; + + iNonce_R = HBufC8::NewL(aIkeMsg->iNonce->PlDataLen()); + iNonce_R->Des().Copy(aIkeMsg->iNonce->PayloadData(), aIkeMsg->iNonce->PlDataLen()); + if ( !ProcessKeyExchangeL((TKEPayloadIkev2*)aIkeMsg->iKe, iHdr.iDHGroup) ) + { + return EFalse; + } + + // + // IKE_SA_INIT request is completed enter IKE_AUTH + // + GenerateIkeKeysL(); + TPtrC8 ikeHdrPtr((TUint8*)IkeHdr, IkeHdr->GetLength()); + SaveSignedDataL(EFalse, ikeHdrPtr); // Save IKE_AUTH message 2 + + //We ignore possible cert req payloads and just work + //according our policy + if ( !iHdr.iEAPType && + (iHdr.iAuthMethod == RSA_DIGITAL_SIGN || iHdr.iAuthMethod == DSS_DIGITAL_SIGN) ) + { + SaveSignedDataL(ETrue, iHdr.iLastRequest->IkeMessageDatagram()); // Own identity not yet saved to signed data + + GetOwnIdentityL(); // Get own Identity from Certificate (or policy) + AddIdToSignedDataL(ETrue, iAuthMsgInit, iLocalIdentity->PayloadData()); + } + else + { + // + // Check if "implicit" Child SA exchange required + // by getting request CIkev2Acquire object from queue + // + GetOwnIdentityL(); + SaveSignedDataL(ETrue, iHdr.iLastRequest->IkeMessageDatagram()); // Own identity saved to signed data + } + iChildSaRequest = CIkev2Acquire::GetNext(GetAcquireQue(), EFalse); + SendIkeAuthMessageL(); + } + else + { + // + // Ignore received message silently + // + DEBUG_LOG1(_L("IKE_SA_INIT response received in state %d"), iState); + } + } + else { + if ( !Initiator ) + { + DEBUG_LOG1(_L("IKEv2 Message without Orig_Init-bit in wrong, state: %d"), iState); + return ETrue; + } + if ( Response ) + { + DEBUG_LOG1(_L("IKEv2 Message is not request, state: %d"), iState); + return ETrue; + } + + switch ( iState ) + { + case KStateIdle: + case KStateIkeSaInitResponse: + //Record Initiator SPI + aIkeMsg->GetIkeMsg()->GetSPI_I(iHdr.SpiI()); + iHdr.SpiI().SetLength(IKEV2_SPI_SIZE); + + // + // Received message should be an IKE_SA_INIT request + // Request message should be format: + // HDR(A,0), SAi1, KEi, Ni, [CERTREQ] + // + { + if ( !CheckPayloadsOrder(aIkeMsg, IKE_SA_INIT, EFalse) ) + { + DEBUG_LOG1(_L("Erroneous IKE_SA_INIT request: %d"), iState); + return EFalse; + } + if ( MsgId != iHdr.ExpectedRequestId() ) { + if ( iHdr.iLastResponse != NULL && + MsgId == iHdr.iLastResponse->MessageId() && + iState == KStateIkeSaInitResponse ) + { + // + // Retransmission of an earlier IKE_SA_INIT + // request. Retransmit current IKE_SA_INIT + // response (if retry count not exhausted) + // + DoRetransmitL(ETrue); + return ETrue; + } + else { + DEBUG_LOG1(_L("Wrong message id in request, state: %d"), iState); + return EFalse; + } + } + if ( iState == KStateIkeSaInitResponse ) + return EFalse; // IKE_SA_INIT request retry with a new message ID + iIkeV2PlugInSession.StartResponding(); + + // + // Build a SA payload from current IKE policy and + // verify received IKE SA request with it + // + HBufC8* SaBfr = Ikev2Proposal::FromPolicyToProposaL(iHdr, iSPI_Rekey, iDHGroupGuess); + CleanupStack::PushL(SaBfr); + HBufC8* proposedSa = NULL; + TBool SaOk = Ikev2Proposal::VerifySaRequestAndGetProposedSaBufferL(iHdr, iChild, + *SaBfr, *aIkeMsg, + proposedSa); + CleanupStack::PopAndDestroy(); + if ( !SaOk ) + { + DEBUG_LOG1(_L("Unaccepted SA content in IKE_SA_INIT request: %d"),iState); + SetNotifyCode(NO_PROPOSAL_CHOSEN); + return EFalse; + } + SetProposedSa(proposedSa); + proposedSa = NULL; + if ( aIkeMsg->iNonce->PlDataLen() < IKEV2_MIN_NONCE_SIZE ) + { + DEBUG_LOG1(_L("Nonce data too short %d"), iState); + return EFalse; + } + + //Check peer NAT status + TBool useNatDetection = EFalse; + if ( !iHdr.iIkeData->iUseNatProbing ) + { + TInetAddr LocalIp; + if ( iHdr.iIkeData->iUseMobIke ) + LocalIp.SetAddress(KInetAddrNone); + else LocalIp = iHdr.iLocalAddr; + iHdr.iNATFlags = CIkev2NatT::CheckPeerNotifysL(*aIkeMsg->iNotifs, LocalIp, + iHdr.iRemoteAddr, IKE_PORT, + iHdr.SpiI(), iHdr.SpiR(), useNatDetection); + } + + if ( !ProcessKeyExchangeL((TKEPayloadIkev2*)aIkeMsg->iKe, iHdr.iDHGroup) ) + return EFalse; + + + // + // Create own SPI (responder) + // + CreateIkeSPI(iHdr.SpiR()); + delete iNonce_I; + iNonce_I = NULL; + iNonce_I = HBufC8::NewL(aIkeMsg->iNonce->PlDataLen()); + iNonce_I->Des().Copy(aIkeMsg->iNonce->PayloadData(), aIkeMsg->iNonce->PlDataLen()); + GetNonceDataL(EFalse); + + TPtrC8 ikeHdrPtr((TUint8*)IkeHdr, IkeHdr->GetLength()); + SaveSignedDataL(EFalse, ikeHdrPtr); // Save IKE_AUTH message 2 + + // + // Build IKE_SA_INIT response message: HDR, SAr1, KEr, Nr, [CERTREQ] + // + __ASSERT_DEBUG(!iHdr.iInitiator, User::Invariant()); + CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), iHdr.SpiR(), + IKE_SA_INIT, + iHdr.iInitiator, + ETrue, + iHdr.ExpectedRequestId(), + iDebug); + CleanupStack::PushL(ikeMsg); + + HBufC8* saBfr = Ikev2Proposal::FromPolicyToProposaL(iHdr, iSPI_Rekey, iDHGroupGuess); + CleanupStack::PushL(saBfr); + ikeMsg->AppendSaPayloadL(*saBfr); + CleanupStack::Pop(saBfr); + SetProposedSa(saBfr); + + AppendKEPayloadL(*ikeMsg, iHdr.iDHGroup); + ikeMsg->AppendNoncePayloadL(*iNonce_R); + + if ( iPkiService ) + { + ikeMsg->AppendCertReqPayloadL(iPkiService->CaList()); + } + + if ( useNatDetection ) + { + delete iNatNotify; + iNatNotify = NULL; + + TInetAddr LocalIp; + if ( iHdr.iIkeData->iUseMobIke ) + LocalIp.SetAddress(KInetAddrNone); + else LocalIp = iHdr.iLocalAddr; + + + iNatNotify = CIkev2NatT::NewL(LocalIp, iHdr.iRemoteAddr, IKE_PORT, ikeMsg->InitiatorSpi(), ikeMsg->ResponderSpi()); + ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, NAT_DETECTION_SOURCE_IP, + iNatNotify->SourceNofify()); + ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, NAT_DETECTION_DESTINATION_IP, + iNatNotify->DestinNofify()); + } + GetNatStatus(useNatDetection, aRemote); + CleanupStack::Pop(ikeMsg); + SendIkeMsgL(ikeMsg); + GenerateIkeKeysL(); + + SaveSignedDataL(ETrue, ikeMsg->IkeMessageDatagram()); // Own identity is not yet saved to signed data + iState = KStateIkeSaInitResponse; + } + break; + + default: + // + // Ignore received message silently + // + DEBUG_LOG1(_L("IKE_SA_INIT message received in state %d"), iState); + break; + + } + } + + return ETrue; +} + +TBool CIkev2Negotiation::ProcessIkeAuthL(CIkev2Payloads* aIkeMsg) +{ + ASSERT(aIkeMsg); + // + // Process IKE message of exchange type IKE_AUTH + // + ThdrISAKMP* IkeHdr = aIkeMsg->GetIkeMsg(); // IKE Message fixed header + TBool Response = IkeHdr->GetFlags() & IKEV2_RESPONSE_MSG; + TBool Initiator = IkeHdr->GetFlags() & IKEV2_INITIATOR; + TUint32 MsgId = IkeHdr->GetMessageId(); + + if ( iHdr.iInitiator ) + { + if ( Initiator ) + { + DEBUG_LOG1(_L("IKEv2 Message with Orig_Init-bit in wrong state: %d"), iState); + return ETrue; + } + if ( !Response ) + { + DEBUG_LOG1(_L("IKEv2 Message is not response; state: %d"), iState); + return ETrue; + } + if ( MsgId != iHdr.ExpectedResponseId() ) + { + DEBUG_LOG1(_L("Wrong message id in response; state: %d"), iState); + return ETrue; + } + + switch ( iState ) + { + case KStateIkeSaAuthRequest: + DEBUG_LOG(_L("Handling IKE_AUTH response")); + // + // Received message should be a response to a + // IKE_AUTH request transmitted. + // Response message should be format: + // HDR(A,B), SK {IDr, [CERT,] AUTH, [CP], SAr2, TSi, TSr} + // + if ( aIkeMsg->iEncr ) + { + ProcessNotifyPayloadsL(*aIkeMsg->iNotifs, EFalse, IKE_AUTH); + if ( iDeleteIkeSA ) + { + DEBUG_LOG1(_L("Error Notify in IKE_AUTH response: %d"), iState); + + //Because we are just in IKE_AUTH no IKE_SAs exists --> we don't + //want to delete one. So we set iDeleteIkeSA back to false. + iDeleteIkeSA = EFalse; + + return EFalse; + } + } + if ( !CheckPayloadsOrder(aIkeMsg, IKE_AUTH, ETrue) ) + { + DEBUG_LOG1(_L("Erroneous IKE_AUTH response: %d"), iState); + SetNotifyCode(INVALID_SYNTAX); + + if ( iChildSaRequest && !iChildSARejected && !aIkeMsg->iSa ) + { + iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest); + } + + return EFalse; + } + DEBUG_LOG(_L("IKE_AUTH payload order check passed")); + TBool Status; + if ( iEapCompleted ) + { + Status = AuthenticatePeerL(aIkeMsg->iAuth); + } + else + { + if ( iPkiService && !VerifyPeerCertificateL(aIkeMsg->iCerts, aIkeMsg->iIdR) ) + { + SetNotifyCode(AUTHENTICATION_FAILED); + return EFalse; + } + Status = AddIdAndAuthenticatePeerL(aIkeMsg); + } + if ( !Status ) + { + SetNotifyCode(AUTHENTICATION_FAILED); + return EFalse; + } + // + // If implicit Child SA negotiation requested, + // verify IPSEC SA- and Traffic selector payloads, too + // + if ( iChildSaRequest ) + { + DEBUG_LOG(_L("Processing CHILD_SA creation")); + if ( !iChildSARejected ) + { + if ( !Ikev2Proposal::VerifySaResponseL(iHdr, iChild, *iChildSaRequest->SA(), *aIkeMsg) ) + { + DEBUG_LOG1(_L("Unaccepted SA payload content in IKE_AUTH response: %d"),iState); + SetNotifyCode(NO_PROPOSAL_CHOSEN); + iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest); + return EFalse; + } + DEBUG_LOG(_L("SA response verified")); + if ( !IpsecSelectors::VerifyTrafficSelectorsL(iChildSaRequest, (TTSPayloadIkev2*)aIkeMsg->iTsI, (TTSPayloadIkev2*)aIkeMsg->iTsR ) ) + { + DEBUG_LOG1(_L("Unaccepted Traffic Selectors in IKE_AUTH response: %d"),iState); + SetNotifyCode(TS_UNACCEPTABLE); + iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest); + return EFalse; + } + DEBUG_LOG(_L("Traffic selectors verified")); + if ( aIkeMsg->iCp ) + { + if ( iConfigMode ) + { + iConfigMode->ProcessCpL(aIkeMsg->iCp); + } + else + { + DEBUG_LOG(_L("Unsolicited CP payload in IKE_AUTH response")); + } + } + iChildSaRequest->SetSPI_Out(iChild.iSPI_Out); + DEBUG_LOG(_L("Generating IPsec keys")); + iChild.GenerateIpsecKeysL(iHdr.iSK_d, KZeroDesc, + *iNonce_I, *iNonce_R, iHdr.iPRFAlg); + DEBUG_LOG(_L("IPsec keys generated")); + } + else + { + DEBUG_LOG1(_L("Implicit CHILD_SA rejected Notify in IKE_AUTH response: %d"), iState); + iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest); + } + } + // + // IKE_AUTH request is completed and IKE SA has been + // negotiated + // + IkeSaCompletedL(); + break; + + case KStateIkeSaEapStarted: + // + // Received message should be an IKE_AUTH response + // containing an EAP payload. + // The content of received IKE message shall be: + // HDR, SK {IDr, [CERT,] AUTH, EAP } + // + if ( !aIkeMsg->iEncr || !aIkeMsg->iIdR || !aIkeMsg->iAuth || !aIkeMsg->iEap ) + { + DEBUG_LOG1(_L("Erroneous IKE_AUTH response: %d"), iState); + SetNotifyCode(INVALID_SYNTAX); + return EFalse; + } + if ( iPkiService && !VerifyPeerCertificateL(aIkeMsg->iCerts, aIkeMsg->iIdR) ) + { + SetNotifyCode(AUTHENTICATION_FAILED); + return EFalse; + } + if ( !AddIdAndAuthenticatePeerL(aIkeMsg) ) + { + SetNotifyCode(AUTHENTICATION_FAILED); + return EFalse; + } + iState = KStateIkeSaEapGoing; + iEapPlugin->EapDataInbound(aIkeMsg->iEap); + break; + + case KStateIkeSaEapGoing: + // + // Received message should be an IKE_AUTH response + // containing an EAP payload. + // The content of received IKE message shall be: + // HDR, SK {EAP} + // + if ( !aIkeMsg->iEncr || !aIkeMsg->iEap ) + { + DEBUG_LOG1(_L("Erroneous IKE_AUTH response: %d"), iState); + SetNotifyCode(INVALID_SYNTAX); + return EFalse; + } + iEapPlugin->EapDataInbound(aIkeMsg->iEap); + break; + + default: + // + // Ignore received message silently + // + DEBUG_LOG1(_L("IKE_AUTH response received in state %d"), iState); + break; + + } + } + else + { + if ( !Initiator ) + { + DEBUG_LOG1(_L("IKEv2 Message without Orig_Init-bit in wrong, state: %d"), iState); + return ETrue; + } + if ( Response ) + { + DEBUG_LOG1(_L("IKEv2 Message is not request, state: %d"), iState); + return ETrue; + } + switch ( iState ) + { + case KStateIkeSaInitResponse: + case KStateIkeSaCompleted: + // + // Received message should be an IKE_AUTH request + // Request message should be format: + // HDR(A,B), SK {IDi, [CERT,] [CERTREQ,] [IDr,] AUTH, SAi2, TSi, TSr} + // + if ( !CheckPayloadsOrder(aIkeMsg, IKE_AUTH, EFalse) ) + { + DEBUG_LOG1(_L("Erroneous IKE_AUTH request: %d"), iState); + SetNotifyCode(INVALID_SYNTAX); + return EFalse; + } + if ( MsgId != iHdr.ExpectedRequestId() ) { + if ( iHdr.iLastResponse != NULL && + MsgId == iHdr.iLastResponse->MessageId() && + iState == KStateIkeSaCompleted ) + { + // + // Retransmission of an earlier IKE_SA_INIT + // request. Retransmit current IKE_SA_INIT + // response (if retry count not exhausted) + // + DoRetransmitL(ETrue); + return ETrue; + } + else { + DEBUG_LOG1(_L("Wrong message id in request, state: %d"), iState); + SetNotifyCode(INVALID_MESSAGE_ID); + StoreNotifyData32(MsgId); + return EFalse; + } + } + if ( iState == KStateIkeSaCompleted ) + return EFalse; // IKE_AUTH request retry with a new message ID + + //if ( aIkeMsg->iEncr ) + //{ + ProcessNotifyPayloadsL(*aIkeMsg->iNotifs, EFalse, IKE_AUTH); + if ( iDeleteIkeSA ) + { + DEBUG_LOG1(_L("Error Notify in IKE_AUTH response: %d"), iState); + return EFalse; + } + //} + + if ( iPkiService && !VerifyPeerCertificateL(aIkeMsg->iCerts, aIkeMsg->iIdI) ) + { + DEBUG_LOG(_L("Peer certificate validation failed.")); + SetNotifyCode(AUTHENTICATION_FAILED); + return EFalse; + } + if ( !AddIdAndAuthenticatePeerL(aIkeMsg) ) + { + SetNotifyCode(AUTHENTICATION_FAILED); + return EFalse; + } + // + // Process "concatenated" Child SA- and Traffic + // Selector payloads if present + // + if ( aIkeMsg->iSa ) + { + DEBUG_LOG(_L("IKE_AUTH request has SA and TS payload.")); + CIkev2Acquire* Acquire = IpsecSelectors::GetIpsecPolicyL(iIkeV2PlugInSession, aIkeMsg); + if ( !Acquire ) + { + DEBUG_LOG1(_L("Unaccepted Traffic Selectors in IKE_AUTH request: %d"),iState); + SetNotifyCode(TS_UNACCEPTABLE); + return EFalse; + } + CleanupStack::PushL(Acquire); + HBufC8* proposedSaBuffer = NULL; + if (!Ikev2Proposal::VerifySaRequestAndGetProposedSaBufferL(iHdr, iChild, + *Acquire->SA(), *aIkeMsg, + proposedSaBuffer)) + { + CleanupStack::PopAndDestroy(Acquire); + DEBUG_LOG1(_L("Unaccepted SA content in IKE_AUTH request: %d"),iState); + SetNotifyCode(NO_PROPOSAL_CHOSEN); + return EFalse; + } + SetProposedSa(proposedSaBuffer); + proposedSaBuffer = NULL; + // + // Replace SA payload buffer in CIkev2Acquire with + // selected SA payload built in VerifySaRequestL + // + CleanupStack::Pop(Acquire); + Acquire->ReplaceSA(GetProposedSa()); + Acquire->SetSPI_Out(iChild.iSPI_Out); + Acquire->SetResponse(); + if ( iChild.iTransport ) + { + + Acquire->SetTransport(); + } + CIkev2Acquire::Link(Acquire, GetAcquireQue()); + DEBUG_LOG(_L("Acquire linked.")); + + if ( aIkeMsg->iCp ) + { + // + // CP payload received as IKE SA responder + // Handle CP payload and return "dummy" + // virtual IP to initiator. + // + delete iConfigMode; + iConfigMode = NULL; + iConfigMode = CIkev2Config::NewL(Acquire, (TInetAddr*)&iHdr.iRemoteAddr); + iConfigMode->ProcessCpL(aIkeMsg->iCp); + Acquire->SetVirtualIp(); + } + // + // Get SPI for new inbound SA + // + iChild.GenerateIpsecKeysL(iHdr.iSK_d, KZeroDesc, + *iNonce_I, *iNonce_R, iHdr.iPRFAlg); + + if ( iPkiService && !iEapPlugin && + aIkeMsg->iCertReqs && + aIkeMsg->iCertReqs->Count() ) + { + GetOwnIdentityL(); // Get own Identity from Certificate (or policy) + AddIdToSignedDataL(ETrue, iAuthMsgResp, iLocalIdentity->PayloadData()); + + CIkev2Acquire* Acquire = CIkev2Acquire::PeekFirst(GetAcquireQue()); + if ( Acquire ) + { + GetIpsecSPI(Acquire); + iState = KStateIkeSaAuthWaitSpi; + } + else + { + DEBUG_LOG(_L("CIkev2Acquire::PeekFirst returned NULL.")); + DEBUG_LOG(_L("Sending IKE_AUTH response.")); + SendIkeAuthMessageL(); + } + + } + else + { + GetOwnIdentityL(); + AddIdToSignedDataL(ETrue, iAuthMsgResp, iLocalIdentity->PayloadData()); + GetIpsecSPI(Acquire); + iState = KStateIkeSaAuthWaitSpi; + } + } + else + { + if ( iPkiService && !iEapPlugin && + aIkeMsg->iCertReqs && + aIkeMsg->iCertReqs->Count() ) + { + GetOwnIdentityL(); // Get own Identity from Certificate (or policy) + AddIdToSignedDataL(ETrue, iAuthMsgResp, iLocalIdentity->PayloadData()); + + CIkev2Acquire* Acquire = CIkev2Acquire::PeekFirst(GetAcquireQue()); + if ( Acquire ) + { + GetIpsecSPI(Acquire); + iState = KStateIkeSaAuthWaitSpi; + } + else + { + SendIkeAuthMessageL(); + } + } + else + { + // + // Build and send an IKE_AUTH response + // + GetOwnIdentityL(); + AddIdToSignedDataL(ETrue, iAuthMsgResp, iLocalIdentity->PayloadData()); + SendIkeAuthMessageL(); + } + } + break; + + default: + // + // Ignore received message silently + // + DEBUG_LOG1(_L("IKE_SA_INIT message received in state %d"), iState); + break; + } + } + + return ETrue; +} + +TBool CIkev2Negotiation::ProcessChildSaL(CIkev2Payloads* aIkeMsg) +{ + ASSERT(aIkeMsg); + // + // Process IKE message of exchange type CREATE_CHILD_SA + // + TUint16 PfsDHGroup; + ThdrISAKMP* IkeHdr = aIkeMsg->GetIkeMsg(); // IKE Message fixed header + TBool Response = IkeHdr->GetFlags() & IKEV2_RESPONSE_MSG; + TBool Initiator = IkeHdr->GetFlags() & IKEV2_INITIATOR; + TUint32 MsgId = IkeHdr->GetMessageId(); + + if ( iHdr.iInitiator ) + { + if ( Initiator ) + { + DEBUG_LOG1(_L("IKEv2 Message with Orig_Init-bit in wrong state: %d"), iState); + SetNotifyCode(INVALID_SYNTAX); + return EFalse; + } + } + else + { + if ( !Initiator ) + { + DEBUG_LOG1(_L("IKEv2 Message without Orig_Init-bit in wrong state: %d"), iState); + SetNotifyCode(INVALID_SYNTAX); + return EFalse; + } + } + + if ( Response ) + { + // + // CREATE_CHILD_SA response message received + // + switch ( iState ) + { + case KStateIkeChildSARequest: + // + // Received message should be a response to a + // CREATE_CHILD_SA request transmitted. + // Response message should be format: + // HDR(A,B), SK { SA, Nr, [KEr], [TSi, TSr]} + // + if ( MsgId != iHdr.ExpectedResponseId() ) + { + DEBUG_LOG1(_L("Wrong message id in response; state: %d"), iState); + + SetNotifyCode(INVALID_MESSAGE_ID); + StoreNotifyData32(MsgId); + return EFalse; + } + if ( aIkeMsg->iEncr ) + { + ProcessNotifyPayloadsL(*aIkeMsg->iNotifs, EFalse, CREATE_CHILD_SA); + if ( iDeleteIkeSA ) + { + DEBUG_LOG1(_L("Error Notify in CREATE_CHILD_SA response: %d"), iState); + return EFalse; + } + if ( iChildSARejected ) + { + DEBUG_LOG1(_L("CHILD_SA rejected Notify in CREATE_CHILD_SA response: %d"), iState); + iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest); + iStopped = ETrue; + return EFalse; + } + } + if ( !CheckPayloadsOrder(aIkeMsg, CREATE_CHILD_SA, ETrue) ) + { + DEBUG_LOG1(_L("Erroneous CREATE_CHILD_SA response: %d"), iState); + SetNotifyCode(INVALID_SYNTAX); + iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest); + return EFalse; + } + if ( aIkeMsg->iNonce->PlDataLen() < IKEV2_MIN_NONCE_SIZE ) + { + DEBUG_LOG1(_L("Nonce data too short %d"), iState); + iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest); + iStopped = ETrue; + return EFalse; + } + + if ( !Ikev2Proposal::VerifySaResponseL(iHdr, iChild, *iChildSaRequest->SA(), *aIkeMsg) ) + { + DEBUG_LOG1(_L("Unaccepted SA content in CREATE_CHILD_SA response: %d"),iState); + SetNotifyCode(NO_PROPOSAL_CHOSEN); + iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest); + return EFalse; + } + if ( !IpsecSelectors::VerifyTrafficSelectorsL(iChildSaRequest, (TTSPayloadIkev2*)aIkeMsg->iTsI, (TTSPayloadIkev2*)aIkeMsg->iTsR ) ) + { + DEBUG_LOG1(_L("Unaccepted Traffic Selectors in CREATE_CHILD_SA response: %d"),iState); + SetNotifyCode(TS_UNACCEPTABLE); + iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest); + return EFalse; + } + delete iNonce_R; + iNonce_R = NULL; + iNonce_R = HBufC8::NewL(aIkeMsg->iNonce->PlDataLen()); + iNonce_R->Des().Copy(aIkeMsg->iNonce->PayloadData(), aIkeMsg->iNonce->PlDataLen()); + PfsDHGroup = iChildSaRequest->DHGroup(); + if ( PfsDHGroup ) + { + if ( !ProcessKeyExchangeL((TKEPayloadIkev2*)aIkeMsg->iKe, PfsDHGroup) ) + { + iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest); + return EFalse; + } + HBufC8* g_ir = iDHKeys->ComputeAgreedKeyL(iDHPublicPeer->Des()); + CleanupStack::PushL(g_ir); + + iChild.GenerateIpsecKeysL(iHdr.iSK_d, *g_ir, + *iNonce_I, *iNonce_R, iHdr.iPRFAlg); + + + g_ir->Des().FillZ(); // Wipe out shared secret value from buffer + CleanupStack::PopAndDestroy(); //g_ir + + } + else if ( aIkeMsg->iKe ) + { + DEBUG_LOG1(_L("Unsolicted Key Exchange payload present in CREATE_CHILD_SA response: %d"),iState); + SetNotifyCode(INVALID_KE_PAYLOAD); + iChildSaRequest = Ikev2Pfkey::DeleteInboundSPI(iHdr, iIkeV2PlugInSession, iChildSaRequest); + return EFalse; + } + else + { + iChild.GenerateIpsecKeysL(iHdr.iSK_d, KZeroDesc, + *iNonce_I, *iNonce_R, iHdr.iPRFAlg); + + } + // + // CREATE_CHILD_SA request is completed Update + // + IpsecSANegotiatedL(); + break; + + case KStateIkeSARekeyRequest: + // + // Received message should be a response to a + // IKE SA rekey CHILD_SA request transmitted. + // Response message should be format: + // HDR(A,B), SK { SA, Nr, KEr } + // + if ( CheckPayloadsOrder(aIkeMsg, CREATE_CHILD_SA, ETrue) && aIkeMsg->iKe ) + { + DEBUG_LOG1(_L("IKE SA rekey message received as CHILD_SA response: %d"), iState); + ProcessIkeSARekeyL(aIkeMsg); + } + else + { + DEBUG_LOG1(_L("Erroneous IKE SA rekey message received as CHILD_SA response: %d"),iState); + } + //iIkeV2PlugInSession.UpdateIkev2SAL(&iHdr, NULL, EFalse); + BuildDeleteRequestL(NULL); // Delete IKE SA rekeyed + iIkeV2PlugInSession.DeleteIkev2SA(iHdr.SaId()); + break; + + default: + // + // Ignore received message silently + // + DEBUG_LOG1(_L("CREATE_CHILD_SA response received in state %d"), iState); + break; + + } + } + else + { + // + // CREATE_CHILD_SA request message received + // + if ( MsgId != iHdr.ExpectedRequestId() ) { + if ( iHdr.iLastResponse != NULL && + MsgId == iHdr.iLastResponse->MessageId() ) + { + // + // Retransmission of an earlier request. + // Retransmit current response + // + iState = KStateIkeChildSAResponse; + DoRetransmitL(ETrue); + return ETrue; + } + else { + DEBUG_LOG1(_L("Wrong message id in request, state: %d"), iState); + SetNotifyCode(INVALID_MESSAGE_ID); + StoreNotifyData32(MsgId); + return EFalse; + } + } + + if ( iState >= KStateIkeSaCompleted ) + { + // + // Received CREATE_CHILD_SA message can be one of the + // following: + // -- Create new Ipsec SA request: + // HDR(A,B), SK { SA, Nr, [KEi], [TSi, TSr]} + // -- Rekey Ipsec SA request: + // HDR(A,B), SK { N, SA, Ni, [KEi], [TSi, TSr]} + // -- Rekey IKE SA request: + // HDR(A,B), SK { SA, Ni, KEi} + // + if ( !CheckPayloadsOrder(aIkeMsg, CREATE_CHILD_SA, EFalse) ) + { + DEBUG_LOG1(_L("Erroneous CREATE_CHILD_SA request: %d"), iState); + SetNotifyCode(INVALID_SYNTAX); + return EFalse; + } + // + // Check is the current request an IKE SA rekey by checking + // Proposal payload protocol value + // + if ( Ikev2Proposal::IkeSaRekey(aIkeMsg) ) + { + TBool Status; + if ( iState == KStateIkeSARekeyRequest ) + { + DEBUG_LOG1(_L("IKE SA Rekey collision for SAID: %d"), iHdr.SaId()); + SetNotifyCode(NO_ADDITIONAL_SAS); + Status = EFalse; + } + else + { + DEBUG_LOG1(_L("IKE SA Rekey started by peer for SAID: %d"), iHdr.SaId()); + iState = KStateIkeSARekeyResponse; + Status = ProcessIkeSARekeyL(aIkeMsg); + iIkeV2PlugInSession.UpdateIkev2SAL(&iHdr, NULL); + } + return Status; + } + if ( CIkev2Acquire::Responding(GetAcquireQue()) ) + { + DEBUG_LOG1(_L("CREATE_CHILD_SA IKE SA request already pending: %d"), iState); + SetNotifyCode(NO_ADDITIONAL_SAS); + return EFalse; + } + + // + // Get acceptable Ipsec policy for peer defined traffic + // selectors (and peer address) + // + CIkev2Acquire* Acquire = IpsecSelectors::GetIpsecPolicyL(iIkeV2PlugInSession, aIkeMsg, + iHdr.iIkeData->iGroupDesc_II); + if ( !Acquire ) + { + DEBUG_LOG1(_L("Unaccepted Traffic Selectors in CREATE_CHILD_SA request: %d"),iState); + SetNotifyCode(TS_UNACCEPTABLE); + return EFalse; + } + CleanupStack::PushL(Acquire); + HBufC8* proposedSaBuffer = NULL; + if (!Ikev2Proposal::VerifySaRequestAndGetProposedSaBufferL(iHdr, iChild, *Acquire->SA(), + *aIkeMsg, proposedSaBuffer)) + { + CleanupStack::PopAndDestroy(Acquire); + DEBUG_LOG1(_L("Unaccepted SA content in CREATE_CHILD_SA request: %d"),iState); + SetNotifyCode(NO_PROPOSAL_CHOSEN); + return EFalse; + } + this->SetProposedSa(proposedSaBuffer); + proposedSaBuffer = NULL; + delete iNonce_I; + iNonce_I = NULL; + iNonce_I = HBufC8::NewL(aIkeMsg->iNonce->PlDataLen()); + iNonce_I->Des().Copy(aIkeMsg->iNonce->PayloadData(), aIkeMsg->iNonce->PlDataLen()); + if ( aIkeMsg->iKe ) + { + PfsDHGroup = Acquire->DHGroup(); + if ( PfsDHGroup == 0 ) + { + PfsDHGroup = Ikev2Proposal::GetDHGroup(iHdr.iIkeData->iGroupDesc_II); + Acquire->DHGroup(PfsDHGroup); + } + if ( !ProcessKeyExchangeL((TKEPayloadIkev2*)aIkeMsg->iKe, PfsDHGroup) ) + { + CleanupStack::PopAndDestroy(Acquire); + return EFalse; + } + } + CleanupStack::Pop(Acquire); + Acquire->SetSPI_Out(iChild.iSPI_Out); + Acquire->SetResponse(); + if ( iChild.iTransport ) + Acquire->SetTransport(); + CIkev2Acquire::Link(Acquire, GetAcquireQue()); + // + // Get SPI for new inbound SA + // + GetIpsecSPI(Acquire); + } + else + { + // + // Ignore received message silently + // + DEBUG_LOG1(_L("CREATE_CHILD_SA request received in state %d"), iState); + } + } + + return ETrue; +} + +TBool CIkev2Negotiation::ProcessIkeSARekeyL(CIkev2Payloads* aIkeMsg) +{ + ASSERT(aIkeMsg); + // + // Process IKE SA rekey message (as IKE_CHILD_SA exchange) + // HDR(A,B), SK { SA, Nonce, KE} + // + + + if ( (iState == KStateIkeSARekeyRequest) || (iState == KStateIkeSARekeyResponse) ) + { + // + // Received CREATE_CHILD_SA message for IKE SA rekey must + // look like the following: HDR(A,B), SK { SA, Ni, [KEi]} + // Allocate a new CIkev2Negotiation object for new IKE SA + // + // + CIkev2Negotiation* NewSA = new (ELeave) CIkev2Negotiation(iIkeV2PlugInSession, iPfKeySocketIf, + iEventLogger, iMessageSendQue, iDebug, 0); + CleanupStack::PushL(NewSA); + + //Do not copy the previous sent request and response: + CIkeV2Message* lastResponse = iHdr.iLastResponse; + iHdr.iLastResponse = NULL; + CIkeV2Message* lastRequest = iHdr.iLastRequest; + iHdr.iLastRequest = NULL; + NewSA->iHdr.Copy(iHdr); + iHdr.iLastResponse = lastResponse; + iHdr.iLastRequest = lastRequest; + + + NewSA->iHdr.iWindowSize = 1; + NewSA->iHdr.iEncrAlg = 0; + NewSA->iHdr.iPRFAlg = 0; + NewSA->iHdr.iIntegAlg = 0; + NewSA->iHdr.iDHGroup = 0; + NewSA->iHdr.iAuthMethod = 0; + NewSA->iHdr.iCipherKeyLth = 0; + NewSA->iHdr.iCipherBlkLth = 0; + NewSA->iHdr.iIntChkSumLth = 0; + + if ( iState == KStateIkeSARekeyRequest ) + { + NewSA->iHdr.iInitiator = ETrue; + NewSA->iHdr.SetSaId(iSAid_Rekey); + NewSA->iHdr.SetSpiI(iSPI_Rekey); + NewSA->iNonce_I = iNonce_I; // Nonce was created in BuildIkeSaRekeyMsgL() earlier + NewSA->iDHKeys = iDHKeys; // DH keys object was created in BuildIkeSaRekeyMsgL() earlier + iNonce_I = NULL; + iDHKeys = NULL; + } + else + { + NewSA->iHdr.iInitiator = EFalse; + NewSA->iHdr.SetSaId(iIkeV2PlugInSession.GetSAId()); // Get a new SA Id + NewSA->CreateIkeSPI(NewSA->iHdr.SpiR()); + } + // + // Build a SA payload from current IKE policy and + // verify received IKE SA request with it + // + HBufC8* SaBfr = Ikev2Proposal::FromPolicyToProposaL(NewSA->iHdr, NewSA->iSPI_Rekey, NewSA->iDHGroupGuess, ETrue); + CleanupStack::PushL(SaBfr); + HBufC8* proposedSaBuffer = NULL; + TBool SaOk = Ikev2Proposal::VerifySaRequestAndGetProposedSaBufferL(NewSA->iHdr, NewSA->iChild, + *SaBfr, *aIkeMsg, proposedSaBuffer); + CleanupStack::PopAndDestroy(); + if ( iState == KStateIkeSARekeyRequest ) + SaOk &= Ikev2Proposal::GetRekeySpi(aIkeMsg, NewSA->iHdr.SpiR()); + else SaOk &= Ikev2Proposal::GetRekeySpi(aIkeMsg, NewSA->iHdr.SpiI()); + if ( !SaOk ) + { + DEBUG_LOG1(_L("Unaccepted SA content in IKE_SA Rekey request: %d"), iState); + SetNotifyCode(NO_PROPOSAL_CHOSEN); + CleanupStack::PopAndDestroy(NewSA); + return EFalse; + } + NewSA->SetProposedSa(proposedSaBuffer); + proposedSaBuffer = NULL; + if ( aIkeMsg->iNonce->PlDataLen() < IKEV2_MIN_NONCE_SIZE ) + { + DEBUG_LOG1(_L("Nonce data too short in IKE_SA Rekey request %d"), iState); + SetNotifyCode(INVALID_SYNTAX); + CleanupStack::PopAndDestroy(NewSA); + return EFalse; + } + if ( iState == KStateIkeSARekeyRequest ) + { + NewSA->iNonce_R = HBufC8::NewL(aIkeMsg->iNonce->PlDataLen()); + NewSA->iNonce_R->Des().Copy(aIkeMsg->iNonce->PayloadData(), aIkeMsg->iNonce->PlDataLen()); + } + else + { + NewSA->iNonce_I = HBufC8::NewL(aIkeMsg->iNonce->PlDataLen()); + NewSA->iNonce_I->Des().Copy(aIkeMsg->iNonce->PayloadData(), aIkeMsg->iNonce->PlDataLen()); + } + + if ( !NewSA->ProcessKeyExchangeL((TKEPayloadIkev2*)aIkeMsg->iKe, NewSA->iHdr.iDHGroup) ) + { + //If there was notify code set, copy it to current negotiation before destroying NewSa + if(NewSA->GetNotifyCode()) + { + SetNotifyCode(NewSA->GetNotifyCode()); + } + TInt dataLth(0); + TUint8* notifyData = NewSA->NotifyData(dataLth); + if(dataLth == 2) + { + StoreNotifyData16(GET16(notifyData)); + } + else if(dataLth == 4) + { + StoreNotifyData32(GET32(notifyData)); + } + CleanupStack::PopAndDestroy(NewSA); + return EFalse; + } + + if ( iState == KStateIkeSARekeyResponse ) + { + // + // Build IKE SA rekey response (CHILD_SA response): + // HDR, SAr, Nr, KEr + // + iDHKeys = NewSA->iDHKeys; // To calculate own DH value + iSPI_Rekey = NewSA->iHdr.SpiR(); + SetProposedSa(NewSA->GetProposedSa()); + BuildIkeSaRekeyMsgL(EFalse); + NewSA->iNonce_R = iNonce_R; // Nonce is created in BuildIkeSaRekeyMsgL() + iNonce_R = NULL; + iDHKeys = NULL; + } + // + // Generate key material for new IKE SA + // + NewSA->GenerateIkeKeysL(&iHdr); + + // + // Create a new IKE SA and swap IPSec SA from rekeyed IKE SA + // to the new just created SA + // + iIkeV2PlugInSession.CreateIkev2SAL(NewSA->iHdr); + iIkeV2PlugInSession.InheritIpsecSas(NewSA->iHdr.SaId(), iHdr.SaId()); + + CleanupStack::PopAndDestroy(NewSA); + } + + return ETrue; +} + +TBool CIkev2Negotiation::ProcessInfoMsgL(CIkev2Payloads* aIkeMsg) +{ + ASSERT(aIkeMsg); + // + // Process IKE message of exchange type INFORMATIONAL + // HDR, SK {[N,] [D,] [CP,] ...} + // Only encyrpted and authenitcated are processed. + // + if ( !aIkeMsg->Encrypted() ) + { + if ( iState == KStateIdle) + iStopped = ETrue; + return EFalse; + } + ThdrISAKMP* IkeHdr = aIkeMsg->GetIkeMsg(); // IKE Message fixed header + TBool Response = IkeHdr->GetFlags() & IKEV2_RESPONSE_MSG; + TUint32 MsgId = IkeHdr->GetMessageId(); + + if ( Response ) + { + if ( (iState == KStateIkeInfoRequest) || (iState == KStateIkeDeleteRequest) ) + { + // + // A response received to a transmitted Informational request + // + DEBUG_LOG(_L("Response received to a transmitted Informational request")); + + if ( MsgId == iHdr.ExpectedResponseId() ) + { + iIkeV2PlugInSession.UpdateIkev2SAL(&iHdr, NULL); + if ( iState == KStateIkeDeleteRequest ) + { + iIkeV2PlugInSession.IkeSaDeleted(KErrNone); //IKE SA deletion going + } + else + { + if ( aIkeMsg->iNotifs->Count() ) + { + ProcessNotifyPayloadsL(*aIkeMsg->iNotifs, EFalse, INFORMATIONAL); + } + } + iStopped = ETrue; + return EFalse; + } + } + else if ( iState == KStateChildDeleteRequest ) + { + // + // A response received to a transmitted Child SA delete request + // + if ( aIkeMsg->iDeletes->Count() ) + { + ProcessDeletePayloadsL(*aIkeMsg->iDeletes, EFalse); + } + + // + // Update sequence numbers and IKE SA data + // + iIkeV2PlugInSession.UpdateIkev2SAL(&iHdr, NULL); + iStopped = ETrue; + return EFalse; + } + } + else + { + // + // A Informational request received. Process request according + // to payload content and send informational response. + // + DEBUG_LOG1(_L("INFORMATIONAL request received in state %d"), iState); + if ( MsgId == iHdr.ExpectedRequestId() ) + { + TBool BuildResponse = ETrue; + if ( aIkeMsg->iDeletes->Count() ) + { + BuildResponse = ProcessDeletePayloadsL(*aIkeMsg->iDeletes, ETrue); + } + if ( aIkeMsg->iNotifs->Count() ) + { + BuildResponse = ProcessNotifyPayloadsL(*aIkeMsg->iNotifs, ETrue, INFORMATIONAL); + } + if ( BuildResponse ) + { + CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), + iHdr.SpiR(), + INFORMATIONAL, + iHdr.iInitiator, + ETrue, + iHdr.ExpectedRequestId(), + iDebug); + CleanupStack::PushL(ikeMsg); + ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth); + CleanupStack::Pop(ikeMsg); + SendIkeMsgL(ikeMsg); + if ( (iState != KStateIkeInfoRequest) && (iState != KStateIkeDeleteRequest) && (iState != KStateIkeDeleteResponse) ) + { + iState = KStateIkeInfoResponse; + iIkeV2PlugInSession.UpdateIkev2SAL(&iHdr, NULL); + } + } + } + } + + return ETrue; +} + +TBool CIkev2Negotiation::ProcessNotifyPayloadsL(const CArrayFixFlat& aNotifys, + TBool aRequest, TInt aExchange) +{ + if ( Ikev2MobIke::ProcessNotifysL(this, aNotifys, aRequest, aExchange) ) + { + return EFalse; // Notify payload(s) was processed by MOBIKE protocol + } + + TInt MsgType; + TNotifPayloadIkev2* Payload; + TInt Count = aNotifys.Count(); + TInt i = 0; + + while ( i < Count ) + { + Payload = aNotifys.At(i); + MsgType = (TInt)Payload->GetMsgType(); + DEBUG_LOG1(_L("Received Notify payload message type %d"), MsgType); + // + // Process possible error type Notify messages + // + if (aExchange == IKE_SA_INIT) + { + switch ( MsgType ) + { + case INVALID_SYNTAX: + //Fall through + case NO_PROPOSAL_CHOSEN: + return EFalse; + case INVALID_KE_PAYLOAD: + ProcessInvalidKePayloadNotifyL(); + return ETrue; + case COOKIE: + return ProcessCookieL(aNotifys, aRequest); + default: + break; + } + } + else + { + switch ( MsgType ) + { + case UNSUPPORTED_CRITICAL_PAYLOAD: + case INVALID_SYNTAX: + case INVALID_MESSAGE_ID: + case AUTHENTICATION_FAILED: + case INTERNAL_ADDRESS_FAILURE: + case FAILED_CP_REQUIRED: + // + // When some of these error types received IKE SA shall + // corresponding IKE SA shall be deleted + // + iDeleteIkeSA = ETrue; + break; + + case NO_PROPOSAL_CHOSEN: + case SINGLE_PAIR_REQUIRED: + case NO_ADDITIONAL_SAS: + case TS_UNACCEPTABLE: + case INVALID_SELECTORS: + // + // When some of these error types received within + // IKE_AUTH or CREATE_CHILD_SA exchange (in response) + // Child SA request is interpreted to be failed + // + if ( ((aExchange == IKE_AUTH) || (aExchange == CREATE_CHILD_SA) ) && !aRequest ) + iChildSARejected = ETrue; + break; + + default: + break; + } + } + + i++; + } + + return ETrue; +} + +TBool CIkev2Negotiation::ProcessCookieL(const CArrayFixFlat& aNotifys, TBool aRequest) +{ + + // + // Special handling for COOKIE Notify payload. + // The following actions are taken: + // - Assure that the first Notify payload in array is cookie + // - When the COOKIE is received in response (aRequest = EFalse) + // - Retransmit IKE_SA_INIT request again in format: + // HDR(A,0), N(COOKIE), SAi1, KEi, Ni, [Nat Notifies] + // - When the COOKIE is received in request (aRequest = ETrue) + // - Assure that COOKIE returned by the initiator is the we + // have earlier transmitted. + // + if ( aNotifys.Count() ) + { + const TNotifPayloadIkev2* NotifyPayload = aNotifys.At(0); + if ( NotifyPayload->GetMsgType() == COOKIE && !aRequest) + { + // + // Local end COOKIE usage has not been implemented yet + // + + // + // Init a new IKE message buffer and copy received COOKIE + // Notify to the first payload. Concatenate then all + // payloads from original IKE_SA_INIT request to this new + // IKE message (and set next payload field in Notify) + // + DEBUG_LOG1(_L("Cookie received, IKE_SA_INIT repeated: %d"), iState); + if ( iCookieReturned ) + { + // + // One cookie already returned. Avoid cookie-loop + // by stopping ongoing IKE_SA_INIT exchange + // + DEBUG_LOG(_L("Cookie already returned once, IKE_SA_INIT exchange stopped")); + return EFalse; + } + CIkeV2Message* originalIkeSaInitRequest = iHdr.iLastRequest; + const TPtrC8 cookieData(NotifyPayload->NotifData(), NotifyPayload->NotifDataLength()); + originalIkeSaInitRequest->PrependCookieNotifyPayloadL(cookieData); + iHdr.iLastRequest = NULL; //claims the ownership of the message + + SendIkeMsgL(originalIkeSaInitRequest); + iTimer->Cancel(); // Reset transmit retry timer + iTimer->IssueRequest(iSendAttempt); // Start retry timer + iCookieReturned = ETrue; + return ETrue; + } + } + DEBUG_LOG1(_L("Cookie required, NO COOKIE Notify found: %d"), iState); + + return EFalse; +} + + + +TBool CIkev2Negotiation::ProcessDeletePayloadsL(const CArrayFixFlat& aDeletes, + TBool aRequest) +{ + // + // Process delete payloads received. + // + CDesC8ArrayFlat* SpiList = NULL; + TUint8 Protocol = IKEV2_PROT_NONE; + + for (TInt i = 0; i < aDeletes.Count(); ++i) + { + const TDeletePlIkev2* Payload = aDeletes.At(i); + Protocol = Payload->GetProtocolId(); + switch ( Protocol ) + { + case IKEV2_PROTOCOL: + // + // Deletion of current existing IKE SA. All IPSEC SA:s + // negotiated within IKE SA are deleted implicitly + // + iIkeV2PlugInSession.DeleteIkev2SA(iHdr.SaId()); + delete SpiList; + SpiList = NULL; + i = aDeletes.Count(); // Stop outer while loop + iState = KStateIkeDeleteResponse; // Set next state here + break; + + case IKEV2_IPSEC_AH: + case IKEV2_IPSEC_ESP: + if ( Payload->GetSPISize() == 4 ) + { + // + // Delete Ipsec SPI:s from IKE SA (and IPSEC SADB) + // If Delete payload received within Info request + // build inbound SPI list of corresponding inbound + // SA:s + // + TUint SpiCount = (TInt)Payload->GetNbrOfSpis(); + if ( TPayloadIkev2::Cast(Payload)->GetLength() == + ( TDeletePlIkev2::Size() + 4*SpiCount) ) + { + const TUint8* Spis = Payload->SPIs(); + if ( aRequest && !SpiList ) + { + SpiList = new (ELeave) CDesC8ArrayFlat(2); + CleanupStack::PushL(SpiList); + } + while ( SpiCount ) + { + TPtrC8 Spi(Spis, 4); + if ( SpiList ) + { + const TIkeV2IpsecSAData* IpsecSa = + iIkeV2PlugInSession.FindIpsecSAData(iHdr.SaId(), Spi, EFalse); + if ( IpsecSa && IpsecSa->iSPI_In.Length() > 0 ) + { + SpiList->AppendL(IpsecSa->iSPI_In); + } + } + iIkeV2PlugInSession.DeleteIpsecSAData(iHdr.SaId(), Spi, EFalse); + Spis += 4; + SpiCount--; + } + } + } + break; + default: + break; + } + } + + if ( SpiList ) + { + // + // Build Informational exchange response with a + // Delete payload containing SPI:s of corresponding + // inbound SA:s. + // + CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), + iHdr.SpiR(), + INFORMATIONAL, + iHdr.iInitiator, + ETrue, + iHdr.ExpectedRequestId(), iDebug); + CleanupStack::PushL(ikeMsg); + ikeMsg->AppendEncryptedPayloadL(iHdr.iCipherBlkLth); + ikeMsg->AppendDeletePayloadL(Protocol, *SpiList); + CleanupStack::Pop(ikeMsg); + SendIkeMsgL(ikeMsg); + CleanupStack::PopAndDestroy(SpiList); + iState = KStateIkeInfoResponse; + iIkeV2PlugInSession.UpdateIkev2SAL(&iHdr, NULL); + aRequest = EFalse; + } + + return aRequest; +} + +void CIkev2Negotiation::ProcessInvalidKePayloadNotifyL() +{ + // Build and send new IKE_SA_INIT message (request) with another DH group # + // HDR, SAi1, KEi, Ni, N[NAT_SRC], N[NAT_DST] + // + iDHGroupGuess++; + delete iDHKeys; // Delete old DH object + iDHKeys = NULL; + iHdr.iDHGroup = 0; + + TUint32 lastRequestMsgId = 0; + if(iHdr.iLastRequest != NULL) + { + lastRequestMsgId = iHdr.iLastRequest->MessageId(); + } + + CIkeV2Message* ikeMsg = CIkeV2Message::NewL(iHdr.SpiI(), + iHdr.SpiR(), + IKE_SA_INIT, + iHdr.iInitiator, + EFalse, + lastRequestMsgId, + iDebug); + CleanupStack::PushL(ikeMsg); + + HBufC8* saBfr = Ikev2Proposal::FromPolicyToProposaL(iHdr, iSPI_Rekey, iDHGroupGuess); + CleanupStack::PushL(saBfr); + ikeMsg->AppendSaPayloadL(*saBfr); + CleanupStack::Pop(saBfr); + SetProposedSa(saBfr); + + AppendKEPayloadL(*ikeMsg, iHdr.iDHGroup); + ikeMsg->AppendNoncePayloadL(*iNonce_I); + if ( !iHdr.iIkeData->iUseNatProbing ) + { + delete iNatNotify; + iNatNotify = NULL; + + TInetAddr LocalIp; + if ( iHdr.iIkeData->iUseMobIke ) + LocalIp.SetAddress(KInetAddrNone); + else LocalIp = iHdr.iLocalAddr; + iNatNotify = CIkev2NatT::NewL( + LocalIp, iHdr.iRemoteAddr, IKE_PORT, ikeMsg->InitiatorSpi(), ikeMsg->ResponderSpi()); + + ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, NAT_DETECTION_SOURCE_IP, + iNatNotify->SourceNofify()); + ikeMsg->AppendNotifyPayloadL(IKEV2_PROTOCOL, KZeroDesc, NAT_DETECTION_DESTINATION_IP, + iNatNotify->DestinNofify()); + } + + CleanupStack::Pop(ikeMsg); + SendIkeMsgL(ikeMsg); + + iState = KStateIkeSaInitRequest; +} + + + +void CIkev2Negotiation::GetNonceDataL(TBool aInitiator) +{ + // + // Get random data for local nonce + // + HBufC8* Nonce; + if ( aInitiator ) + { + Nonce = HBufC8::NewL(IKEV2_DEF_NONCE_SIZE); + delete iNonce_I; + iNonce_I = Nonce; + } + else + { + Nonce = HBufC8::NewL(IKEV2_DEF_NONCE_SIZE); + delete iNonce_R; + iNonce_R = Nonce; + } + TPtr8 RandOctet(Nonce->Des()); + RandOctet.SetLength(IKEV2_DEF_NONCE_SIZE); + TRandom::RandomL(RandOctet); +} + +void CIkev2Negotiation::GetOwnIdentityL(TBool aEapIdResponse) +{ + if ( iLocalIdentity ) + { + return; // We already have own identity data + } + + // + // The own IKE identity data is built with the following system: + // -- If Own Certificate exist take try to get identity data from it + // If no Certificate or identity cannot be get from certificate + // -- If EAP used use identity speficied by the EAP plugin + // -- If EAP not used, get own identity data information from current IKE policy + // If no identity information found use local IP address as + // identity. Own IKE Identity information is stored in iLocalIdentity + // buffer (linked into negotiation object) in format of Identity + // payload (TIDPayloadIkev2) + // + + + HBufC8* IdBfr = NULL; + TUint8 IdType = ID_NOT_DEFINED; + + + //Try to get the identity from the user certificate + if ( iPkiService && iPkiService->UserCertificateData().Length() > 0 ) + { + IdType = iHdr.iIkeData->iIdType; + IdBfr = IkePkiUtils::GetIdentityFromCertL(IdType, iPkiService->UserCertificateData()); + if ( IdBfr != NULL) + { + if (IdType == ID_NOT_DEFINED) + { + IdType = ID_DER_ASN1_DN; + } + } + else + { + //We didn't get the ID data from the user certificate. + //Make sure that the type is set to not defined. + IdType = ID_NOT_DEFINED; + } + } + + //If we didn't get the identity from the user certificate, + //try to get it from the EAP plugin. + if ( IdType == ID_NOT_DEFINED && iEapPlugin ) + { + __ASSERT_DEBUG(IdBfr == NULL, User::Invariant()); + // + // Try to get Own identity data from EAP Plug-in + // + IdBfr = iEapPlugin->Identity(); + if ( IdBfr != NULL && IdBfr->Length() ) + { + // + // Identity data provided by EAP plug-in. Define IKE Id type + // value according to Identity data content. If Id data + // contains realm (format username@realm) Id type + // ID_RFC822_ADDR is used. If no realm in ID use type ID_KEY_ID + // + TInt offset = IdBfr->Find(_L8("@")); + IdType = ( offset == KErrNotFound ) ? ID_KEY_ID : ID_RFC822_ADDR; + } + else + { + delete IdBfr; + IdBfr = NULL; + if ( !aEapIdResponse ) + return; // Identity not yet available continue waiting + } + } + + //If we don't have identity so far, try to get it from the + //policy: + if ( IdType == ID_NOT_DEFINED && + iHdr.iIkeData->iIdType != ID_NOT_DEFINED && + iHdr.iIkeData->iFQDN.Length() > 0) + { + __ASSERT_DEBUG(IdBfr == NULL, User::Invariant()); + IdBfr = HBufC8::NewL(iHdr.iIkeData->iFQDN.Length()); + IdBfr->Des().Copy(iHdr.iIkeData->iFQDN); + IdType = iHdr.iIkeData->iIdType; + } + + + //If we have not been able to get the identity so far, we are using the default + //identity, which is our own IP address. + if ( IdType == ID_NOT_DEFINED) + { + __ASSERT_DEBUG(IdBfr == NULL, User::Invariant()); + if ( (iHdr.iLocalAddr.Family()== KAfInet) || iHdr.iLocalAddr.IsV4Mapped() ) + { + TUint32 num = ByteOrder::Swap32(iHdr.iLocalAddr.Address());//Put in network order + IdBfr = HBufC8::NewL(sizeof(num)); + IdBfr->Des().Append(reinterpret_cast(&num), sizeof(num)); + IdType = ID_IPV4_ADDR; + } + else + { + IdBfr = HBufC8::NewL(16); + const TUint8* pnum = &iHdr.iLocalAddr.Ip6Address().u.iAddr8[0]; //Address in a bytestream + IdBfr->Des().Append(pnum, 16); + IdType = ID_IPV6_ADDR; + } + } + + __ASSERT_DEBUG((IdType != ID_NOT_DEFINED && IdBfr != NULL), User::Invariant()); + CleanupStack::PushL(IdBfr); + iLocalIdentity = CIkeV2Identity::NewL(IdType, *IdBfr); + CleanupStack::PopAndDestroy(IdBfr); +} + + +void CIkev2Negotiation::GenerateIkeKeysL(TIkev2SAData* aRekeydSaData) +{ + // + // Generate IKE keying material. Start by calculating + // Diffie-Hellman secret. + // + User::LeaveIfNull(iDHPublicPeer); + if ( !iDHKeys ) + { + iDHKeys = CDHKeys::CreateDHKeyL(iHdr.iDHGroup); + iDHKeys->XValueL(); // Calculate own DH public value + } + HBufC8* g_ir = iDHKeys->ComputeAgreedKeyL(iDHPublicPeer->Des()); + CleanupStack::PushL(g_ir); + delete iDHKeys; + iDHKeys = NULL; + + HBufC8* Ni_Nr; + HBufC8* SKEYSEED; + TUint16 prfAlg(0); + + if ( aRekeydSaData ) + { + // + // Calculate IKE keying material seed SKEYDSEED = prf(SK_d(old), [g^ir (new)] | Ni | Nr) + // + Ni_Nr = HBufC8::NewL(g_ir->Length() + iNonce_I->Length() + iNonce_R->Length()); + CleanupStack::PushL(Ni_Nr); + Ni_Nr->Des().Copy(g_ir->Des()); + Ni_Nr->Des().Append(iNonce_I->Des()); + Ni_Nr->Des().Append(iNonce_R->Des()); + + prfAlg = aRekeydSaData->iPRFAlg; + SKEYSEED = IkeCrypto::PrfhmacL(*Ni_Nr, aRekeydSaData->iSK_d, prfAlg); + CleanupStack::PushL(SKEYSEED); + } + else + { + // + // Calculate IKE keying material seed SKEYDSEED = prf(Ni | Nr, g^ir) + // + Ni_Nr = HBufC8::NewL(iNonce_I->Length() + iNonce_R->Length()); + CleanupStack::PushL(Ni_Nr); + Ni_Nr->Des().Copy(iNonce_I->Des()); + Ni_Nr->Des().Append(iNonce_R->Des()); + + prfAlg = iHdr.iPRFAlg; + SKEYSEED = IkeCrypto::PrfhmacL(*g_ir, *Ni_Nr, prfAlg); + CleanupStack::PushL(SKEYSEED); + } + + g_ir->Des().FillZ(); // Wipe out shared secret value from buffer + + iHdr.GenerateIkeKeyDerivatesL(SKEYSEED->Des(),prfAlg, *iNonce_I, *iNonce_R); + SKEYSEED->Des().FillZ(); // Wipe out SKEYSEED value from buffer + + CleanupStack::PopAndDestroy(3); //g_ir , Ni_Nr and SKEYSEED +} + + +void CIkev2Negotiation::SaveSignedDataL(TBool aLocal, const TDesC8& aIkeMsg) +{ + // + // Allocate buffer for signed octets needed for IKE SA + // authentication with AUTH payload. + // The signed octet contains the following data: + // Initiator: + // - IKE_SA_INIT message content (message number 1) + // concatenated with responder nonce data and value + // prf(SK_pi,IDi") where IDi" is initiator ID data without fixed + // payload header + // + // Responder: + // - IKE_SA_INIT message content (message number 2) + // concatenated with initiator nonce data and value + // prf(SK_pr,IDr") where IDr" is responder ID data without fixed + // payload header + // + TInt SignedLth = aIkeMsg.Length(); // Initial value + HBufC8* Nonce; + HBufC8** SignedBfrPtr; + if ( aLocal ) + { + if ( iHdr.iInitiator ) + { + SignedBfrPtr = &iAuthMsgInit; + Nonce = iNonce_R; + } + else { + SignedBfrPtr = &iAuthMsgResp; + Nonce = iNonce_I; + } + } + else + { + if ( iHdr.iInitiator ) + { + SignedBfrPtr = &iAuthMsgResp; + Nonce = iNonce_I; + } + else + { + SignedBfrPtr = &iAuthMsgInit; + Nonce = iNonce_R; + } + } + + SignedLth += Nonce->Length() + IkeCrypto::AlgorithmInfo(IKEV2_PRF, iHdr.iPRFAlg); + HBufC8* Signed = HBufC8::NewL(SignedLth); + Signed->Des().Copy(aIkeMsg); + Signed->Des().Append(Nonce->Des()); + + if ( aLocal && iLocalIdentity ) + { + // + // Add value prf(SK_px,IDx") into local signed data buffer end + // + AddIdToSignedDataL(ETrue, Signed, iLocalIdentity->PayloadData()); + } + + delete *SignedBfrPtr; + *SignedBfrPtr = Signed; +} + + +void CIkev2Negotiation::AddIdToSignedDataL(TBool aLocal, HBufC8* aSigned, const TDesC8& aIdData) +{ + ASSERT(aSigned); + // + // Add value prf(SK_px,IDx") into signed data buffer end + // + + HBufC8* signedIdData = NULL;; + if ( iHdr.iInitiator ) + { + if ( aLocal ) + { + signedIdData = IkeCrypto::PrfhmacL(aIdData, iHdr.iSK_pi, iHdr.iPRFAlg); + } + else + { + signedIdData = IkeCrypto::PrfhmacL(aIdData, iHdr.iSK_pr, iHdr.iPRFAlg); + } + } + else + { + if ( aLocal ) + { + signedIdData = IkeCrypto::PrfhmacL(aIdData, iHdr.iSK_pr, iHdr.iPRFAlg); + } + else + { + signedIdData = IkeCrypto::PrfhmacL(aIdData, iHdr.iSK_pi, iHdr.iPRFAlg); + } + } + aSigned->Des().Append(*signedIdData); + delete signedIdData; +} + +HBufC8* CIkev2Negotiation::SignAuthDataL(const TDesC8& aAuthData, TUint8 aAuthMethod) +{ + // + // Sign aMsgData according to authentication method parameter + // + HBufC8* signedAuthData = NULL; + + if ( iPkiService && + iPkiService->TrustedCaName().Length() > 0 && + iPkiService->UserCertificateData().Length() > 0 ) + { + // + // Message data is signed using private key + // + TPtrC8 TrustedCa(iPkiService->TrustedCaName()); + signedAuthData = HBufC8::NewLC(320); // reserved for sign (aware for 2048 bits signatures) + TPtr8 signedAuthDataPtr(signedAuthData->Des()); + + iPkiService->Ikev2SignatureL(TrustedCa, iHdr.iIkeData->iOwnCert, aAuthData, signedAuthDataPtr, aAuthMethod); + CleanupStack::Pop(signedAuthData); + } + else + { + // + // Message data is signed using negotiated PRF function as + // follows: + // AUTH = + // prf(prf(Shared Secret,"Key Pad for IKEv2"), ) + // If EAP method that creates a shared key as a side effect of + // authentication used, this shared key is used as Shared Secret + // Otherwise preshared key configured into policy is used as + // Shared secret. + // + if ( !iPresharedKey ) + iPresharedKey = Ikev2Proposal::GetPSKFromPolicyL(iHdr.iIkeData); + // + // Calculate KEY = prf(Shared Secret,"Key Pad for IKEv2") + // + HBufC8* PskKey = IkeCrypto::PrfhmacL(KIkev2PSKData, *iPresharedKey, iHdr.iPRFAlg); + CleanupStack::PushL(PskKey); + // + // Calculate prf(KEY, ) + // + signedAuthData = IkeCrypto::PrfhmacL(aAuthData, *PskKey, iHdr.iPRFAlg); + CleanupStack::PopAndDestroy(PskKey); + } + return signedAuthData; +} + +TBool CIkev2Negotiation::AddIdAndAuthenticatePeerL(CIkev2Payloads* aIkeMsg) +{ + ASSERT(aIkeMsg); + // + // Verify that authentication payload of peer is correct + // To do this the signed data octets of peer must be filled with + // value: prf(SK_px,IDx") + // So the peer ID payload must be verified first. + // + HBufC8* Signed; + TIDPayloadIkev2* Id; + if ( iHdr.iInitiator ) + { + Signed = iAuthMsgResp; + Id = (TIDPayloadIkev2*)aIkeMsg->iIdR; + } + else + { + Signed = iAuthMsgInit; + Id = (TIDPayloadIkev2*)aIkeMsg->iIdI; + } + if ( !Signed || !Id ) + return EFalse; + + if ( !iPeerIdInSignedData ) + { + TUint16 IdLth = TPayloadIkev2::Cast(Id)->GetLength(); + if ( IdLth < TIDPayloadIkev2::Size() ) + { + DEBUG_LOG1(_L("Peer ID payload too short; Length %d"), IdLth); + return EFalse; + } + // + // Add value prf(SK_px,IDx") into peer signed data buffer end + // + TPayloadIkev2* idPayload = TPayloadIkev2::Cast(Id); + TPtrC8 idPtr(idPayload->PayloadData(), (idPayload->GetLength() - TPayloadIkev2::Size())); + AddIdToSignedDataL(EFalse, Signed, idPtr); + iPeerIdInSignedData = ETrue; + } + + return AuthenticatePeerL(aIkeMsg->iAuth); + +} + +TBool CIkev2Negotiation::AuthenticatePeerL(TAuthPayloadIkev2* aAuth) +{ + // + // Authenticate peer tication payload of peer is correct + // To do this the signed data octets of peer must be filled with + // value: prf(SK_px,IDx") + // So the peer ID payload must be verified first. + // + HBufC8* Signed; + if ( iHdr.iInitiator ) + Signed = iAuthMsgResp; + else Signed = iAuthMsgInit; + + if ( !Signed || !aAuth ) + return EFalse; + + TUint16 AuthLth = TPayloadIkev2::Cast(aAuth)->GetLength(); + if ( AuthLth < TAuthPayloadIkev2::Size() ) + { + DEBUG_LOG1(_L("Peer Auth payload too short; Length %d"), AuthLth); + return EFalse; + } + AuthLth = (TUint16)(AuthLth - TAuthPayloadIkev2::Size()); + TBool Status = EFalse; + + if ( aAuth->GetAuthMethod() == PRESHARED_KEY ) + { + DEBUG_LOG(_L("Authenticating SGW with PSK")); + // + // Pre shared key authentication is not accepted for peer if we + // have requested an certificate from peer (PKI authentication + // required) + // + if ( !iPkiAuthRequired ) + { + HBufC8* AuthRef = SignAuthDataL(*Signed, PRESHARED_KEY); + CleanupStack::PushL(AuthRef); + if ( AuthRef->Length() == AuthLth ) + { + Status = (Mem::Compare(AuthRef->Ptr(), AuthRef->Length(), aAuth->AuthData(), AuthLth ) == 0); + } + CleanupStack::PopAndDestroy(); // AuthRef + } + } + else + { + // + // Authentication based on PKI (private key signature) + // + if ( iPkiService && iPeerCert ) + { + DEBUG_LOG(_L("Authenticating SGW with certs")); + + TPtrC8 AuthData(Signed->Des()); + TPtrC8 Signature(aAuth->AuthData(), AuthLth); + Status = IkePkiUtils::VerifyIkev2SignatureL(Signature, AuthData, *iPeerCert); + iPkiAuthRequired = EFalse; + } + } + if (Status) + { + DEBUG_LOG(_L("SGW authentication success")); + } + else + { + DEBUG_LOG(_L("SGW authentication failed")); + } + + return Status; +} + + +TBool CIkev2Negotiation::VerifyPeerCertificateL(CArrayFixFlat* aCerts, TIDPayloadIkev2* aId ) +{ + TBool Status = EFalse; + + const CIkeCaList& trustedCaList = iPkiService->CaList(); + CX509Certificate* PeerCert = IkePkiUtils::VerifyCertificateL(*aCerts, trustedCaList); + + if ( PeerCert && aId ) + { + CleanupStack::PushL(PeerCert); + TPtrC8 IdData(aId->IdData(), (TPayloadIkev2::Cast(aId)->GetLength() - TIDPayloadIkev2::Size())); + Status = IkePkiUtils::CertifyIdentityL(PeerCert, IdData, (TInt)aId->GetIdType()); + if ( Status ) + { + DEBUG_LOG(_L("IDr matches the SGW certificate")); + if (iRemoteIdentity && !iHdr.iIkeData->iSkipRemoteIdCheck ) //iRemoteIdentity if the REMOTE_IF from the policy + { + //TIDPayloadIkev2* peerIdentityPayload = TIDPayloadIkev2::Cast(iRemoteIdentity->Ptr()); + if (iRemoteIdentity->IdType() == aId->GetIdType()) + { + TPtrC8 idPtr(aId->IdData(), + TPayloadIkev2::Cast(aId)->GetLength() - TIDPayloadIkev2::Size()); + TPtrC8 peerIdentityPtr(iRemoteIdentity->Identity()); + + //Check if we accept partial remote id + if (iHdr.iIkeData->iAcceptPartialRemoteId && + iRemoteIdentity->IdType() == ID_FQDN && + peerIdentityPtr.Length() > idPtr.Length()) + { + DEBUG_LOG(_L("Using PARTIAL_REMOTE_ID_CHECK")); + peerIdentityPtr.Set(peerIdentityPtr.Right(idPtr.Length())); + } + if (idPtr.Compare(peerIdentityPtr) == 0) + { + DEBUG_LOG(_L("IDr matches the REMOTE_ID")); + Status = ETrue; + } + else + { + DEBUG_LOG(_L("IDr does not match the REMOTE_ID")); + Status = EFalse; + } + } + else + { + DEBUG_LOG(_L("IDr payload ID does not match REMOTE_ID_TYPE")); + Status = EFalse; + } + } + } + else + { + DEBUG_LOG(_L("IDr does not match the SGW certificate")); + } + + if ( Status ) + { + CleanupStack::Pop(PeerCert); + delete iPeerCert; + iPeerCert = PeerCert; + } + else CleanupStack::PopAndDestroy(PeerCert); + } + return Status; +} + + +TBool CIkev2Negotiation::ProcessKeyExchangeL(TKEPayloadIkev2* aKePayload, TUint16 aGroup) +{ + // + // Process key exchange payload received from peer + // + if ( !aKePayload ) + { + DEBUG_LOG1(_L("Key Exchange payload not present, required Group %d"), aGroup); + SetNotifyCode(INVALID_KE_PAYLOAD); + StoreNotifyData16(aGroup); + return EFalse; + } + TUint16 PlLth = TPayloadIkev2::Cast(aKePayload)->GetLength(); + if (( PlLth <= TKEPayloadIkev2::Size() ) || ( aKePayload->GetDHGroup() != aGroup )) + { + DEBUG_LOG1(_L("Peer Key Exchange DH group does not match, Group %d"), aKePayload->GetDHGroup()); + SetNotifyCode(INVALID_KE_PAYLOAD); + StoreNotifyData16(aGroup); + return EFalse; + } + if ( !iDHKeys ) + iDHKeys = CDHKeys::CreateDHKeyL(aGroup); + PlLth = (TUint16)(PlLth - TKEPayloadIkev2::Size()); + if ( PlLth != iDHKeys->ModulusLength() ) + { + DEBUG_LOG1(_L("Peer DH public value length does not match group, Length %d"), PlLth); + SetNotifyCode(INVALID_KE_PAYLOAD); + StoreNotifyData16(aGroup); + return EFalse; + } + delete iDHPublicPeer; + iDHPublicPeer = NULL; + iDHPublicPeer = HBufC8::NewL(PlLth); + iDHPublicPeer->Des().Copy(aKePayload->DHPublic(), PlLth); + + return ETrue; +} + +void CIkev2Negotiation::AppendKEPayloadL(CIkeV2Message& aIkeMsg, TUint16 aDHGroup) +{ + if ( !iDHKeys ) + iDHKeys = CDHKeys::CreateDHKeyL(aDHGroup); + + iDHKeys->XValueL(); // Calculate own DH public value + HBufC8* dHPublic = iDHKeys->GetPubKey(); //save the public key in a buffer to have easy access + User::LeaveIfNull(dHPublic); + CleanupStack::PushL(dHPublic); + + TInt modulusLength = iDHKeys->ModulusLength(); + HBufC8* kePayloadData = HBufC8::NewLC(modulusLength); + TPtr8 kePayloadDataPtr(kePayloadData->Des()); + + __ASSERT_DEBUG(modulusLength == dHPublic->Length(), User::Invariant()); + + kePayloadDataPtr.Append(*dHPublic); + kePayloadDataPtr.SetLength(modulusLength); //adds zero padding, if needed + + aIkeMsg.AppendKePayloadL(aDHGroup, *kePayloadData); + + CleanupStack::PopAndDestroy(kePayloadData); + CleanupStack::PopAndDestroy(dHPublic); +} + + + +TBool CIkev2Negotiation::CheckPayloadsOrder(CIkev2Payloads* aIkeMsg, TUint8 aExchange, TBool aResponse) + { + switch ( aExchange ) + { + case IKE_SA_INIT: + if(!aIkeMsg->iSa || !aIkeMsg->iKe || !aIkeMsg->iNonce) return EFalse; + if(aIkeMsg->iSa->GetNextPayload() != IKEV2_PAYLOAD_KE) return EFalse; + if(aIkeMsg->iKe->GetNextPayload() != IKEV2_PAYLOAD_NONCE) return EFalse; + break; + + case IKE_AUTH: + if(!iEapPlugin) + { + if(!aIkeMsg->iEncr || !aIkeMsg->iAuth || !aIkeMsg->iSa || !aIkeMsg->iTsI || !aIkeMsg->iTsR) + { + DEBUG_LOG(_L("1")); + return EFalse; + } + if(aIkeMsg->iSa->GetNextPayload() != IKEV2_PAYLOAD_TS_I) + { + DEBUG_LOG(_L("2")); + return EFalse; + } + if(aIkeMsg->iTsI->GetNextPayload() != IKEV2_PAYLOAD_TS_R) + { + DEBUG_LOG(_L("3")); + return EFalse; + } + + if(aResponse) + { + if(!aIkeMsg->iIdR) + { + DEBUG_LOG(_L("4")); + return EFalse; + } + if(!aIkeMsg->iCerts || aIkeMsg->iCerts->Count() == 0) + { + if(aIkeMsg->iIdR->GetNextPayload() != IKEV2_PAYLOAD_AUTH) + { + DEBUG_LOG(_L("5")); + return EFalse; + } + } + else + { + if(aIkeMsg->iIdR->GetNextPayload() != IKEV2_PAYLOAD_CERT) + { + DEBUG_LOG(_L("6")); + return EFalse; + } + TInt c = aIkeMsg->iCerts->Count(); + if(aIkeMsg->iCerts->At(c-1)->GetNextPayload() != IKEV2_PAYLOAD_AUTH) + { + DEBUG_LOG(_L("7")); + return EFalse; + } + } + } + else + { + if(!aIkeMsg->iIdI) + { + DEBUG_LOG(_L("8")); + return EFalse; + } + if(aIkeMsg->iCerts && aIkeMsg->iCerts->Count() != 0) + { + if(aIkeMsg->iIdI->GetNextPayload() != IKEV2_PAYLOAD_CERT) + { + DEBUG_LOG(_L("9")); + return EFalse; + } + } + if(aIkeMsg->iCertReqs && aIkeMsg->iCertReqs->Count() != 0) + { + TInt c = aIkeMsg->iCertReqs->Count(); + if(aIkeMsg->iIdR && aIkeMsg->iCertReqs->At(c-1)->GetNextPayload() != IKEV2_PAYLOAD_ID_R) + { + DEBUG_LOG(_L("10")); + return EFalse; + } + if(!aIkeMsg->iIdR && aIkeMsg->iCertReqs->At(c-1)->GetNextPayload() != IKEV2_PAYLOAD_AUTH) + { + DEBUG_LOG(_L("11")); + return EFalse; + } + } + if(aIkeMsg->iIdR && aIkeMsg->iIdR->GetNextPayload() != IKEV2_PAYLOAD_AUTH) + { + DEBUG_LOG(_L("12")); + return EFalse; + } + } + } + break; + + case CREATE_CHILD_SA: + if(!aIkeMsg->iEncr || !aIkeMsg->iSa || !aIkeMsg->iNonce) return EFalse; + if(aIkeMsg->iSa->GetNextPayload() != IKEV2_PAYLOAD_NONCE) return EFalse; + if(aIkeMsg->iKe && aIkeMsg->iNonce->GetNextPayload() != IKEV2_PAYLOAD_KE) return EFalse; + if(aIkeMsg->iTsI) + { + if(aIkeMsg->iKe && aIkeMsg->iKe->GetNextPayload() != IKEV2_PAYLOAD_TS_I) return EFalse; + if(!aIkeMsg->iKe && aIkeMsg->iNonce->GetNextPayload() != IKEV2_PAYLOAD_TS_I) return EFalse; + if(aIkeMsg->iTsI->GetNextPayload() != IKEV2_PAYLOAD_TS_R) return EFalse; + } + break; + + default: + break; + } + DEBUG_LOG(_L("13")); + return ETrue; + } + + +TBool CIkev2Negotiation::Stopped() + { + return iStopped; + } + + +TBool CIkev2Negotiation::ImplicitChildSa() + { + return (iState < KStateIkeSaCompleted); + } + + +HBufC8* CIkev2Negotiation::PeekProposedSa() + { + return iProposedSA; + } + + +HBufC8* CIkev2Negotiation::GetProposedSa() + { + HBufC8* Sa = iProposedSA; + iProposedSA = NULL; + return Sa; + } + + +void CIkev2Negotiation::SetProposedSa(HBufC8* aSaPl) + { + delete iProposedSA; + iProposedSA = aSaPl; + } + + +CIkev2Acquire** CIkev2Negotiation::GetAcquireQue() + { + return &iAcquireFirst; + } + + +CIkev2Expire** CIkev2Negotiation::GetExpireQue() + { + return &iExpireFirst; + } + + +TBool CIkev2Negotiation::RequestsPending() + { + return (iAcquireFirst || iExpireFirst); + } + + +void CIkev2Negotiation::SetNotifyCode(TInt aMsgType) + { + if (iNotifyCode == 0) + iNotifyCode = aMsgType; + } + + +TInt CIkev2Negotiation::GetNotifyCode() + { + return iNotifyCode; + } + + +void CIkev2Negotiation::StoreNotifyData32(TUint32 aData) + { + PUT32(iNotifyData, aData); + iNotifyDataLth = 4; + } + + +void CIkev2Negotiation::StoreNotifyData16(TUint16 aData) + { + PUT16(iNotifyData, aData); + iNotifyDataLth = 2; + } + + +TUint8* CIkev2Negotiation::NotifyData(TInt& aDataLth) + { + aDataLth = iNotifyDataLth; + if ( iNotifyDataLth ) + return iNotifyData; + else return NULL; + } + + +TInetAddr CIkev2Negotiation::GetLocalAddr() const + { + if ( iHdr.iVirtualAddr.IsUnspecified() ) + { + return iHdr.iLocalAddr; + } + else + { + return iHdr.iVirtualAddr; + } + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2pfkey.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2pfkey.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,279 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Utility methods to handle PFKEY messaging +* +*/ + +#include "ikev2pfkey.h" +#include "ikev2pluginsession.h" +#include "ikev2SAdata.h" +#include "ipsecsadata.h" +#include "pfkeyextdatautil.h" +#include "ikev2acquire.h" +#include "ikev2trafficselector.h" +#include "ikev2ipsecsadata.h" +#include +#include "ikev2const.h" + +static const TUid KIkeV2PlugInUid3 = { 0x10206993 }; + +void Ikev2Pfkey::UpdateIpsecSaDataBaseL(const TIkev2SAData& aIkev2SA, + const TIkeV2IpsecSAData& aChild, + CIkev2PluginSession& aIkePluginSession, + CIkev2Acquire& aAcquire) +{ + // + // Fill Ipsec SA info int TSAData object for PFKEY Update/Add + // primitives. Take local and remote identity data from CIkev2Acquire object + // + __ASSERT_DEBUG(aChild.iKeyMaterial != NULL, User::Invariant()); + + TUint16 LocalPort = 0; + TUint16 RemotePort = 0; + TUint8 LocalIdType = 0; + TUint8 RemoteIdType = 0; + TUint8 Protocol = 0; + const CArrayFix& TsI = aAcquire.TS_i(); + const CArrayFix& TsR = aAcquire.TS_r(); + + __ASSERT_DEBUG(TsI.Count() > 0, User::Invariant()); + __ASSERT_DEBUG(TsR.Count() > 0, User::Invariant()); + + HBufC8* localId = aAcquire.LocalId(); + HBufC8* remoteId = NULL; + + + if ( aAcquire.RemoteId() ) + { + remoteId = aAcquire.RemoteId()->AllocLC(); + } + else + { + if ( aAcquire.Response() ) + { + remoteId = TsI[0].IdFromTsL(); + CleanupStack::PushL(remoteId); + } + else + { + remoteId = TsR[0].IdFromTsL(); + CleanupStack::PushL(remoteId); + } + } + + // + // Build Encryption and integrity keys for Ipsec SA:s + // Keying material MUST be taken from the expanded KEYMAT in the + // following order: + // - All keys for SAs carrying data from the initiator to the responder + // are taken before SAs going in the reverse direction. + // If a single protocol has both encryption and authentication keys, + // the encryption key is taken from the first octets of KEYMAT and + // the authentication key is taken from the next octets. + // + const TUint8* KeyMat = aChild.iKeyMaterial->Des().Ptr(); + TPtrC8 InAuthKey(NULL,0), OutAuthKey(NULL,0); + TPtrC8 InEncrKey(NULL,0), OutEncrKey(NULL,0); + + if ( aChild.iSaType == SADB_SATYPE_ESP ) + { + if ( aAcquire.Response() ) + { + KeyMat = Ikev2Pfkey::GetIpsecKeys(&InEncrKey, &InAuthKey, KeyMat, aChild.iCipherKeyLth, aChild.iIntegKeyLth); + KeyMat = Ikev2Pfkey::GetIpsecKeys(&OutEncrKey, &OutAuthKey, KeyMat, aChild.iCipherKeyLth, aChild.iIntegKeyLth); + } + else + { + KeyMat = Ikev2Pfkey::GetIpsecKeys(&OutEncrKey, &OutAuthKey, KeyMat, aChild.iCipherKeyLth, aChild.iIntegKeyLth); + KeyMat = Ikev2Pfkey::GetIpsecKeys(&InEncrKey, &InAuthKey, KeyMat, aChild.iCipherKeyLth, aChild.iIntegKeyLth); + } + } + else + { // SADB_SATYPE_AH + if ( aAcquire.Response() ) + { + KeyMat = Ikev2Pfkey::GetIpsecKeys(&InEncrKey, &InAuthKey, KeyMat, 0, aChild.iIntegKeyLth); + KeyMat = Ikev2Pfkey::GetIpsecKeys(&OutEncrKey, &OutAuthKey, KeyMat, 0, aChild.iIntegKeyLth); + } + else + { + KeyMat = Ikev2Pfkey::GetIpsecKeys(&OutEncrKey, &OutAuthKey, KeyMat, 0, aChild.iIntegKeyLth); + KeyMat = Ikev2Pfkey::GetIpsecKeys(&InEncrKey, &InAuthKey, KeyMat, 0, aChild.iIntegKeyLth); + } + } + TIpsecSAData SaData; + TUint32 SadbFlags; + if (aAcquire.DHGroup()) + SadbFlags = SADB_SAFLAGS_PFS; + else SadbFlags = 0; + + if ( !aChild.iTransport ) + { + SaData.iInternalAddress.Init(KAfInet6); + SaData.iInternalAddress.SetScope(aIkePluginSession.VpnInterfaceIndex()); + SadbFlags |= SADB_SAFLAGS_INT_ADDR; + } + + // + // Inbound SA + // + SaData.iSAType = aChild.iSaType; + if ( aAcquire.Response() ) + SaData.iSeq = aAcquire.Id(); + else SaData.iSeq = aAcquire.Seq(); + SaData.iPid = KIkeV2PlugInUid3.iUid; + SaData.iSrc = aIkev2SA.iRemoteAddr; + SaData.iSrc.SetPort(RemotePort); + if ( aAcquire.SrcSpecific() ) + { + SaData.iDst = aIkev2SA.iLocalAddr; + SaData.iDst.SetPort(LocalPort); + } + else SaData.iDst.Init(0); + SaData.iProtocol = Protocol; + SaData.iSrcIdType = RemoteIdType; + SaData.iDstIdType = LocalIdType; + SaData.iSrcIdent.Set(remoteId->Des()); + if ( !aAcquire.Response() && localId != NULL) + SaData.iDstIdent.Set(localId->Des()); + + TUint32 spi; + TPtr8 spiPtr(reinterpret_cast(&spi), sizeof(spi)); + spiPtr = aChild.iSPI_In; + SaData.iSPI = spi; + switch ( aChild.iIntegAlg ) + { + case AUTH_HMAC_MD5_96: + SaData.iAuthAlg = SADB_AALG_MD5HMAC; + break; + + case AUTH_HMAC_SHA1_96: + SaData.iAuthAlg = SADB_AALG_SHA1HMAC; + break; + + default: + SaData.iAuthAlg = 0; + break; + } + SaData.iEncrAlg = aChild.iEncrAlg; // Should correspond PFKEY2.H ! + SaData.iAuthKey.Set(InAuthKey); + SaData.iEncrKey.Set(InEncrKey); + SaData.iHard = aAcquire.HardLifetime(); + SaData.iSoft = aAcquire.SoftLifetime(); + SaData.iReplayWindowLength = aAcquire.ReplayWindow(); + SaData.iFlags = SadbFlags; + + // + // Get the following implementation specific information for PFKEY + // primitives: + // -- ESP UDP encapsulation info, if a NAT device detected + // -- Interface index for tunnel mode inbound SA + // + HBufC8* GenExt = NULL; + if ( aIkev2SA.iNATFlags ) + { + GenExt = HBufC8::NewLC(128); + TPtr8 GenExtPtr = GenExt->Des(); + TInetAddr DummyAddr; + DummyAddr.SetFamily(KAFUnspec); + PFKeyExtDataUtil::BuildUdpEncExtensionData(GenExtPtr, aIkev2SA.iNATFlags, + EFalse, EFalse, 0, 0, + aIkev2SA.iDestinAddr, DummyAddr); + } + else + { + GenExt = HBufC8::NewLC(1); + } + SaData.iGenericExtension.Set(*GenExt); + + aIkePluginSession.UpdateSAL(SaData); + + SaData.iFlags &= ~SADB_SAFLAGS_INT_ADDR; //No VPN interface index to outbound SA + // + // Outbound SA. Some changes in the SA, the rest is the same + // + if ( !aAcquire.Response() ) + SaData.iPid = aAcquire.Pid(); // Use Acquire PID for OUT SA when initiator + if ( aAcquire.SrcSpecific() ) + { + SaData.iSrc = aIkev2SA.iLocalAddr; + SaData.iSrc.SetPort(LocalPort); + } + else SaData.iSrc.Init(0); + SaData.iDst = aIkev2SA.iRemoteAddr; + SaData.iDst.SetPort(RemotePort); + SaData.iSrcIdType = LocalIdType; + SaData.iDstIdType = RemoteIdType; + SaData.iSrcIdent.Set(localId->Des()); + SaData.iDstIdent.Set(remoteId->Des()); + + spiPtr = aChild.iSPI_Out; + SaData.iSPI = spi; + SaData.iAuthKey.Set(OutAuthKey); + SaData.iEncrKey.Set(OutEncrKey); + + aIkePluginSession.AddSAL(SaData); + + CleanupStack::PopAndDestroy(GenExt); + CleanupStack::PopAndDestroy(remoteId); + +} + +CIkev2Acquire* Ikev2Pfkey::DeleteInboundSPI(const TIkev2SAData& aIkev2SA, + CIkev2PluginSession& aIkePluginSession, + CIkev2Acquire* aAcquire) +{ + // + // Issue PFKEY Delete SA for Inbound SPI in CIkev2Acquire object and + // delete CIkev2Acquire object then + // + if ( aAcquire ) + { + TInetAddr LocalAddr; + if ( aAcquire->SrcSpecific() ) + LocalAddr = aIkev2SA.iLocalAddr; + else LocalAddr.Init(0); + LocalAddr.SetPort(0); + TInetAddr RemoteAddr = aIkev2SA.iRemoteAddr; + RemoteAddr.SetPort(0); + + TUint32 spi; + TPtr8 spiPtr(reinterpret_cast(&spi), sizeof(spi)); + spiPtr = aAcquire->SPI_In(); + aIkePluginSession.DeleteIpsecSA(spi, RemoteAddr, LocalAddr, aAcquire->IpsecProtocol()); + delete aAcquire; + } + + return NULL; +} + +const TUint8* Ikev2Pfkey::GetIpsecKeys(TPtrC8* aEncrKey, TPtrC8* aIntegKey, const TUint8* aKeyMaterial, TInt aCipherKeyLth, TInt aIntegKeyLth ) +{ + if ( aCipherKeyLth && aKeyMaterial) + { + ASSERT(aEncrKey); + aEncrKey->Set(aKeyMaterial, aCipherKeyLth); + aKeyMaterial += aCipherKeyLth; + } + + if ( aIntegKeyLth ) + { + ASSERT(aIntegKey && aKeyMaterial); + aIntegKey->Set(aKeyMaterial, aIntegKeyLth); + aKeyMaterial += aIntegKeyLth; + } + + return aKeyMaterial; +} + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2plugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2plugin.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,139 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 protocol plugin +* +*/ + +#include +#include + +#include "ikev2plugin.h" +#include "ikedebug.h" +#include "ikev2pluginsession.h" +#include "ipsecpolicyutil.h" + + +EXPORT_C MIkePluginIf* Ikev2PlugInL( MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ) + { + return CIkev2PlugIn::NewL(aEventLogger, aDebug); + } + +CIkev2PlugIn* CIkev2PlugIn::NewL( MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ) + { + CIkev2PlugIn* self = new (ELeave) CIkev2PlugIn(aEventLogger, aDebug); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +CIkev2PlugIn::CIkev2PlugIn( MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ) +: iEventLogger(aEventLogger), iDebug(aDebug) + { + } + + +void CIkev2PlugIn::ConstructL() + { + iPfKeySocketIf = CPFKeySocketIf::NewL(this, iDebug); + iIpsecPolicyUtil = CIpsecPolicyUtil::NewL(); + } + + +CIkev2PlugIn::~CIkev2PlugIn() + { + delete iIpsecPolicyUtil; + delete iPfKeySocketIf; + + __ASSERT_DEBUG( iPluginSessions.Count() == 0, + User::Invariant() ); + iPluginSessions.Close(); + } + + +MIkePluginSessionIf* CIkev2PlugIn::CreateSessionL( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + MIkeDataInterface& aIkeDataInterface ) + { + CIkev2PluginSession* pluginSession = CIkev2PluginSession::NewL( aVpnIapId, + aVpnNetId, + aVpnInterfaceIndex, + aIkeDataInterface, + *this, + *iPfKeySocketIf, + *iIpsecPolicyUtil, + iEventLogger, + iDebug ); + TInt err = iPluginSessions.Append( pluginSession ); + + if ( err != KErrNone ) + { + delete pluginSession; + pluginSession = NULL; + User::Leave( err ); + } + + return pluginSession; + } + +void CIkev2PlugIn::PluginSessionDeleted(const MIkePluginSessionIf* aDeletedSession) + { + for (TInt i = 0; i < iPluginSessions.Count(); ++i) + { + if (iPluginSessions[i] == aDeletedSession) + { + iPluginSessions.Remove(i); + } + } + } + +void CIkev2PlugIn::PfkeyMessageReceived( const TPfkeyMessage& aPfkeyMessage ) + { + switch ( aPfkeyMessage.iBase.iMsg->sadb_msg_type ) + { + case SADB_ADD: // Fall through + case SADB_ACQUIRE: + { + for ( TInt i=0; i< iPluginSessions.Count(); i++ ) + { + if ( iPluginSessions[i]->MatchDestinationAddress( aPfkeyMessage.iDstAddr.Address() ) ) + { + iPluginSessions[i]->PfkeyMessageReceived( aPfkeyMessage ); + break; + } + } + break; + } + + case SADB_EXPIRE: + { + for ( TInt i=0; i< iPluginSessions.Count(); i++ ) + { + if ( iPluginSessions[i]->MatchDestinationAddress( aPfkeyMessage.iSrcAddr.Address() ) ) + { + iPluginSessions[i]->PfkeyMessageReceived( aPfkeyMessage ); + break; + } + } + break; + } + default: + break; + } + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2pluginsession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2pluginsession.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,1177 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include + +#include "ikev2pluginsession.h" +#include "ikev2plugin.h" +#include "ikev2Negotiation.h" +#include "ikepolparser.h" +#include "ikedebug.h" +#include "ikev2SA.h" +#include "ikev2SAdata.h" +#include "ikedatainterface.h" +#include "ipsecsadata.h" +#include "ikev2pfkey.h" +#include "ipsecsalist.h" +#include "ipsecpolicyutil.h" +#include "ikev2messagesendqueue.h" + + +CIkev2PluginSession* CIkev2PluginSession::NewL( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + MIkeDataInterface& aDataInterface, + CIkev2PlugIn& aPlugin, + CPFKeySocketIf& aPfKeySocketIf, + CIpsecPolicyUtil& aIpsecPolicyUtil, + MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ) + { + CIkev2PluginSession* self = new (ELeave) CIkev2PluginSession( aVpnIapId, aVpnNetId, + aVpnInterfaceIndex, aDataInterface, + aPlugin, aPfKeySocketIf, aIpsecPolicyUtil, + aEventLogger, aDebug ); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + + return self; + } + + +CIkev2PluginSession::CIkev2PluginSession( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + MIkeDataInterface& aDataInterface, + CIkev2PlugIn& aPlugin, + CPFKeySocketIf& aPfKeySocketIf, + CIpsecPolicyUtil& aIpsecPolicyUtil, + MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ) +: iVpnIapId(aVpnIapId), iVpnNetId(aVpnNetId), iDataInterface(aDataInterface), iPlugin(aPlugin), + iPfKeySocketIf(aPfKeySocketIf), iIpsecPolicyUtil(aIpsecPolicyUtil), iEventLogger(aEventLogger), + iDebug(aDebug), iVpnInterfaceIndex(aVpnInterfaceIndex) + { + } + + +void CIkev2PluginSession::ConstructL() + { + TPtr8 ptr((TUint8*)&iSAIdSeed, sizeof(iSAIdSeed)); + ptr.SetLength(sizeof(iSAIdSeed)); + TRandom::RandomL(ptr); + iSAIdSeed &= 0x7fffffff; // Reset the most significant bit + DEBUG_LOG1(_L("CIkev2Plugin::ConstructL, SAId seed: %d"), iSAIdSeed ); + } + + +CIkev2PluginSession::~CIkev2PluginSession() + { + //Makes sure that all the negotiations and + //Sa data structures are deleted: + while ( iFirstNegotiation ) + { + CIkev2Negotiation* negotiation = iFirstNegotiation; + iFirstNegotiation = iFirstNegotiation->iNext; + + delete negotiation; + } + + while(iFirstIkev2SA) + { + CIkev2SA* ikeV2Sa = iFirstIkev2SA; + iFirstIkev2SA = ikeV2Sa->iNext; + + delete ikeV2Sa; + } + + delete iMessageSendQue; + delete iReceiver; + delete iIkeData; + delete iDeactivationTimer; + + iPlugin.PluginSessionDeleted(this); + } + + +void CIkev2PluginSession::NegotiateWithHost( const CIkeData& aIkeData, + TVPNAddress& aInternalAddress, + TRequestStatus& aStatus ) + { + __ASSERT_DEBUG(iClientStatusNegotiate == NULL, + User::Invariant()); + + iClientStatusNegotiate = &aStatus; + *iClientStatusNegotiate = KRequestPending; + + iInternalAddress = &aInternalAddress; + + TRAPD(err, DoNegotiateWithHostL(aIkeData)); + if (err != KErrNone) + { + DoCompleteNegotiateWithHost(err); + } + } + + +void CIkev2PluginSession::DoNegotiateWithHostL( const CIkeData& aIkeData ) + { + iIkeData = CIkeData::NewL(&aIkeData); + + iReceiver = CIkev2Receiver::NewL( iDataInterface, + *this ); + + iMessageSendQue = CIkev2MessageSendQueue::NewL(iDataInterface, + iIkeData->iAddr, + iIkeData->iDscp, + iIkeData->iNatKeepAlive, + iDebug); + + + TInetAddr physicalAddr; + iDataInterface.GetLocalAddress(physicalAddr); + TInetAddr sgwAddr(iIkeData->iAddr); + + // Negotiation ownership is transferred to the plugin + // before leave can occur. + iSAIdSeed++; + + if (aIkeData.iUseInternalAddr) + { + CIkev2Negotiation* Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, iEventLogger, + *iMessageSendQue, iDebug, iIkeData, + iVpnIapId, iSAIdSeed, + physicalAddr, sgwAddr); + + Negotiation->StartIkeSANegotiationL(); + } + else + { + //If internall addressing is not in use, we do not do anything else + //in this phase. The actual IKE negotiation is trickered by an Acquire + //PFKEY message from the IPsec, when there is actual data between the SGW and + //the phone. + DoCompleteNegotiateWithHost( KErrNone); + } + } + + +void CIkev2PluginSession::CancelNegotiateWithHost() + { + + if (iClientStatusNegotiate != NULL) + { + //If the Negotiate with host is cancelled we pretty much do a silent close + //for the connection + + while ( iFirstNegotiation ) + { + CIkev2Negotiation* negotiation = iFirstNegotiation; + iFirstNegotiation = iFirstNegotiation->iNext; + + delete negotiation; + } + + while(iFirstIkev2SA) + { + CIkev2SA* ikeV2Sa = iFirstIkev2SA; + iFirstIkev2SA = ikeV2Sa->iNext; + + delete ikeV2Sa; + } + DoCompleteNegotiateWithHost(KErrCancel); + } + } + + +void CIkev2PluginSession::DeleteSession( const TBool aSilentClose, + TRequestStatus& aStatus ) + { + DEBUG_LOG1(_L("Deactivating IKE SA:s for vpn iap %d"), iVpnIapId); + + __ASSERT_DEBUG(iClientStatusDelete == NULL, User::Invariant()); + iClientStatusDelete = &aStatus; + *iClientStatusDelete = KRequestPending; + + TInt err = KErrNone; + TBool doSilentClose = aSilentClose; + //Deletes all ongoing ike negotiations + while ( iFirstNegotiation ) + { + CIkev2Negotiation* negotiation = iFirstNegotiation; + iFirstNegotiation = iFirstNegotiation->iNext; + + delete negotiation; + } + + TBool deactivating = EFalse; + while(iFirstIkev2SA) + { + CIkev2SA* ikeV2Sa = iFirstIkev2SA; + iFirstIkev2SA = ikeV2Sa->iNext; + + if (!doSilentClose) + { + TRAP(err, DoDeleteIkeSAExhangeL(ikeV2Sa->iIkeV2SaData)); + if (err == KErrNone) + { + deactivating = ETrue; + } + else + { + //If we can't start the IKE SA delete exhange, + //we do following expection handling: + //1. Possible already active delete exhanges can continue as they were. + //2. The IKE SA, which delete exchange failured, is deleted silently. + //3. The rest of the IKE SAs are deleted silently. + //4. The caller is notified with the error returned by the failed delete + // exchange attempt, if no delete exhanges are in progress. + //5. If there is ongoing delete exhange(s), the caller is notified with the + // status of last delete exhange, which completes. + DEBUG_LOG1(_L("CIkev2PluginSession::DeleteSession: Can't start IKE SA delete exhange (%d)"), + err ); + doSilentClose = ETrue; + } + } + delete ikeV2Sa; + } + + if (deactivating) + { + TRAP( err, iDeactivationTimer = CIkev2DeactivationTimer::NewL(*this) ); + } + + if (deactivating && + err == KErrNone) + { + iDeactivationTimer->IssueRequest(); + } + else + { + delete iIkeData; + iIkeData = NULL; + DoCompleteDeleteSession(err); + } + } + + +void CIkev2PluginSession::DoDeleteIkeSAExhangeL(TIkev2SAData& aIkev2SAdata) + { + DEBUG_LOG1(_L("Deleting IKE SA SAID = %d"), aIkev2SAdata.SaId()); + + __ASSERT_DEBUG(iFirstNegotiation == NULL, User::Invariant()); + + CIkev2Negotiation* negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, + iEventLogger, *iMessageSendQue, + iDebug, aIkev2SAdata); + CleanupStack::PushL(negotiation); + negotiation->StartIkeSADeleteL(); + CleanupStack::Pop(negotiation); + + __ASSERT_DEBUG( !negotiation->Stopped(), User::Invariant() ); + + } + + +void CIkev2PluginSession::CancelDeleteSession() + { + if (iClientStatusDelete != NULL) + { + //If the delete sessionis cancelled we pretty much do a silent close + //for the connection + iMessageSendQue->CancelAll(); + iReceiver->Cancel(); + delete iDeactivationTimer; + iDeactivationTimer = NULL; + + while ( iFirstNegotiation ) + { + CIkev2Negotiation* negotiation = iFirstNegotiation; + iFirstNegotiation = iFirstNegotiation->iNext; + + delete negotiation; + } + + while(iFirstIkev2SA) + { + CIkev2SA* ikeV2Sa = iFirstIkev2SA; + iFirstIkev2SA = ikeV2Sa->iNext; + + delete ikeV2Sa; + } + DoCompleteDeleteSession(KErrCancel); + } + } + + +void CIkev2PluginSession::NotifyError( TRequestStatus& aStatus ) + { + aStatus = KRequestPending; + iClientStatusNotifyError = &aStatus; + } + +void CIkev2PluginSession::CancelNotifyError() + { + if (iClientStatusNotifyError != NULL) + { + DoCompleteNotifyError(KErrCancel); + } + } + + +void CIkev2PluginSession::NotifyInternalAddressChanged( TVPNAddress& aInternalAddress, + TRequestStatus& aStatus ) + { + __ASSERT_DEBUG(iClientStatusInternalAddressChange == NULL, + User::Invariant()); + + __ASSERT_DEBUG(iChangedInternalAddress == NULL, + User::Invariant()); + + + iClientStatusInternalAddressChange = &aStatus; + *iClientStatusInternalAddressChange = KRequestPending; + + iChangedInternalAddress = &aInternalAddress; + } + + +void CIkev2PluginSession::CancelNotifyInternalAddressChanged() + { + if (iClientStatusInternalAddressChange != NULL) + { + __ASSERT_DEBUG(iChangedInternalAddress != NULL, User::Invariant()); + iChangedInternalAddress = NULL; + User::RequestComplete(iClientStatusInternalAddressChange, KErrCancel); + } + } + + +void CIkev2PluginSession::LinkNegotiation(CIkev2Negotiation* aNegotiation) +{ + ASSERT(aNegotiation); + aNegotiation->iNext = iFirstNegotiation; + iFirstNegotiation = aNegotiation; +} + + +void CIkev2PluginSession::RemoveNegotiation(CIkev2Negotiation* aNegotiation) + { + CIkev2Negotiation* Prev = NULL; + CIkev2Negotiation* Neg = iFirstNegotiation; + + while ( Neg ) + { + if ( Neg == aNegotiation ) + { + if ( Prev ) + Prev->iNext = Neg->iNext; + else iFirstNegotiation = Neg->iNext; + break; + } + Prev = Neg; + Neg = Neg->iNext; + } + } + +// +// Find an IKEv2 SA using SA Id as search argument +// +CIkev2SA* CIkev2PluginSession::FindIkev2SA(TUint32 aSAId, TInt aRequiredState, TInt aNewState) +{ + CIkev2SA* Sa = iFirstIkev2SA; + while ( Sa ) + { + if ( ( Sa->iIkeV2SaData.SaId() == aSAId ) + && + ( ( aRequiredState == KSaStateNotDefined) || + ( aRequiredState == Sa->iIkeV2SaData.iSAState ) ) ) + { + if ( aNewState != KSaStateNotDefined ) + Sa->iIkeV2SaData.iSAState = aNewState; + break; + } + Sa = Sa->iNext; + } + return Sa; +} + + +TBool CIkev2PluginSession::UpdateIkev2SAL(TIkev2SAData* aIkev2SAData, TIkeV2IpsecSAData* aIpsecSAData) + { + ASSERT(aIkev2SAData); + CIkev2SA* Ikev2SA = FindIkev2SA(aIkev2SAData->SaId(), KSaStateNotDefined, KSaStateNotDefined); + if ( Ikev2SA ) + { + Ikev2SA->UpdateL(aIkev2SAData, aIpsecSAData); + return ETrue; + } + else + { + return EFalse; + } + } + +TIkeV2IpsecSAData* CIkev2PluginSession::FindIpsecSAData(TUint32 aSAId, const TDesC8& aSpi, TBool aInbound) + { + __ASSERT_ALWAYS(aSpi.Length() == 4, User::Invariant()); + + _LIT8(KZeroSpi, ""); + TIkeV2IpsecSAData* SaData = NULL; + CIkev2SA* Ikev2SA = FindIkev2SA(aSAId, KSaStateNotDefined, KSaStateNotDefined); + if ( Ikev2SA ) + { + if ( aInbound ) + SaData = Ikev2SA->FindIpsecSaData(aSpi, KZeroSpi, EFalse); + else SaData = Ikev2SA->FindIpsecSaData(KZeroSpi, aSpi, EFalse); + } + return SaData; + } + + +// +// Delete an IKEv2 SA using SA Id as search argument +// +void CIkev2PluginSession::DeleteIkev2SA(TUint32 aSAId) +{ + CIkev2SA* Sa = iFirstIkev2SA; + CIkev2SA* PrevSa = NULL; + while ( Sa ) + { + if ( Sa->iIkeV2SaData.SaId() == aSAId ) + { + if ( PrevSa ) + { + PrevSa->iNext = Sa->iNext; + } + else + { + iFirstIkev2SA = Sa->iNext; + } + if (Sa->iIkeV2SaData.iFloatedPort) + { + iMessageSendQue->SaBehindNatDeleted(Sa->iIkeV2SaData.SaId()); + } + delete Sa; + break; + } + PrevSa = Sa; + Sa = Sa->iNext; + } +} + +TUint32 CIkev2PluginSession::GetSAId() + { + iSAIdSeed++; + return iSAIdSeed; + } + +TBool CIkev2PluginSession::CreateIkev2SAL(TIkev2SAData& aIkev2SAData) + { + CIkev2SA* Ikev2SA = CIkev2SA::NewL(*this, aIkev2SAData, iDebug); + if (aIkev2SAData.iFloatedPort) + { + CleanupStack::PushL(Ikev2SA); + iMessageSendQue->NewSaBehindNatL(aIkev2SAData.SaId()); + CleanupStack::Pop(Ikev2SA); + } + Ikev2SA->iNext = iFirstIkev2SA; + iFirstIkev2SA = Ikev2SA; + + return ETrue; + } + +void CIkev2PluginSession::IkeSaCompleted(TInt aStatus, TVPNAddress& aInternalAddress) +{ + if (iClientStatusNegotiate != NULL) + { + //This is the first IKE sa of this session + if (!aInternalAddress.iVPNIfAddr.IsUnspecified()) + { + *iInternalAddress = aInternalAddress; + } + + // Completion is postponed, if IPsec SAs have not yet been updated. + if (iActivated || + aStatus != KErrNone) + { + DoCompleteNegotiateWithHost(aStatus); + } + } + else if (aStatus == KErrNone) + { + //This is not the first IKE SA in this session. + //If IA has changed we notify the possible address change + if(!aInternalAddress.iVPNIfAddr.IsUnspecified()) + { + VirtualIpChanged(aInternalAddress); + } + } + else if(iClientStatusNotifyError != NULL) + { + //Ike sa establishmet has failed. + DoCompleteNotifyError(aStatus); + } +} + + +void CIkev2PluginSession::VirtualIpChanged(TVPNAddress& aVirtualIp) + { + if (iClientStatusInternalAddressChange != NULL) + { + __ASSERT_DEBUG(iChangedInternalAddress != NULL, User::Invariant()); + *iChangedInternalAddress = aVirtualIp; + User::RequestComplete(iClientStatusInternalAddressChange, KErrNone); + iChangedInternalAddress = NULL; + } + } + +void CIkev2PluginSession::StartResponding() + { + iCurrIkeSaRespCount++; + } + + +void CIkev2PluginSession::StopResponding() + { + if (iCurrIkeSaRespCount) + { + iCurrIkeSaRespCount--; + } + } + + +void CIkev2PluginSession::DeleteIpsecSAData(TUint32 aSAId, const TDesC8& aSpi, TBool aInbound) + { + __ASSERT_DEBUG(aSpi.Length() == 4, User::Invariant()); + _LIT8(KZeroSpi, ""); + CIkev2SA* Ikev2SA = FindIkev2SA(aSAId, KSaStateNotDefined, KSaStateNotDefined); + if ( Ikev2SA ) + { + if ( aInbound ) + Ikev2SA->DeleteIpsecSaData(aSpi, KZeroSpi); + else Ikev2SA->DeleteIpsecSaData(KZeroSpi, aSpi); + } + } + +void CIkev2PluginSession::IkeSaDeleted(TInt aStatus) + { + if (iClientStatusDelete != NULL) + { + DoCompleteDeleteSession(aStatus); + } + else if (aStatus != KErrNone && iClientStatusNotifyError != NULL) + { + DoCompleteNotifyError(aStatus); + } + else if (aStatus != KErrNone && iClientStatusNegotiate != NULL) + { + TVPNAddress dummyVirtualIp; + IkeSaCompleted(aStatus,dummyVirtualIp); + } + } + + +CIpsecSaSpecList* CIkev2PluginSession::GetIPsecSaSpecListL( const TInetAddr& aLocalAddr, const TInetAddr& aLocalMask, + const TInetAddr& aRemoteAddr, const TInetAddr& aRemoteMask, + TInt aProtocol ) + { + CIpsecSaSpecList* saSpecList = iIpsecPolicyUtil.GetIpseSaSpecListLC( aLocalAddr, aLocalMask, + aRemoteAddr, aRemoteMask, + aProtocol, iVpnNetId ); + CleanupStack::Pop(saSpecList); + + return saSpecList; + } + + +TBool CIkev2PluginSession::InheritIpsecSas(TUint32 aDstSAId, TUint32 aSrcSAId) + { + CIkev2SA* DstIkev2SA = FindIkev2SA(aDstSAId, KSaStateNotDefined, KSaStateNotDefined); + if ( DstIkev2SA ) + { + CIkev2SA* SrcIkev2SA = FindIkev2SA(aSrcSAId, KSaStateNotDefined, KSaStateNotDefined); + if ( SrcIkev2SA ) + { + DstIkev2SA->SetIpsecSaQue(SrcIkev2SA->GetIpsecSaQue()); + return ETrue; + } + } + return EFalse; + } + + +TUint32 CIkev2PluginSession::VpnInterfaceIndex() const + { + return iVpnInterfaceIndex; + } + +TBool CIkev2PluginSession::RemoteAddrChanged(TIkev2SAData* aIkev2SAData, TInetAddr& aNewIp) + { + __ASSERT_DEBUG(aIkev2SAData, User::Invariant()); + CIkev2SA* Ikev2SA = FindIkev2SA(aIkev2SAData->SaId(), KSaStateNotDefined, KSaStateNotDefined); + if ( Ikev2SA ) + return Ikev2SA->RemoteAddrChanged(aNewIp); + else return ETrue; + } + +void CIkev2PluginSession::KeepAliveIkeSAL(TIkev2SAData* aIkev2SAdata) + { + ASSERT(aIkev2SAdata); + CIkev2Negotiation* Negotiation = FindNegotiation(aIkev2SAdata->SaId(), KSaStateNotDefined); + if ( Negotiation ) + { + //There is already some negotiation going on this SA, don't send keep-alive + return; + } + + Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, + iEventLogger, *iMessageSendQue, + iDebug, *aIkev2SAdata); + CleanupStack::PushL(Negotiation); + Negotiation->SendKeepAliveMsgL(); + if ( Negotiation->Stopped() ) + { + CleanupStack::PopAndDestroy(Negotiation); + } + else + { + CleanupStack::Pop(Negotiation); + } + } + +CIkev2Negotiation* CIkev2PluginSession::FindNegotiation(TUint32 aSAId, TInt aRequiredState) + { + // + // Find IKEv2 negotiation object using SAId as search argument + // + CIkev2Negotiation* Neg = iFirstNegotiation; + while ( Neg ) + { + if ( ( Neg->iHdr.SaId() == aSAId ) + && + ( ( aRequiredState == KSaStateNotDefined) || + ( aRequiredState == Neg->iHdr.iSAState ) ) ) + { + break; + } + + Neg = Neg->iNext; + } + return Neg; + } + +TBool CIkev2PluginSession::DeleteIkeSAL(TIkev2SAData* aIkev2SAdata, TBool aNormal) + { + ASSERT(aIkev2SAdata); + // + // An IKE SA delete request received + // Check first does there exists an ongoing negotiation on this IKE + // SA deleted and delete this block. + // Allocate a new negotiation with TIkev2SAData and initiate IKE SA + // deletion request + // + DEBUG_LOG1(_L("Deleting IKE SA SAID = %d"), aIkev2SAdata->SaId()); + + CIkev2Negotiation* Negotiation = FindNegotiation(aIkev2SAdata->SaId(), KSaStateNotDefined); + while ( Negotiation ) + { + delete Negotiation; // destructor removes object from queue, too + Negotiation = FindNegotiation(aIkev2SAdata->SaId(), KSaStateNotDefined); + } + + TBool Started = EFalse; + if ( aNormal ) + { + Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, + iEventLogger, *iMessageSendQue, + iDebug, *aIkev2SAdata); + CleanupStack::PushL(Negotiation); + Negotiation->StartIkeSADeleteL(); + CleanupStack::Pop(Negotiation); + if ( Negotiation->Stopped() ) + delete Negotiation; + else Started = ETrue; + } + else + { + DEBUG_LOG(_L("Forced close, no delete payload(s) sent")); + } + + DeleteIkev2SA(aIkev2SAdata->SaId()); + + return Started; + } + +void CIkev2PluginSession::RekeyIkeSAL(TIkev2SAData* aIkev2SAdata) + { + ASSERT(aIkev2SAdata); + // + // Rekey specified IKE SA + // + DEBUG_LOG1(_L("Starting to rekey IKE SA SAID = %d"), aIkev2SAdata->SaId()); + CIkev2Negotiation* Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, + iEventLogger, *iMessageSendQue, + iDebug, *aIkev2SAdata); + CleanupStack::PushL(Negotiation); + Negotiation->BuildIkeSaRekeyMsgL(ETrue); + if ( Negotiation->Stopped() ) + CleanupStack::PopAndDestroy(Negotiation); + else CleanupStack::Pop(Negotiation); + } + +void CIkev2PluginSession::IkeMsgReceived( const ThdrISAKMP& aIkeMsg, + const TInetAddr& aSrcAddr, + TInt aLocalPort) + { + TRAPD(err, IkeMessageReceivedL(aIkeMsg, aSrcAddr, aLocalPort)); + if (err != KErrNone) + { + //Leave that we have not been able to handle + //above layers. We close the connection and report an error. + IkeSaDeleted(err); + } + } + +// --------------------------------------------------------------------------- +// From class MIkev2ReceiverCallback +// Handles notification about receive error. +// --------------------------------------------------------------------------- +// +void CIkev2PluginSession::ReceiveError( TInt aError ) + { + IkeSaDeleted( aError ); + } + +void CIkev2PluginSession::IkeMessageReceivedL(const ThdrISAKMP& aIkeMessage, + const TInetAddr &aRemote, + TUint16 aLocalPort) + { + + // + // Do sanity check Parse incoming IKE message + // + TUint32 NegotiationId; + if ( !CheckIkeMessageHeader(aIkeMessage, NegotiationId) ) + return; // Format error in received IKE message header + + TBool CleanUpUsed = EFalse; + CIkev2Negotiation* Negotiation; + if ( NegotiationId ) + { + // + // Try to find ongoing IKEv2 negotiation with Id + // + Negotiation = FindNegotiation(NegotiationId, KSaStateNotDefined); + if ( !Negotiation ) + { + if (!(aIkeMessage.GetFlags() & IKEV2_RESPONSE_MSG)) + { + // + // Try to find an IKEv2 SA with negotiation ID + // + TIkev2SAData* Ikev2SAdata = FindIkev2SAData(NegotiationId, + KSaStateNotDefined, KSaStateNotDefined); + if ( Ikev2SAdata ) + { + Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, + iEventLogger, *iMessageSendQue, + iDebug, *Ikev2SAdata); + CleanupStack::PushL(Negotiation); + CleanUpUsed = ETrue; + } + else + { + DEBUG_LOG(_L("Receive IKE message cannot be associated")); + return; + } + } + else + { + DEBUG_LOG(_L("Received response message, but we don't have associated negotiation")); + DEBUG_LOG(_L("--> Message silently discarded.")); + return; + } + } + } + else + { + // + // Negotiation ID has zero value. This must be an IKE_SA_INIT + // message from peer where Responder SPI has zero value + // Get a new negotiation object + // + + TInetAddr localAddr; + iDataInterface.GetLocalAddress(localAddr); + Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, iEventLogger, + *iMessageSendQue, iDebug, + iIkeData, iVpnIapId, this->GetSAId(), + localAddr, + aRemote); + CleanupStack::PushL(Negotiation); + if ( !Negotiation->StartRespondingL(aIkeMessage) ) + { + if ( Negotiation->Stopped() ) + CleanupStack::PopAndDestroy(Negotiation); + else CleanupStack::Pop(Negotiation); + return; + } + CleanUpUsed = ETrue; + } + + Negotiation->ProcessIkeMessageL(aIkeMessage, (TInetAddr&)aRemote, aLocalPort); + if ( CleanUpUsed ) + CleanupStack::Pop(Negotiation); + + if ( Negotiation->Stopped() ) + delete Negotiation; + } + +TBool CIkev2PluginSession::CheckIkeMessageHeader(const ThdrISAKMP& aIkeMessage, TUint32& NegotiationId) + { + // + // Do the following sanity checks to incoming IKE message fixed + // header + // -- Check that Exchange type has some value specified in IKEv2 + // -- Check that Next Payload has some value specified in IKEv2 + // -- Check that Inititor SPI has not "zero" value + // + TUint8 ExchangeType = aIkeMessage.GetExchange(); + if ( (ExchangeType < IKE_SA_INIT) || (ExchangeType > INFORMATIONAL) ) + { + DEBUG_LOG1(_L("Unsupported Exchange Type: %d"),ExchangeType); + return EFalse; + } + + TUint32 SPI_I_Low = aIkeMessage.GetSPI_I_Low32(); + TUint32 NegotiationId_I = aIkeMessage.GetNegotiationID_I(); + if ( (SPI_I_Low == 0 ) && ( NegotiationId_I == 0 ) ) + { + DEBUG_LOG(_L("Initiator SPI has zero value !\n")); + return EFalse; + } + // + // The negotiation id is a 32-bit (not zero) id value which + // unambiguously identiefies an IKEv2 negotiation object (CIkev2Negotiation). + // This negotiation id is packed into the SPI value ( 32 most + // significant bits of SPI) defined by the local end (=us). + // Get the negotiation id from local SPI in IKE message + // according to Initiator Bit in received IKE message header + // flags. + // Initiator = 1 ==> Get negotiation id from responder SPI + // Initiator = 0 ==> Get negotiation id from initiator SPI + // + aIkeMessage.GetFlags(); + if ( aIkeMessage.GetFlags() & IKEV2_INITIATOR ) + NegotiationId = aIkeMessage.GetNegotiationID_R(); + else NegotiationId = NegotiationId_I; + + return ETrue; + } + + +void CIkev2PluginSession::DeleteIpsecSA( const TUint32 aSPI, const TInetAddr& aSrc, + const TInetAddr& aDst, const TUint8 aProtocol ) + { + iPfKeySocketIf.DeleteSA(aSPI, aSrc, aDst, aProtocol); + } + + +void CIkev2PluginSession::AddSAL( const TIpsecSAData& aSAData ) + { + iPfKeySocketIf.AddSAL( aSAData ); + } + + +void CIkev2PluginSession::UpdateSAL( const TIpsecSAData& aSAData ) + { + iPfKeySocketIf.UpdateSAL( aSAData ); + } + + +TIkev2SAData* CIkev2PluginSession::FindIkev2SAData(TUint32 aSAId, TInt aRequiredState, TInt aNewState) + { + TIkev2SAData* SaData = NULL; + CIkev2SA* Ikev2SA = FindIkev2SA(aSAId, aRequiredState, aNewState); + if ( Ikev2SA ) + SaData = (TIkev2SAData*)&Ikev2SA->iIkeV2SaData; + return SaData; + } + +void CIkev2PluginSession::PfkeyMessageReceived(const TPfkeyMessage& aPfkeyMessage) + { + TRAPD(err, PfkeyMessageReceivedL(aPfkeyMessage)); + if (err != KErrNone) + { + //Leave that we have not been able to handle + //above layers. We close the connection and report an error. + IkeSaDeleted(err); + } + } + +void CIkev2PluginSession::PfkeyMessageReceivedL(const TPfkeyMessage& aPfkeyMessage) + { + // + // Process received PFKEY message according to message type + // + TIkev2SAData* Ikev2SAdata = NULL; + CIkev2Negotiation* Negotiation = NULL; + TBool CleanUpUsed = EFalse; + + __ASSERT_DEBUG(aPfkeyMessage.iBase.iMsg->sadb_msg_type != SADB_GETSPI, User::Invariant()); + switch ( aPfkeyMessage.iBase.iMsg->sadb_msg_type ) + { + case SADB_ADD: + { + if ( !iActivated ) + { + DEBUG_LOG(_L("Updating of IPsec SAs completed")); + iActivated = ETrue; + TVPNAddress dummyVirtualIp; + IkeSaCompleted(KErrNone,dummyVirtualIp); + } + break; + case SADB_ACQUIRE: + if ( iClientStatusDelete != NULL ) + { + DEBUG_LOG(_L("Acquire ignored because of ongoing deactivation.")); + return; + } + if (iFirstIkev2SA != NULL) + { + Ikev2SAdata = &(iFirstIkev2SA->iIkeV2SaData); + } + if ( Ikev2SAdata ) + { + DEBUG_LOG(_L("Found IKE SA for the acquire")); + // + // An IKE SA found for Acquire. Get a negotiation + // object for IKE Child SA exchange + // + Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, + iEventLogger, *iMessageSendQue, + iDebug,*Ikev2SAdata); + CleanupStack::PushL(Negotiation); + CleanUpUsed = ETrue; + } + else + { + DEBUG_LOG(_L("No IKE SA for the Acquire. Creating new.")); + // + // No IKE SA found for Acquire not ongoing + // negotiation found for defined destination + // address. + // We shall start a new IKE SA negotiation to + // defined destination address. Find first the IKE + // policy for that destination address. + // + TInetAddr localAddr; + this->iDataInterface.GetLocalAddress(localAddr); + Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, iEventLogger, + *iMessageSendQue, iDebug, iIkeData, + iVpnIapId, GetSAId(), + localAddr, + *(aPfkeyMessage.iDstAddr.iAddr)); + CleanupStack::PushL(Negotiation); + CleanUpUsed = ETrue; + } + Negotiation->ProcessAcquireL(aPfkeyMessage); + if ( CleanUpUsed ) + CleanupStack::Pop(Negotiation); + if ( Negotiation->Stopped() ) + delete Negotiation; + break; + + case SADB_EXPIRE: + if (aPfkeyMessage.iSoft.iExt) + { + // + // An IPSEC SA soft lifetime has expired. + // + // Try to find an existing IKE SA with remote address + // + if (iFirstIkev2SA != NULL) + { + Ikev2SAdata = &(iFirstIkev2SA->iIkeV2SaData); + } + if ( Ikev2SAdata ) + { + // + // An IKE SA found for soft expire. Get a negotiation + // object for IKE Child SA exchange + // + Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, iEventLogger, + *iMessageSendQue, iDebug, *Ikev2SAdata); + CleanupStack::PushL(Negotiation); + DEBUG_LOG(_L("IKE SA found for soft expire IP.")); + + Negotiation->StartIpsecSaRekeyingL(aPfkeyMessage); + CleanupStack::Pop(Negotiation); + if ( Negotiation->Stopped() ) + delete Negotiation; + } + else + { + DEBUG_LOG(_L("No IKE SA found for soft expire IP")); + } + } + else + { + // + // An IPSEC SA has been expired. + // Try to find an existing IKE SA with remote address + // + if (iFirstIkev2SA != NULL) + { + Ikev2SAdata = &(iFirstIkev2SA->iIkeV2SaData); + } + if ( Ikev2SAdata ) + { + // + // An IKE SA found for Expire. Get a negotiation + // object for IKE Informational exchange + // + Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, iEventLogger, + *iMessageSendQue, iDebug, *Ikev2SAdata); + CleanupStack::PushL(Negotiation); + DEBUG_LOG(_L("IKE SA found for Expire IP")); + + Negotiation->ProcessExpireL(aPfkeyMessage); + CleanupStack::Pop(Negotiation); + if ( Negotiation->Stopped() ) + delete Negotiation; + } + else + { + DEBUG_LOG(_L("No IKE SA found Expire IP")); + } + } + break; + } + default: + break; + } + } + +TBool CIkev2PluginSession::MatchDestinationAddress( const TInetAddr& aDestAddr ) const + { + TBool match( EFalse ); + + if ( iIkeData ) + { + match = iIkeData->iAddr.Match( aDestAddr ); + } + return match; + } + +void CIkev2PluginSession::DeactivationTimeout() + { + IkeSaDeleted(KErrTimedOut); + } + +// --------------------------------------------------------------------------- +// Handles completion of client's negotiate request. +// --------------------------------------------------------------------------- +// +void CIkev2PluginSession::DoCompleteNegotiateWithHost( TInt aStatus ) + { + if ( aStatus != KErrNone ) + { + DoCancelActiveOperations(); + } + else + { + iActivated = ETrue; + } + + User::RequestComplete( iClientStatusNegotiate, aStatus ); + } + +// --------------------------------------------------------------------------- +// Handles completion of client's delete session request. +// --------------------------------------------------------------------------- +// +void CIkev2PluginSession::DoCompleteDeleteSession( TInt aStatus ) + { + delete iIkeData; + iIkeData = NULL; + delete iDeactivationTimer; + iDeactivationTimer = NULL; + + if ( aStatus != KErrCancel ) + { + DoCancelActiveOperations(); + } + User::RequestComplete( iClientStatusDelete, aStatus ); + } + +// --------------------------------------------------------------------------- +// Handles completion of client's notify error request. +// --------------------------------------------------------------------------- +// +void CIkev2PluginSession::DoCompleteNotifyError( TInt aStatus ) + { + if ( aStatus != KErrCancel ) + { + DoCancelActiveOperations(); + } + User::RequestComplete( iClientStatusNotifyError, aStatus ); + } + +// --------------------------------------------------------------------------- +// Cancels active operations. +// --------------------------------------------------------------------------- +// +void CIkev2PluginSession::DoCancelActiveOperations() + { + // Cancel active negotiation operations. + CIkev2Negotiation* negotiation = iFirstNegotiation; + while ( negotiation != NULL ) + { + negotiation->CancelOperation(); + negotiation = negotiation->iNext; + } + + // Cancel active IKE SA operations. + CIkev2SA* ikev2Sa = iFirstIkev2SA; + while( ikev2Sa != NULL ) + { + ikev2Sa->Cancel(); + ikev2Sa = ikev2Sa->iNext; + } + + DoCancelDataTransfer(); + } + +// --------------------------------------------------------------------------- +// Cancels data transfer. +// --------------------------------------------------------------------------- +// +void CIkev2PluginSession::DoCancelDataTransfer() + { + if ( iReceiver != NULL ) + { + iReceiver->StopReceive(); + } + if ( iMessageSendQue != NULL ) + { + iMessageSendQue->Cancel(); + iMessageSendQue->CancelAll(); + } + } diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2proposal.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2proposal.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,788 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 Proposal handling. +* +*/ + + +#include +#include +#include "ikedebug.h" +#include "ikev2proposal.h" +#include "ikev2SAdata.h" +#include "ikev2payloads.h" +#include "ikemsgrec.h" +#include "ikev2const.h" +#include "ikev2plugin.h" +#include "ikepolparser.h" +#include "ikev2identity.h" +#include "ikev2ipsecsadata.h" +#include "ikev2Negotiation.h" +#include + +HBufC8* Ikev2Proposal::FromPolicyToProposaL(TIkev2SAData& aIkeSaData, + const TDesC8& aRekeySpi, + TInt aDHGroupGuess, + TBool aRekey) +{ + // + // Build IKE SA proposal from IKE policy data + // Because proposal information is presented as "IKEv1" + // proposals in policy these are presented as sequence of + // proposals. All these transforms contains 4 different type transform + // payloads. + // + TProposalData* PropList = aIkeSaData.iIkeData->iPropList; + + if ( !aRekey ) + { + aIkeSaData.iEAPType = aIkeSaData.iIkeData->iEAPProtocol; + } + + if (!PropList) + { + User::LeaveIfNull(PropList); + } + + HBufC8* saData = HBufC8::NewL(512); //512 should be enough for all Proposals + + TUint8 PropNum = 1; + TUint16 SaLth = 0; + TUint16 PropLth; + TUint16 TranLth; + TUint16 PRF; + TUint16 DHGroup; + + TProposalIkev2* Proposal = TProposalIkev2::Cast(saData->Ptr()); + TProposalIkev2* Next = Proposal; + TTransformIkev2* Transform; + TDataAttributes* Attributes; + + while ( PropList ) + { + + Proposal = Next; + TPayloadIkev2::Cast(Proposal)->Init(); // Initialize Payload general header + TPayloadIkev2::Cast(Proposal)->SetNextPayload(IKEV2_PAYLOAD_PROP); + Proposal->SetNum(PropNum); + Proposal->SetProtocol(IKEV2_PROTOCOL); + if ( aRekey ) + { + Proposal->SetSPISize(IKEV2_SPI_SIZE); + Mem::Copy(Proposal->SPI(), aRekeySpi.Ptr(), IKEV2_SPI_SIZE); + } + else Proposal->SetSPISize(0); + Proposal->SetNumTrans(4); + PropLth = (TUint16)Proposal->PropHdrLth(); + + Transform = Proposal->TransformPl(); + TPayloadIkev2::Cast(Transform)->Init(); // Initialize Payload general header + TPayloadIkev2::Cast(Transform)->SetNextPayload(IKEV2_PAYLOAD_TRANS); + Transform->SetType(IKEV2_ENCR); // Encryption Algorithm transform (1) + Transform->SetReserved(); + TranLth = (TUint16)Transform->Size(); + + switch ( PropList->iEncrAlg ) + { + case IKE_PARSER_DES_CBC: + Transform->SetID(ENCR_DES); + break; + case IKE_PARSER_DES3_CBC: + Transform->SetID(ENCR_3DES); + break; + case IKE_PARSER_AES_CBC: + Transform->SetID(ENCR_AES_CBC); + // + // Add key length attribute to transform data + // + Transform->SetID(ENCR_AES_CBC); + Attributes = Transform->Attributes(); + Attributes->SetType(IKEV2_ENCR_KEY_LTH); + Attributes->SetBasic(); + if (PropList->iEncrKeyLth) + Attributes->SetValue((TUint16)PropList->iEncrKeyLth); + else Attributes->SetValue(128); //default AES key size + TranLth = (TUint16)(TranLth + Attributes->Size()); + break; + default: + Transform->SetID(ENCR_3DES); // Use 3DES as default + break; + } + TPayloadIkev2::Cast(Transform)->SetLength(TranLth); + PropLth = (TUint16)(PropLth + TranLth); + + Transform = (TTransformIkev2*)TPayloadIkev2::Cast(Transform)->Next(); + TPayloadIkev2::Cast(Transform)->Init(); // Initialize Payload general header + TPayloadIkev2::Cast(Transform)->SetNextPayload(IKEV2_PAYLOAD_TRANS); + Transform->SetType(IKEV2_INTEG); // Integrity Algorithm (3) + Transform->SetReserved(); + TranLth = (TUint16)Transform->Size(); + + switch ( PropList->iHashAlg ) + { + case IKE_PARSER_MD5: + Transform->SetID(AUTH_HMAC_MD5_96); + PRF = IKE_PARSER_MD5; + break; + case IKE_PARSER_SHA1: + Transform->SetID(AUTH_HMAC_SHA1_96); + PRF = IKE_PARSER_SHA1; + break; + default: + Transform->SetID(AUTH_HMAC_SHA1_96); + PRF = IKE_PARSER_SHA1; + break; + } + TPayloadIkev2::Cast(Transform)->SetLength(TranLth); + PropLth = (TUint16)(PropLth + TranLth); + + Transform = (TTransformIkev2*)TPayloadIkev2::Cast(Transform)->Next(); + TPayloadIkev2::Cast(Transform)->Init(); // Initialize Payload general header + TPayloadIkev2::Cast(Transform)->SetNextPayload(IKEV2_PAYLOAD_TRANS); + Transform->SetType(IKEV2_PRF); // Pseudo-random Function (2) + Transform->SetReserved(); + TranLth = (TUint16)Transform->Size(); + + if ( PropList->iPRF ) + PRF = PropList->iPRF; + switch ( PRF ) + { + case IKE_PARSER_MD5: + Transform->SetID(PRF_HMAC_MD5); + break; + case IKE_PARSER_SHA1: + Transform->SetID(PRF_HMAC_SHA1); + break; + default: + Transform->SetID(AUTH_HMAC_SHA1_96); + break; + } + TPayloadIkev2::Cast(Transform)->SetLength(TranLth); + PropLth = (TUint16)(PropLth + TranLth); + + + Transform = (TTransformIkev2*)TPayloadIkev2::Cast(Transform)->Next(); + TPayloadIkev2::Cast(Transform)->Init(); // Initialize Payload general header + TPayloadIkev2::Cast(Transform)->SetNextPayload(IKEV2_PAYLOAD_NONE); + Transform->SetType(IKEV2_DH); // Diffie-Hellman Group (4) + Transform->SetReserved(); + TranLth = (TUint16)Transform->Size(); + + + DHGroup = (PropList->iGroupDesc == 0) ? aIkeSaData.iIkeData->iGroupDesc_II : + PropList->iGroupDesc; + + DHGroup = Ikev2Proposal::GetDHGroup(DHGroup); + Transform->SetID(DHGroup); + TPayloadIkev2::Cast(Transform)->SetLength(TranLth); + + if ( PropNum == aDHGroupGuess) + { + if (aIkeSaData.iDHGroup == 0) + aIkeSaData.iDHGroup = DHGroup; // Preferred group for initial KE payload + switch ( PropList->iAuthMeth ) + { + case IKE_PARSER_DSS_SIG: + aIkeSaData.iAuthMethod = DSS_DIGITAL_SIGN; + break; + + case IKE_PARSER_RSA_SIG: + case IKE_PARSER_RSA_REV_ENCR: + aIkeSaData.iAuthMethod = RSA_DIGITAL_SIGN; + break; + + default: + aIkeSaData.iAuthMethod = PRESHARED_KEY; + break; + + } + } + + if ( aIkeSaData.iLifetime == 0 ) + aIkeSaData.iLifetime = PropList->iLifetimeSec; // Init lifetime + else if ( PropList->iLifetimeSec && (aIkeSaData.iLifetime > PropList->iLifetimeSec) ) + aIkeSaData.iLifetime = PropList->iLifetimeSec; // Take shorter time + + PropLth = (TUint16)(PropLth + TranLth); + SaLth = (TUint16)(SaLth + PropLth); + TPayloadIkev2::Cast(Proposal)->SetLength(PropLth); + + PropNum ++; + Next = (TProposalIkev2*)TPayloadIkev2::Cast(Proposal)->Next(); + PropList = PropList->iNext; + } + + if ( aIkeSaData.iLifetime == 0 ) + aIkeSaData.iLifetime = IKEV2_DEF_LIFETIME; + TPayloadIkev2::Cast(Proposal)->SetNextPayload(IKEV2_PAYLOAD_NONE); + + saData->Des().SetLength(SaLth); + + return saData; + +} + +HBufC8* Ikev2Proposal::GetPSKFromPolicyL(CIkeData* aHostData) +{ + ASSERT(aHostData); + // + // Get Preshared Key from IKE policy and return in to caller in + // HBufc8. + // + HBufC8 *PSK = NULL; + if ( aHostData->iPresharedKey.iFormat == STRING_KEY ) + { + PSK = HBufC8::NewL(aHostData->iPresharedKey.iKey.Length()); + PSK->Des().Copy(aHostData->iPresharedKey.iKey); + } + else if ( aHostData->iPresharedKey.iFormat == HEX_KEY ) + { + PSK = HBufC8::NewL(aHostData->iPresharedKey.iKey.Length() / 2); + + + for(TInt i = 0; i < aHostData->iPresharedKey.iKey.Length(); i += 2) + { + TPtrC hexByte(aHostData->iPresharedKey.iKey.Mid(i, 2)); + TLex lex(hexByte); + TUint8 value; + User::LeaveIfError(lex.Val(value, EHex)); + + PSK->Des().Append(&value, 1); + } + + } + + return PSK; +} + +TUint16 Ikev2Proposal::GetDHGroup(TInt aDHGroup) +{ + // + // Map DH group Enum value used in IKE policy to the real DH group + // transform type value used in IKEv2 negotiation + // If aDHGroup parameter is not defined mapping is done to + // iGroupDesc_II data member value in CIkeData + // + TUint16 DHTransId = 0; + switch ( aDHGroup ) + { + case IKE_PARSER_MODP_768: + DHTransId = DH_GROUP_768; + break; + case IKE_PARSER_MODP_1024: + DHTransId = DH_GROUP_1024; + break; + case IKE_PARSER_MODP_1536: + DHTransId = DH_GROUP_1536; + break; + case IKE_PARSER_MODP_2048: + DHTransId = DH_GROUP_2048; + break; + default: + break; + } + + return DHTransId; +} + +HBufC8* Ikev2Proposal::BuildSaResponseL(TProposalIkev2* aAcceptedProp, CIkev2Payloads* aAcceptedTrans) +{ + ASSERT(aAcceptedProp && aAcceptedTrans); + HBufC8* SaRespBfr = HBufC8::NewL(256); //256 should be enough response + + // + // Build SA response payload based on Transform payloads which are + // marked to be "SELECTED" in request proposal + // + TProposalIkev2* Proposal = TProposalIkev2::Cast(const_cast(SaRespBfr->Ptr())); + TUint16 PropLth = (TUint16)aAcceptedProp->PropHdrLth(); + Mem::Copy((TUint8*)Proposal, (TUint8*)aAcceptedProp, PropLth); + + TTransformIkev2* Transform = Proposal->TransformPl(); + TTransformIkev2* LastTrans = Transform; + TTransformIkev2* AccTransform; + TUint8 NbrOfTransforms = 0; + TInt TranCount = aAcceptedTrans->iTrans->Count(); + for ( TInt i = 0; i < TranCount; ++i ) + { + AccTransform = (TTransformIkev2*)aAcceptedTrans->iTrans->At(i); + if ( AccTransform->IsSelected() ) + { + NbrOfTransforms ++; + Mem::Copy((TUint8*)Transform, (TUint8*)AccTransform, TPayloadIkev2::Cast(AccTransform)->GetLength()); + Transform->NotSelected(); // Reset selected bit ! + PropLth = (TUint16)(PropLth + TPayloadIkev2::Cast(AccTransform)->GetLength()); + TPayloadIkev2::Cast(Transform)->SetNextPayload(IKEV2_PAYLOAD_TRANS); + LastTrans = Transform; + Transform = (TTransformIkev2*)TPayloadIkev2::Cast(Transform)->Next(); + } + } + TPayloadIkev2::Cast(LastTrans)->SetNextPayload(IKEV2_PAYLOAD_NONE); + TPayloadIkev2::Cast(Proposal)->SetNextPayload(IKEV2_PAYLOAD_NONE); + TPayloadIkev2::Cast(Proposal)->SetLength(PropLth); + Proposal->SetNumTrans(NbrOfTransforms); + SaRespBfr->Des().SetLength(PropLth); + + return SaRespBfr; +} + + +TBool Ikev2Proposal::GetSelectedProposalData(TIkev2SAData& aIkev2SaData, + TIkeV2IpsecSAData& aChildSaData, + const CIkev2Payloads& aAcceptedProp, + const TProposalIkev2& aProp) +{ + // + // Get IKE SA algorithm information from Transform payload which are + // marked to be "SELECTED" + // + TTransformIkev2* Transform; + TDataAttributes* Attribute; + TUint16 EncrAlg; + TInt KeyLth; + TUint8 ExistingTypes = 0; + TUint8 RequiredTypes; + TUint8 Protocol = aProp.GetProtocol(); + switch ( Protocol ) + { + case IKEV2_IPSEC_AH: + { + RequiredTypes = (1 << IKEV2_INTEG); + aChildSaData.iSaType = SADB_SATYPE_AH; + TUint32 spi = 0; + aProp.GetIpsecSPI(&spi); + aChildSaData.iSPI_Out = TPtrC8(reinterpret_cast(&spi), sizeof(spi)); + } + break; + case IKEV2_IPSEC_ESP: + { + RequiredTypes = (1 << IKEV2_ENCR); + aChildSaData.iSaType = SADB_SATYPE_ESP; + TUint32 spi = 0; + aProp.GetIpsecSPI(&spi); + aChildSaData.iSPI_Out = TPtrC8(reinterpret_cast(&spi), sizeof(spi)); + } + break; + default: //IKEV2_PROTOCOL: + RequiredTypes = ((1 << IKEV2_ENCR) | (1 << IKEV2_PRF) | (1 << IKEV2_INTEG) | (1 << IKEV2_DH)); + break; + } + + TInt TranCount = aAcceptedProp.iTrans->Count(); + + for ( TInt i = 0; i < TranCount; ++i ) + { + Transform = (TTransformIkev2*)aAcceptedProp.iTrans->At(i); + if ( Transform->IsSelected() ) + { + Transform->NotSelected(); // Reset private "selected" bit + switch ( Transform->GetType() ) + { + case IKEV2_ENCR: + ExistingTypes |= (1 << IKEV2_ENCR); + EncrAlg = Transform->GetID(); + if ( Protocol == IKEV2_PROTOCOL ) + aIkev2SaData.iEncrAlg = EncrAlg; + else aChildSaData.iEncrAlg = EncrAlg; + if ( EncrAlg == ENCR_AES_CBC ) + { + // + // Get encryption key length from attributes + // (or use default key length 128 bit) + // + if ( TPayloadIkev2::Cast(Transform)->GetLength() > Transform->Size() ) + { + Attribute = Transform->Attributes(); + KeyLth = (Attribute->GetValue() >> 3); // byte length + } + else KeyLth = 16; // default: 16 bytes = 128 bits + if ( Protocol == IKEV2_PROTOCOL ) + aIkev2SaData.iCipherKeyLth = KeyLth; + else aChildSaData.iCipherKeyLth = KeyLth; + } + break; + + case IKEV2_PRF: + ExistingTypes |= (1 << IKEV2_PRF); + if ( Protocol == IKEV2_PROTOCOL ) + aIkev2SaData.iPRFAlg = Transform->GetID(); + break; + + case IKEV2_INTEG: + ExistingTypes |= (1 << IKEV2_INTEG); + if ( Protocol == IKEV2_PROTOCOL ) + aIkev2SaData.iIntegAlg = Transform->GetID(); + else aChildSaData.iIntegAlg = Transform->GetID(); + break; + + case IKEV2_DH: + ExistingTypes |= (1 << IKEV2_DH); + if ( Protocol == IKEV2_PROTOCOL ) + aIkev2SaData.iDHGroup = Transform->GetID(); + break; + + case IKEV2_ESN: + ExistingTypes |= (1 << IKEV2_ESN); + if ( Protocol != IKEV2_PROTOCOL ) + aChildSaData.iESN = (TUint8)Transform->GetID(); + break; + + default: + break; + + } + } + + } + + return ((RequiredTypes & ExistingTypes) == RequiredTypes); +} + +TBool Ikev2Proposal::VerifySaResponseL(TIkev2SAData& aIkeSaData, + TIkeV2IpsecSAData& aIpsecSaData, + const TDesC8& aReferenceSaData, + const CIkev2Payloads& aRespProp) +{ + // + // Verify content of an IKE SA response to proposed IKE SA transform + // list. The IKE SA proposal selected by peer MUST contain one + // proposal and transform selected from our SA proposal + // + if ( aRespProp.iProps->Count() != 1 ) + return EFalse; + + TBool Status = EFalse; + TPtrC8 unprocessedReferenceSaData(aReferenceSaData); + + while(!Status && unprocessedReferenceSaData.Length() > 0) + { + TPayloadIkev2* referenceProposal = TPayloadIkev2::Cast(unprocessedReferenceSaData.Ptr()); + CIkev2Payloads* OwnProp = CIkev2Payloads::NewL(referenceProposal, IKEV2_PAYLOAD_PROP, aIkeSaData); + CleanupStack::PushL(OwnProp); + + //Something is seriously wrong, if we can't parse our own reference data + __ASSERT_DEBUG(OwnProp->Status() == KErrNone, User::Invariant()); + + TProposalIkev2* Prop = (TProposalIkev2*)aRespProp.iProps->At(0); + Status = Ikev2Proposal::VerifyProposaL(OwnProp, Prop, aIkeSaData); + if ( Status ) + { + Status = Ikev2Proposal::GetSelectedProposalData(aIkeSaData, aIpsecSaData, aRespProp, *Prop); + } + CleanupStack::PopAndDestroy(OwnProp); + unprocessedReferenceSaData.Set(unprocessedReferenceSaData.Mid(referenceProposal->GetLength())); + } + + return Status; +} + +TBool Ikev2Proposal::VerifySaRequestAndGetProposedSaBufferL(TIkev2SAData& aIkeSaData, + TIkeV2IpsecSAData& aIpsecSaData, + const TDesC8& aReferenceSaData, + const CIkev2Payloads& aProposed, + HBufC8*& aProposedSaBuffer) +{ + __ASSERT_DEBUG(aReferenceSaData.Length() > 0, User::Invariant()); + + + // + // Verify content of an IKE SA request against a reference + // proposals built according to the local policy. + // + if ( !aProposed.iSa ) + return EFalse; + + TBool Status = EFalse; + TPtrC8 unprocessedReferenceSaData(aReferenceSaData); + while (!Status && unprocessedReferenceSaData.Length() > 0) + { + TPayloadIkev2* referenceSa = TPayloadIkev2::Cast(unprocessedReferenceSaData.Ptr()); + unprocessedReferenceSaData.Set(unprocessedReferenceSaData.Mid(referenceSa->GetLength())); + CIkev2Payloads* OwnProp = CIkev2Payloads::NewL(referenceSa, IKEV2_PAYLOAD_PROP, aIkeSaData); + //If we can't parse our own reference proposal something is seriously wrong. + __ASSERT_DEBUG(OwnProp->Status() == KErrNone, User::Invariant()); + CleanupStack::PushL(OwnProp); + + + CIkev2Payloads* PeerProp = CIkev2Payloads::NewL((TPayloadIkev2*)aProposed.iSa, IKEV2_PAYLOAD_SA, aIkeSaData); + CleanupStack::PushL(PeerProp); + Status = (PeerProp->Status() == KErrNone); + if ( Status ) + { + Status = EFalse; + TInt PropCount = PeerProp->iProps->Count(); + for ( TInt i = 0; i < PropCount; ++i ) + { + TProposalIkev2* Prop = (TProposalIkev2*)PeerProp->iProps->At(i); + Status = Ikev2Proposal::VerifyProposaL(OwnProp, Prop, aIkeSaData); + if ( Status ) + { + // + // Build SA response payload and pick up algorithm + // information into negotiation object + // + + HBufC8* SaRespBfr = NULL; + TRAPD(err, SaRespBfr = Ikev2Proposal::BuildSaResponseL(Prop, PeerProp)); + if (err == KErrNone) + { + aProposedSaBuffer = SaRespBfr; + Status = Ikev2Proposal::GetSelectedProposalData(aIkeSaData, aIpsecSaData, *PeerProp, *Prop); + } + else + { + Status = EFalse; + } + break; + } + } + } + CleanupStack::PopAndDestroy(PeerProp); + CleanupStack::PopAndDestroy(OwnProp); + } + return Status; +} + +TBool Ikev2Proposal::IkeSaRekey(CIkev2Payloads* aIkeMsg) +{ + ASSERT(aIkeMsg); + // + // Check is the current IKE message an IKE SA rekey request + // Should be format: HDR(A,B), SK { SA, Ni, KEi } + // where proposal protcol should be IKEV2_PROTOCOL + // + TBool Status = EFalse; + if ( aIkeMsg->iProps->Count() && !aIkeMsg->iTsI && !aIkeMsg->iTsR ) + { + TProposalIkev2* Prop = (TProposalIkev2*)aIkeMsg->iProps->At(0); + Status = (Prop->GetProtocol() == IKEV2_PROTOCOL); + } + return Status; +} + +TBool Ikev2Proposal::GetRekeySpi(CIkev2Payloads* aIkeMsg, TIkeSPI& aSPI) +{ + ASSERT(aIkeMsg); + // + // Get remote ends IKE SPI from the first Proposal of IKE message + // + TBool Status = EFalse; + if ( aIkeMsg->iProps->Count() ) + { + TProposalIkev2* Proposal = (TProposalIkev2*)aIkeMsg->iProps->At(0); + if ( Proposal->GetSPISize() == IKEV2_SPI_SIZE ) + { + Mem::Copy( (TUint8*)aSPI.Ptr(), Proposal->SPI(), IKEV2_SPI_SIZE); + Status = ETrue; + } + } + return Status; +} + +void Ikev2Proposal::ChangeSpiInProposal(HBufC8* aSaBfr, TIkeSPI& aSPI) +{ + ASSERT(aSaBfr); + TProposalIkev2* Proposal = TProposalIkev2::Cast(aSaBfr->Ptr()); + Mem::Copy(Proposal->SPI(), (TUint8*)aSPI.Ptr(), IKEV2_SPI_SIZE); +} + +TBool Ikev2Proposal::VerifyProposaL(CIkev2Payloads* aReference, TProposalIkev2* aProposal, TIkev2SAData& aIkev2SaData) +{ + // + // Find a matching proposal for "candidate" from reference payload + // chain. This implementation does not support the AND of sequental + // proposals (for example proposal which defines (ESP and AH)) + // + if ( !aProposal || !aReference || (aReference->iProps->Count() == 0) ) + return EFalse; + + CIkev2Payloads* Prop = CIkev2Payloads::NewL(TPayloadIkev2::Cast(aProposal), IKEV2_PAYLOAD_PROP, aIkev2SaData); + CleanupStack::PushL(Prop); + TBool Status = ( Prop->Status() == KErrNone ); + if ( Status ) + { + + Status = EFalse; + TInt PropCount = aReference->iProps->Count(); + TProposalIkev2* RefProp; + + for ( TInt i = 0; i < PropCount; ++i ) + { + RefProp = (TProposalIkev2*)aReference->iProps->At(i); + if ( !aReference->ParsePayloadL(TPayloadIkev2::Cast(RefProp), IKEV2_PAYLOAD_PROP ))// Transforms from Proposal + break; + if ( aReference->iTrans->Count() == 0 ) + break; + if ( RefProp->GetProtocol() != aProposal->GetProtocol() ) + continue; + // + // Compare transforms within proposals + // + Status = Ikev2Proposal::CompareTransforms(aReference->iTrans, Prop->iTrans); + if ( Status ) + break; // Match found + } + } + CleanupStack::PopAndDestroy(Prop); + + return Status; +} + +TBool Ikev2Proposal::CompareTransforms(CArrayFixFlat* aRefTrans, + CArrayFixFlat* aTrans) +{ + ASSERT(aTrans && aRefTrans); + // + // "Select" matching transforms from transform list (aTrans). + // Transforms from aTrans array is marked "SELECTED" if there is a + // matching transform in aRefTrans array for existing transform + // types. + // + TUint8 TransType; + TTransformIkev2* Trans; + TTransformIkev2* RefTrans; + TDataAttributes* Attribute; + + TInt TranCount2; + TUint16 Lth; + TUint8 ExistingTypes = 0; + TUint8 MatchingTypes = 0; + TInt TranCount = aTrans->Count(); + TInt i; + + for ( i = 0; i < TranCount; ++i ) + { + Trans = aTrans->At(i); + TransType = Trans->GetType(); + if ( (TransType < IKEV2_ENCR ) || (TransType > IKEV2_ESN) ) + break; // Unknown transform type (error) + + ExistingTypes |= (1 << TransType); + TranCount2 = aRefTrans->Count(); + + for ( TInt j = 0; j < TranCount2; ++j ) + { + RefTrans = aRefTrans->At(j); + + if ( (TransType != RefTrans->GetType()) || (Trans->GetID() != RefTrans->GetID()) ) + continue; + // + // Matching transform type and ID. Check is there any + // attributes in transform (in this phase only IKEV2_ENCR + // transform type can contain an attribute AES key length) + // + Lth = TPayloadIkev2::Cast(Trans)->GetLength(); + if ( Lth >= Trans->Size() ) + { + if (( TransType == IKEV2_ENCR ) && (Trans->GetID() == ENCR_AES_CBC) ) + { + TUint16 KeyLth = 128; + TUint16 RefKeyLth = 128; + if ( Lth > Trans->Size() ) + { + Attribute = Trans->Attributes(); + Lth = (TUint16)(Lth - Trans->Size()); + if ( (Lth == Attribute->Size()) && Attribute->IsBasic() && (Attribute->GetType() == IKEV2_ENCR_KEY_LTH) ) + KeyLth = Attribute->GetValue(); + } + if ( TPayloadIkev2::Cast(RefTrans)->GetLength() > Trans->Size() ) + { + Attribute = RefTrans->Attributes(); + RefKeyLth = Attribute->GetValue(); + } + if ( KeyLth != RefKeyLth ) + continue; // Not matching attribute + } + } + // + // Mark current transform "SELECTED" + // + if ( (MatchingTypes & (1 << TransType) ) == 0 ) + { + Trans->Selected(); + MatchingTypes |= (1 << TransType); + } + break; + } + } + + TBool Status = (ExistingTypes == MatchingTypes); + if ( !Status ) + { + // + // No match ! Reset "SELECTED" indicator from transforms + // + i = 0; + while ( i < TranCount ) + { + Trans = (TTransformIkev2*)aTrans->At(i); + Trans->NotSelected(); + i ++; + } + } + + return Status; + +} + +CIkeV2Identity* Ikev2Proposal::GetRemoteIdentityL(CIkeData* aHostData) +{ + ASSERT(aHostData); + CIkeV2Identity* identity = NULL; + + if ( aHostData->iRemoteIdentity ) + { + TPtrC16 idData = aHostData->iRemoteIdentity->GetData(); + TUint8 idType = aHostData->iRemoteIdType; + if ( (idType == ID_IPV4_ADDR) || (idType == ID_IPV6_ADDR) ) + { + // + // If configured remote id type is either IPv4- or IPv6 address + // convert ASCII format address data into hexa octet string IP + // address format: IPv4 address shall be represented as four + // octet string and Ipv6 address as 16 octet string + // + TInetAddr ipAddr; + if ( ipAddr.Input(idData) == KErrNone ) + { + if ( idType == ID_IPV4_ADDR ) + { + TUint32 ipv4 = ByteOrder::Swap32(ipAddr.Address()); + TPtrC8 ipv4Ptr(reinterpret_cast(&ipv4), sizeof(ipv4)); + identity = CIkeV2Identity::NewL(idType, ipv4Ptr); + } + else + { + TPtrC8 IPv6Ptr(&ipAddr.Ip6Address().u.iAddr8[0], 16); + identity = CIkeV2Identity::NewL(idType, IPv6Ptr); + } + } + } + else + { + if ( (idType != ID_FQDN) && (idType != ID_RFC822_ADDR) ) + { + idType = ID_FQDN; // Default + } + + HBufC8* id = HBufC8::NewLC(idData.Length()); + TPtr8 idPtr(id->Des()); + idPtr.Copy(idData); + identity = CIkeV2Identity::NewL(idType, *id); + CleanupStack::PopAndDestroy(id); + } + } + + return identity; +} diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2receiver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2receiver.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,165 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Receiver of UDP datagrams +* +*/ + + +#include + +#include "ikedatainterface.h" +#include "ikemsgheader.h" + +// CLASS HEADER +#include "ikev2receiver.h" + + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CIkev2Receiver* CIkev2Receiver::NewL( MIkeDataInterface& aDataInterface, + MIkev2ReceiverCallback& aCallback ) + { + CIkev2Receiver* self = new (ELeave) CIkev2Receiver( aDataInterface, + aCallback ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CIkev2Receiver::~CIkev2Receiver() + { + StopReceive(); + + delete iUdpData; + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CIkev2Receiver::CIkev2Receiver( MIkeDataInterface& aDataInterface, + MIkev2ReceiverCallback& aCallback ) + : CActive( EPriorityStandard ), + iUdpData( NULL ), + iDataInterface( aDataInterface ), + iCallback( aCallback ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CIkev2Receiver::ConstructL() + { + StartReceive(); + } + +// --------------------------------------------------------------------------- +// Starts receive. +// --------------------------------------------------------------------------- +// +void CIkev2Receiver::StartReceive() + { + iReceivingData = ETrue; + DoReceive(); + } + +// --------------------------------------------------------------------------- +// Stops receive. +// --------------------------------------------------------------------------- +// +void CIkev2Receiver::StopReceive() + { + iReceivingData = EFalse; + Cancel(); + iDataInterface.StopReceive(); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles completion of receive. +// --------------------------------------------------------------------------- +// +void CIkev2Receiver::RunL() + { + if ( iStatus.Int() == KErrNone ) + { + __ASSERT_DEBUG( iUdpData != NULL, + User::Invariant() ); + + const ThdrISAKMP* ikeHdr = ThdrISAKMP::Ptr( iUdpData->Des() ); + TInt msgLth = iUdpData->Length(); + + // Ignore possible in the beginning of IKE message. + TUint32 ikeMsgHdrOctets = GET32( ikeHdr ); + if ( ikeMsgHdrOctets == NON_ESP_MARKER ) + { + ikeHdr = ikeHdr->GotoOffset( NON_ESP_MARKER_SIZE ); + msgLth -= NON_ESP_MARKER_SIZE; + } + + iCallback.IkeMsgReceived( *ikeHdr, iSrcAddr, iLocalPort ); + } + + delete iUdpData; + iUdpData = NULL; + + if ( iStatus.Int() == KErrNone ) + { + if ( iReceivingData ) + { + // Continue receiving. + DoReceive(); + } + } + else + { + iCallback.ReceiveError( iStatus.Int() ); + } + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles cancellation of receive. +// --------------------------------------------------------------------------- +// +void CIkev2Receiver::DoCancel() + { + iDataInterface.CancelReceive(); + + delete iUdpData; + iUdpData = NULL; + } + +// --------------------------------------------------------------------------- +// Receives UDP data. +// --------------------------------------------------------------------------- +// +void CIkev2Receiver::DoReceive() + { + iDataInterface.ReceiveUdpData( iUdpData, iSrcAddr, iLocalPort, iStatus ); + SetActive(); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2retransmittimer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2retransmittimer.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Timer to tricket IKE datagram resend, if do not obtain a reply +* +*/ + +#include "ikev2retransmittimer.h" + +//The actual time out value is calculated: +//timeout = send_attempt * KRetryTimeOutBaseMicroSeconds; +//So the time out value increases by geometric serie, +//not exponenially like recommended by the RFC +static const TUint KRetryTimeOutBaseMicroSeconds = 1 * 1000000; //microseconds + + +CIkev2RetransmitTimer* CIkev2RetransmitTimer::NewL( MIkev2RetransmitTimerCallback& aCallback ) + { + CIkev2RetransmitTimer* self = new (ELeave) CIkev2RetransmitTimer( aCallback ); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CIkev2RetransmitTimer::CIkev2RetransmitTimer( MIkev2RetransmitTimerCallback& aCallback ) + : CTimer(EPriorityStandard), + iCallback(aCallback) + { + CActiveScheduler::Add(this); + } + +CIkev2RetransmitTimer::~CIkev2RetransmitTimer() + { + Cancel(); + } + +void CIkev2RetransmitTimer::IssueRequest( TUint16 aSendAttempt ) + { + TTimeIntervalMicroSeconds32 interval = (aSendAttempt * KRetryTimeOutBaseMicroSeconds); + After(interval); + } + +void CIkev2RetransmitTimer::RunL() + { + iCallback.RetransmitRequest(); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2sa.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2sa.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,293 @@ +/* +* Copyright (c) 2003-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 SA +* +*/ + + +#include "ikedebug.h" +#include "ikev2SA.h" +#include "ikepolparser.h" +#include "ikev2ipsecsadata.h" +#include "ikev2pluginsession.h" + +CIkev2SA* CIkev2SA::NewL(CIkev2PluginSession& aIkeV2PluginSession, TIkev2SAData& aIkev2SAdata, MIkeDebug& aDebug) +{ + CIkev2SA *sa = new (ELeave) CIkev2SA(aIkeV2PluginSession, aDebug); + sa->ConstructL(aIkev2SAdata); + return sa; +} + + +CIkev2SA::CIkev2SA(CIkev2PluginSession& aIkeV2PluginSession, MIkeDebug& aDebug) +:CTimer(EPriorityStandard), iIkeV2PluginSession(aIkeV2PluginSession), iDebug(aDebug) +{ + CActiveScheduler::Add(this); +} + + +void CIkev2SA::ConstructL(TIkev2SAData& aIkev2SAdata) +{ + CTimer::ConstructL(); + iIkeV2SaData.Copy(aIkev2SAdata); + // + // Calculate lifetime value for the new IKE SA + // The jitter value is adjusted from SA internal ID (SAId mod 8) + // + iRemainingTime = iIkeV2SaData.iLifetime + (iIkeV2SaData.SaId() % 8); + iIkeV2SaData.iSAState = KSaStateReady; + + TInt DPDHeartbeat = 0; + if ( iIkeV2SaData.iIkeData->iDPDHeartBeat ) + DPDHeartbeat = iIkeV2SaData.iIkeData->iDPDHeartBeat; + + if ( DPDHeartbeat ) + { + iIkeKeepAlive = CIkeV2KeepAlive::NewL(DPDHeartbeat, *this); + } + + DEBUG_LOG2(_L("IKEv2 SA constructed, SAId: %d, Lifetime: %d"), iIkeV2SaData.SaId(), iRemainingTime); + + StartTimer(); +} + + +CIkev2SA::~CIkev2SA() +{ + if (IsActive()) + Cancel(); + PurgeIpsecDataQue(); + iIkeV2SaData.CleanUp(); + delete iIkeKeepAlive; +} + + +void CIkev2SA::DoCancel() +{ + CTimer::DoCancel(); +} + +void CIkev2SA::UpdateL(TIkev2SAData* aIkev2SAdata, TIkeV2IpsecSAData* aIpsecSAdata) +{ + DEBUG_LOG(_L("CIkev2SA::UpdateL")); + + if ( aIkev2SAdata ) + { + // + // Update IKE Sa data information and reset/restart IKE SA lifetime + // + iIkeV2SaData.Copy(*aIkev2SAdata); + iIkeV2SaData.iSAState = KSaStateReady; + } + if ( aIpsecSAdata ) + { + // + // Link an Ipsec SA pair information into IKE SA + // + TIkeV2IpsecSAData* IpsecSA = new (ELeave) TIkeV2IpsecSAData(iDebug); + IpsecSA->Copy(*aIpsecSAdata); + LinkIpsecSa(IpsecSA); + DEBUG_LOG3(_L("Ipsec SA added into IKE SA, SAId: %d, In SPI: %d, Out SPI: %d"), + iIkeV2SaData.SaId(), &aIpsecSAdata->iSPI_In, &aIpsecSAdata->iSPI_Out); + } +} + +TBool CIkev2SA::RemoteAddrChanged(TInetAddr& aNewIp) +{ + +#if __DEBUG + TBuf<40> txt_addr; + aNewIp.OutputWithScope(txt_addr); + DEBUG_LOG2(_L("Remote IP changed IKE SA: %d, new address %S"), iIkeV2SaData.SaId(), &txt_addr); +#endif //__DEBUG + aNewIp = aNewIp; //To silence UREL warnings: contents of DEB macro invisible in UREL builds + + return ETrue; +} + + +TIkeV2IpsecSAData* CIkev2SA::RemoveIpsecSaData(const TDesC8& aInSpi, const TDesC8& aOutSpi) +{ + return FindIpsecSaData(aInSpi, aOutSpi, ETrue); +} + + +TIkeV2IpsecSAData* CIkev2SA::FindIpsecSaData(const TDesC8& aInSpi, const TDesC8& aOutSpi, TBool aRemove) +{ + + __ASSERT_DEBUG( aInSpi.Length() == 4 || aInSpi.Length() == 0, User::Invariant() ); + __ASSERT_DEBUG( aOutSpi.Length() == 4 || aOutSpi.Length() == 0, User::Invariant() ); + __ASSERT_DEBUG( aInSpi.Length() != 0 || aOutSpi.Length() != 0, User::Invariant() ); + + TInt Found = 0; + if ( aInSpi.Length() > 0 ) + Found ++; + if ( aOutSpi.Length() > 0 ) + Found ++; + if ( Found == 0 ) + return NULL; + + TInt Match; + TIkeV2IpsecSAData* Prev = NULL; + TIkeV2IpsecSAData* Sa = iIpsecSaQue; + + while ( Sa ) + { + Match = 0; + if ( aInSpi.Length() > 0 && (aInSpi.Compare(Sa->iSPI_In) == 0)) + Match ++; + if ( aOutSpi.Length() > 0 && (aOutSpi.Compare(Sa->iSPI_Out) == 0) ) + Match ++; + if ( Match == Found ) + { + if ( aRemove ) + { + if ( Prev ) + Prev->iNext = Sa->iNext; + else iIpsecSaQue = Sa->iNext; + } + break; + } + Prev = Sa; + Sa = Sa->iNext; + } + return Sa; +} + +void CIkev2SA::DeleteIpsecSaData(const TDesC8& aInSpi, const TDesC8& aOutSpi) +{ + TIkeV2IpsecSAData* SaData = FindIpsecSaData(aInSpi, aOutSpi, ETrue); + if ( SaData ) + { + SaData->PurgeKeyMaterial(); + SaData->DeleteRekeyData(); + DeleteIpsecSas(SaData); + delete SaData; + } +} + +void CIkev2SA::LinkIpsecSa(TIkeV2IpsecSAData* aSa) +{ + ASSERT(aSa); + aSa->iNext = iIpsecSaQue; + iIpsecSaQue = aSa; +} + +void CIkev2SA::PurgeIpsecDataQue() +{ + + TIkeV2IpsecSAData* Sa = iIpsecSaQue; + while ( iIpsecSaQue ) + { + iIpsecSaQue = Sa->iNext; + Sa->PurgeKeyMaterial(); + Sa->DeleteRekeyData(); + DeleteIpsecSas(Sa); + delete Sa; + Sa = iIpsecSaQue; + } +} + +void CIkev2SA::DeleteIpsecSas(TIkeV2IpsecSAData* aSa) +{ + ASSERT(aSa); + TInetAddr LocalAddr; + if ( aSa->iSrcSpecific ) + LocalAddr = iIkeV2SaData.iLocalAddr; + else LocalAddr.Init(0); + LocalAddr.SetPort(0); + TInetAddr RemoteAddr = iIkeV2SaData.iRemoteAddr; + RemoteAddr.SetPort(0); + if ( aSa->iSPI_In.Length() > 0 ) + { + TUint32 spi; + TPtr8 spiPtr(reinterpret_cast(&spi), sizeof(spi)); + spiPtr = aSa->iSPI_In; + iIkeV2PluginSession.DeleteIpsecSA(spi, RemoteAddr, LocalAddr, aSa->iSaType); + } + if ( aSa->iSPI_Out.Length() > 0 ) + { + TUint32 spi; + TPtr8 spiPtr(reinterpret_cast(&spi), sizeof(spi)); + spiPtr = aSa->iSPI_Out; + iIkeV2PluginSession.DeleteIpsecSA(spi, LocalAddr, RemoteAddr, aSa->iSaType); + } +} + + +void CIkev2SA::RunL() +{ + // + // If IKE SA lifetime expired, delete IKE SA if there is no + // active IPSEC SA:s alive. If there is rekey IKE SA. + // + DEBUG_LOG2(_L("CIkev2SA::RunL, SAId=%d, remaining time=%d"), + iIkeV2SaData.SaId(), iRemainingTime ); + if (iRemainingTime == 0) + { + if ( iIpsecSaQue ) + { + iIkeV2PluginSession.RekeyIkeSAL(&iIkeV2SaData); + } + else + { + iIkeV2PluginSession.DeleteIkeSAL(&iIkeV2SaData, ETrue); // "Normal" close + } + } + else StartTimer(); + +} + +void CIkev2SA::StartTimer() +{ + if (iRemainingTime > KMaxTInt/SECOND) //To avoid overflowing the Timer + { + iRemainingTime -= KMaxTInt/SECOND; + After(KMaxTInt); + } + else //No overflow + { + After(iRemainingTime*SECOND); + iRemainingTime = 0; + } +} + + +void CIkev2SA::EventHandlerL() +{ + // + // The implementation for class MDpdHeartBeatEventHandler virtual function + // This method is called by an CIkeKeepAlive object instance when + // DPD heartbeat timeout has elapsed. + // + iIkeV2PluginSession.KeepAliveIkeSAL(&iIkeV2SaData); +} + + +TIkeV2IpsecSAData* CIkev2SA::GetIpsecSaQue() +{ + TIkeV2IpsecSAData* Que = iIpsecSaQue; + iIpsecSaQue = NULL; + return Que; +} + + +void CIkev2SA::SetIpsecSaQue(TIkeV2IpsecSAData* aQue) +{ + if (aQue != NULL) + { + LinkIpsecSa(aQue); + } +} + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2sadata.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2sadata.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,259 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 SA data definition +* Class TIkev2SAData is the IKEv2 SA parameter definition which +* is used to pass SA information between IKE server and IKEv2 +* plug-in. +* +*/ + +#include "ikev2SAdata.h" +#include "ikecrypto.h" +#include "ikev2const.h" + +TIkev2SAData::TIkev2SAData() +://iSAId(0), + iSPI_I(), + iSPI_R(), + iSAState(0), + iInitiator(EFalse), + iIkeData(NULL), + iVpnIapId(0), + iLocalAddr(), + iVirtualAddr(), + iRemoteAddr(), + iDestinAddr(), + iNATFlags(0), + iFloatedPort(EFalse), + iWindowSize(0), + iRespRetryCount(0), + iEncrAlg(0), + iPRFAlg(0), + iIntegAlg(0), + iDHGroup(0), + iEAPType(0), + iAuthMethod(0), + iLifetime(0), + iCipherKeyLth(0), + iCipherBlkLth(0), + iIntChkSumLth(0), + iMobikeUsed(EFalse) + { + iSPI_I.SetLength(iSPI_I.MaxLength()); + iSPI_I.FillZ(); + + iSPI_R.SetLength(iSPI_R.MaxLength()); + iSPI_R.FillZ(); + } + + +void TIkev2SAData::CleanUp() + { + FreeRespMsg(); + FreeRequestMsg(); + } + + +void TIkev2SAData::FreeRespMsg() + { + delete iLastResponse; + iLastResponse = NULL; + } + + +void TIkev2SAData::FreeRequestMsg() + { + delete iLastRequest; + iLastRequest = NULL; + } + + +void TIkev2SAData::StoreVirtualIp(const TInetAddr& aVirtualAddr) + { + iVirtualAddr = aVirtualAddr; + } + + +void TIkev2SAData::SaveRespMsg(CIkeV2Message* aRespMsg) + { + FreeRespMsg(); + iLastResponse = aRespMsg; + } + + +void TIkev2SAData::SaveRequestMsg(CIkeV2Message* aRequestMsg) + { + FreeRequestMsg(); + iLastRequest = aRequestMsg; + } + + +void TIkev2SAData::Copy(TIkev2SAData& aSrc) + { + TInetAddr savedVirtualAddr = iVirtualAddr; + CIkeV2Message* savedLastResponse = iLastResponse; + CIkeV2Message* savedLastRequest = iLastRequest; + + Mem::Copy((TUint8*)&iSAId, (TUint8*)&aSrc.iSAId, sizeof(TIkev2SAData)); + + if (iLastResponse != NULL) + { + delete savedLastResponse; + aSrc.iLastResponse = NULL; + } + else + { + iLastResponse = savedLastResponse; + } + + if (iLastRequest != NULL) + { + delete savedLastRequest; + aSrc.iLastRequest = NULL; + } + else + { + iLastRequest = savedLastRequest; + } + + if ( iVirtualAddr.IsUnspecified() ) + iVirtualAddr = savedVirtualAddr; + } + + +TUint32 TIkev2SAData::SaId() const + { + return iSAId; + } + + +void TIkev2SAData::SetSaId(TUint32 aSaId) + { + iSAId = aSaId; + } + + +TIkeSPI& TIkev2SAData::SpiI() + { + return iSPI_I; + } + + +void TIkev2SAData::SetSpiI(const TIkeSPI& aSpiI) + { + iSPI_I = aSpiI; + } + + +TIkeSPI& TIkev2SAData::SpiR() + { + return iSPI_R; + } + + +void TIkev2SAData::SetSpiR(const TIkeSPI& aSpiR) +{ + iSPI_R = aSpiR; +} + +void TIkev2SAData::GenerateIkeKeyDerivatesL(const TDesC8& aSKEYSEED,TUint16 aPrfAlg, + const TDesC8& aNonceI, const TDesC8& aNonceR) +{ + // + // Generate IKE keying information from SKEYDSEED (its + // derivates). + // SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr + // = prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr ) + // Since the amount of keying material needed may be greater than + // the size of the output of the prf algorithm prf+ is used as + // follows prf+ (SKEYSEED,S) = T1 | T2 | T3 | T4 | ... + // where: T1 = prf (SKEYSEED, S | 0x01) + // T2 = prf (SKEYSEED, T1 | S | 0x02) .. + // TN = prf (SKEYSEED, TN-1 | S | 0xN ) ;[ N < 256 ] + // Calculate first required key material length: + // Length of SK_d = Length of PRF algorithm output + // Length of SK_ai and SK_ar = Length of integrity algorithm key + // Length of SK_ei and SK_er = Length of cipher algorithm key + // Length of SK_pi and SK_pr = Length of PRF output + // + TInt EncKeyLth = IkeCrypto::AlgorithmInfo(IKEV2_ENCR, iEncrAlg, &iCipherBlkLth); + if ( iCipherKeyLth == 0 ) + iCipherKeyLth = EncKeyLth; + TInt IntKeyLth = IkeCrypto::AlgorithmInfo(IKEV2_INTEG, iIntegAlg, &iIntChkSumLth); + TInt PrfKeyLth = IkeCrypto::AlgorithmInfo(IKEV2_PRF, iPRFAlg, NULL); + TInt KeyMatLth = 2*iCipherKeyLth + 2*IntKeyLth + 3*PrfKeyLth; + HBufC8* S = HBufC8::NewL(aNonceI.Length() + aNonceR.Length() + 2*IKEV2_SPI_SIZE); + CleanupStack::PushL(S); + // + // Copy value S = (Ni | Nr | SPIi | SPIr) into work buffer S + // + S->Des().Copy(aNonceI); + S->Des().Append(aNonceR); + S->Des().Append(SpiI()); + S->Des().Append(SpiR()); + + HBufC8* KeyMat = IkeCrypto::GenerateKeyingMaterialL(aSKEYSEED, S->Des(), KeyMatLth, aPrfAlg); + // + // Store derived key material into negotiation object in the + // following order: Key material = + // SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr + // + TUint8* KeyMatBfr = (TUint8*)KeyMat->Ptr(); // Keymaterial buffer start + iSK_d.Copy(KeyMatBfr, PrfKeyLth); + KeyMatBfr += PrfKeyLth; + iSK_ai.Copy(KeyMatBfr,IntKeyLth ); + KeyMatBfr += IntKeyLth; + iSK_ar.Copy(KeyMatBfr, IntKeyLth); + KeyMatBfr += IntKeyLth; + iSK_ei.Copy(KeyMatBfr, iCipherKeyLth); + KeyMatBfr += iCipherKeyLth; + iSK_er.Copy(KeyMatBfr, iCipherKeyLth); + KeyMatBfr += iCipherKeyLth; + iSK_pi.Copy(KeyMatBfr,PrfKeyLth ); + KeyMatBfr += PrfKeyLth; + iSK_pr.Copy(KeyMatBfr, PrfKeyLth); + + KeyMat->Des().FillZ(); // Wipe out key material (T1 | T2 | ...) data from buffer + delete KeyMat; + + CleanupStack::PopAndDestroy(); //S +} + + +TUint32 TIkev2SAData::NextRequestId() const +{ + TUint32 msgId = 0; + if(iLastRequest != NULL) + { + msgId = iLastRequest->MessageId() + 1; + } + return msgId; +} + + +TUint32 TIkev2SAData::ExpectedResponseId() const +{ + __ASSERT_DEBUG(iLastRequest != NULL, User::Invariant()); + return iLastRequest->MessageId(); +} + +TUint32 TIkev2SAData::ExpectedRequestId() const +{ + TUint32 msgId = 0; + if(iLastResponse != NULL) + { + msgId = iLastResponse->MessageId() + 1; + } + return msgId; +} diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2sender.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2sender.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,101 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Sender of UDP datagrams +* +*/ + + +#include + +#include "ikedatainterface.h" + +// CLASS HEADER +#include "ikev2sender.h" + + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CIkev2Sender* CIkev2Sender::NewL( MIkeDataInterface& aDataInterface, + MIkev2SenderCallback& aCallback ) + { + CIkev2Sender* self = new (ELeave) CIkev2Sender( aDataInterface, + aCallback ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CIkev2Sender::~CIkev2Sender() + { + Cancel(); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CIkev2Sender::CIkev2Sender( MIkeDataInterface& aDataInterface, + MIkev2SenderCallback& aCallback ) + : CActive( EPriorityStandard ), + iDataInterface( aDataInterface ), + iCallback( aCallback ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------------------------- +// Sends IKE message. +// --------------------------------------------------------------------------- +// +void CIkev2Sender::SendIkeMsg( TInt aLocalPort, + TInetAddr& aDestAddr, + TUint8 aDscp, + const TDesC8& aIkeMsg ) + { + Cancel(); + iDataInterface.SendUdpData( aLocalPort, + aDestAddr, + aIkeMsg, + aDscp, + iStatus ); + SetActive(); + } + + +// --------------------------------------------------------------------------- +// From class CActive +// Handles completion of sending. +// --------------------------------------------------------------------------- +// +void CIkev2Sender::RunL() + { + iCallback.SendIkeMsgCompleted( iStatus.Int() ); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles cancellation of sending. +// --------------------------------------------------------------------------- +// +void CIkev2Sender::DoCancel() + { + iDataInterface.CancelSend(); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2trafficselector.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2trafficselector.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,384 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include "ikev2trafficselector.h" +#include "ikev2const.h" +#include "ikev2payloads.h" + +TIkeV2TrafficSelector* TIkeV2TrafficSelector::NewL(const TDesC8& aIkeV2TrafficSector) + { + static const TUint16 KIpv4SelectorLength = 16; + static const TUint16 KIpv6SelectorLength = 48; + + if (aIkeV2TrafficSector.Length() != KIpv4SelectorLength && + aIkeV2TrafficSector.Length() != KIpv6SelectorLength) + { + User::Leave(KErrArgument); + } + + + const TTrafficSelector* selector = + reinterpret_cast(aIkeV2TrafficSector.Ptr()); + + + TInetAddr startAddr; + TInetAddr endAddr; + + const TUint8* addresses = selector->Addresses(); + if ( selector->Type() == TS_IPV4_ADDR_RANGE ) + { + if (aIkeV2TrafficSector.Length() != KIpv4SelectorLength) + { + User::Leave(KErrArgument); + } + TUint32 startA = *(reinterpret_cast(addresses)); + TUint32 endA = *(reinterpret_cast(addresses + 4)); + + BigEndian::Put32(reinterpret_cast(&startA), startA); + BigEndian::Put32(reinterpret_cast(&endA), endA); + + startAddr.SetAddress(startA); + endAddr.SetAddress(endA); + + } + else + { + if (aIkeV2TrafficSector.Length() != KIpv6SelectorLength || + selector->Type() != TS_IPV6_ADDR_RANGE) + { + User::Leave(KErrArgument); + } + TIp6Addr startA; + TIp6Addr endA; + + Mem::Copy(startA.u.iAddr8, addresses, 16); + Mem::Copy(endA.u.iAddr8, addresses+16, 16); + + startAddr.SetAddress(startA); + endAddr.SetAddress(endA); + } + + TUint16 startPort = selector->StartPort(); + BigEndian::Put16(reinterpret_cast(&startPort), startPort); + startAddr.SetPort(startPort); + + TUint16 endPort = selector->EndPort(); + BigEndian::Put16(reinterpret_cast(&endPort), endPort); + endAddr.SetPort(endPort); + + return new (ELeave) TIkeV2TrafficSelector(startAddr, endAddr, selector->Protocol()); + } + + +TIkeV2TrafficSelector::TIkeV2TrafficSelector(TInetAddr aStartingAddress, TInetAddr aEndingAddress, TUint8 aProtocolId) +:iStartingAddress(aStartingAddress), iEndingAddress(aEndingAddress), iProtocolId(aProtocolId) + { + __ASSERT_DEBUG(iStartingAddress.Family() == iEndingAddress.Family() && + iStartingAddress.IsV4Compat() == iEndingAddress.IsV4Compat() && + iStartingAddress.IsV4Mapped() == iEndingAddress.IsV4Mapped(), User::Invariant()); + + iMask = CalcuateMask(); + } + + +TIkeV2TrafficSelector::TIkeV2TrafficSelector(const TIkeV2TrafficSelector& aTrafficSelector) + { + iStartingAddress = aTrafficSelector.iStartingAddress; + iEndingAddress = aTrafficSelector.iEndingAddress; + + iProtocolId = aTrafficSelector.iProtocolId; + + __ASSERT_DEBUG(iStartingAddress.Family() == iEndingAddress.Family() && + iStartingAddress.IsV4Compat() == iEndingAddress.IsV4Compat() && + iStartingAddress.IsV4Mapped() == iEndingAddress.IsV4Mapped(), User::Invariant()); + iMask = CalcuateMask(); + } + + +TInetAddr TIkeV2TrafficSelector::StartingAddress() const + { + return iStartingAddress; + } + + +TInetAddr TIkeV2TrafficSelector::EndingAddress() const + { + return iEndingAddress; + } + +TInetAddr TIkeV2TrafficSelector::Mask() const + { + return iMask; + } + +TUint8 TIkeV2TrafficSelector::ProtocolId() const + { + return iProtocolId; + } + +TUint8 TIkeV2TrafficSelector::Type() const + { + __ASSERT_DEBUG(iStartingAddress.Family() == iEndingAddress.Family() && + iStartingAddress.IsV4Compat() == iEndingAddress.IsV4Compat() && + iStartingAddress.IsV4Mapped() == iEndingAddress.IsV4Mapped(), User::Invariant()); + + if (iStartingAddress.Family() == KAfInet || + iStartingAddress.IsV4Compat() || + iStartingAddress.IsV4Mapped()) + { + return TS_IPV4_ADDR_RANGE; + } + else + { + return TS_IPV6_ADDR_RANGE; + } + } + + +HBufC8* TIkeV2TrafficSelector::IdFromTsL() const + { + TInetAddr idAddr = iStartingAddress; + idAddr.SetPort(0); + TInt prefix = 0; + if (Type() == TS_IPV4_ADDR_RANGE) + { + TUint32 startIp = iStartingAddress.Address(); + TUint32 endIp = iEndingAddress.Address(); + TUint32 mask = ~(endIp ^ startIp); + TUint32 m = 1; + while ( prefix < 32 ) + { + if ( mask & ( m << prefix) ) + break; + prefix ++; + } + prefix = 32 - prefix; + idAddr = TInetAddr(startIp); + } + else + { + prefix = 128; // NOT IMPLEMENTED YET + } + + HBufC* idString = HBufC::NewLC(512); + TPtr idStringPtr = idString->Des(); + idAddr.Output(idStringPtr); + idStringPtr.AppendFormat(_L("/%d"), prefix); + + HBufC8* idString8 = HBufC8::NewL(idString->Length()); + TPtr8 idString8Ptr = idString8->Des(); + idString8Ptr.Copy(*idString); + CleanupStack::PopAndDestroy(idString); + + return idString8; + } + +TInetAddr TIkeV2TrafficSelector::CalcuateMask() const + { + TInetAddr mask; + if ( Type() == TS_IPV4_ADDR_RANGE ) + { + TUint32 A = iStartingAddress.Address(); + TUint32 M = iEndingAddress.Address(); + TUint32 X = 0x80000000; + TUint32 Y = 0; + M = ~(A ^ M); //Gets the bits that are 1 in both addresses + for ( TInt i = 0; i < 32; ++i ) + { + if ( (M & X) == 0 ) + { + M &= Y; + break; + } + Y |= X; + X = (X >> 1); + } + mask.SetAddress(M); + } + else + { + TIp6Addr startAddr = iStartingAddress.Ip6Address(); + TIp6Addr endAddr = iEndingAddress.Ip6Address(); + TIp6Addr m; + Mem::FillZ(m.u.iAddr8, 16); + + TUint8 c = 0xff; + for ( TInt i = 0; i < 16; ++i ) + { + if ( c == 0xff ) + c = (TUint8)(~(startAddr.u.iAddr8[i] ^ endAddr.u.iAddr8[i])); // Convert range to mask + if ( (c != 0) && (c != 0xff) ) + { + TUint8 z = 0x80; + TUint8 w = 0; + for ( TInt j = 0; j < 8; ++j ) + { + if ( (c & z) == 0 ) + { + c &= w; + break; + } + w |= z; + z = (TUint8)(z >> 1); + } + m.u.iAddr8[i] = c; + c = 0; + } + else + { + m.u.iAddr8[i] = c; + } + } + mask.SetAddress(m); + } + return mask; + } + +bool TIkeV2TrafficSelector::operator>(const TIkeV2TrafficSelector& aOtherSelector) const + { + if (Type() != aOtherSelector.Type()) + { + //types do not match. + return false; + } + + if (operator==(aOtherSelector)) + { + //selectors are equal + return false; + } + + return operator>=(aOtherSelector); + } + + +bool TIkeV2TrafficSelector::operator<(const TIkeV2TrafficSelector& aOtherSelector) const + { + if (operator==(aOtherSelector)) + { + //selectors are equal + return false; + } + + //The operator + return operator<=(aOtherSelector); + } + +bool TIkeV2TrafficSelector::operator!=(const TIkeV2TrafficSelector& aOtherSelector) const + { + return !operator==(aOtherSelector); + } + +bool TIkeV2TrafficSelector::operator==(const TIkeV2TrafficSelector& aOtherSelector) const + { + return (iStartingAddress == aOtherSelector.iStartingAddress && + iEndingAddress == aOtherSelector.iEndingAddress); + } + +bool TIkeV2TrafficSelector::operator>=(const TIkeV2TrafficSelector& aOtherSelector) const + { + if (Type() != aOtherSelector.Type()) + { + //types do not match. + return false; + } + + if (operator==(aOtherSelector)) + { + //selectors are equal + return true; + } + + return !operator<(aOtherSelector); + } + +bool TIkeV2TrafficSelector::operator<=(const TIkeV2TrafficSelector& aOtherSelector) const + { + if (Type() != aOtherSelector.Type()) + { + //types do not match. + return false; + } + + if (operator==(aOtherSelector)) + { + //selectors are equal + return true; + } + + if (iStartingAddress.Port() < aOtherSelector.iStartingAddress.Port() || + iEndingAddress.Port() > aOtherSelector.iEndingAddress.Port()) + { + //Port range of this is bigger + return false; + } + + if (Type() == TS_IPV4_ADDR_RANGE) + { + if (iStartingAddress.Address() >= aOtherSelector.iStartingAddress.Address() && + iEndingAddress.Address() <= aOtherSelector.iEndingAddress.Address()) + { + return true; + } + else + { + return false; + } + } + else + { + __ASSERT_DEBUG(Type() == TS_IPV6_ADDR_RANGE, User::Invariant()); + + const TIp6Addr& thisStart = iStartingAddress.Ip6Address(); + const TIp6Addr& thisEnd = iEndingAddress.Ip6Address(); + + const TIp6Addr& otherStart = aOtherSelector.iStartingAddress.Ip6Address(); + const TIp6Addr& otherEnd = aOtherSelector.iEndingAddress.Ip6Address(); + + TInt i; + for (i = 0; i < 4; i++) + { + if (thisStart.u.iAddr32[i] > otherStart.u.iAddr32[i]) + { + //this start address is bigger + break; + } + else if (thisStart.u.iAddr32[i] < otherStart.u.iAddr32[i]) + { + //this start address is smaller. + return false; + } + } + + for (i = 0; i < 4; i++) + { + if (thisEnd.u.iAddr32[i] < otherEnd.u.iAddr32[i]) + { + //this end address is smaller + break; + } + else if (thisEnd.u.iAddr32[i] > otherEnd.u.iAddr32[i]) + { + //this end address is bigger + return false; + } + } + return true; + } + } + + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ipsecproposal.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ipsecproposal.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,326 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Ipsec Proposal handling +* +*/ +#include +#include "ikedebug.h" +#include "ipsecproposal.h" +#include "ikev2proposal.h" +#include "ikev2payloads.h" +#include "ikemsgrec.h" +#include "ikev2const.h" +#include +#include "pfkeymsg.h" +#include "ipsecsalist.h" + +HBufC8* IpsecProposal::BuildIpsecSaRequestL(const TPfkeyMessage& aPfkeyMessage, TUint16 aDHGroup) +{ + return BuildIpsecSaRequestL(aPfkeyMessage.iBase.iMsg->sadb_msg_satype, + aPfkeyMessage.iProposal.iComb->sadb_comb_encrypt, + aPfkeyMessage.iProposal.iComb->sadb_comb_encrypt_maxbits, + aPfkeyMessage.iProposal.iComb->sadb_comb_auth, + aPfkeyMessage.iProposal.iComb->sadb_comb_flags, + aDHGroup); +} + + +HBufC8* IpsecProposal::BuildIpsecSaRequestL(const TUint8 aSaType, const TUint8 aEncryptAlg, + const TUint16 aEncryptMaxbits, + const TUint8 aAuthAlg, const TUint16 aFlags, + TUint16 aDHGroup) +{ + // + // Build Ipsec SA proposal from PFKEY acquire primitive policy data + // In this phase PFKEY Aqcuire contains only one proposal + // (transform) + // + HBufC8* proposal = HBufC8::NewL(1024); + + TUint8 TransCnt = 0; + TBool IntegAlg = EFalse; + TUint16 SaLth = 0; + TUint16 TranLth = 0; + TUint16 PropLth = 0; + + TProposalIkev2* Proposal = TProposalIkev2::Cast(const_cast(proposal->Ptr())); + TTransformIkev2* Transform = NULL; + TDataAttributes* Attributes; + + TPayloadIkev2::Cast(Proposal)->Init(); // Initialize Payload general header + TPayloadIkev2::Cast(Proposal)->SetNextPayload(IKEV2_PAYLOAD_NONE); + Proposal->SetNum(1); + Proposal->SetSPISize(4); // SPI value shall be added later to proposal + PropLth = (TUint16)Proposal->PropHdrLth(); + + switch ( aSaType ) + { + case SADB_SATYPE_AH: + Proposal->SetProtocol(IKEV2_IPSEC_AH); + IntegAlg = ETrue; + break; + + case SADB_SATYPE_ESP: + TransCnt ++; + Proposal->SetProtocol(IKEV2_IPSEC_ESP); + Transform = Proposal->TransformPl(); + TPayloadIkev2::Cast(Transform)->Init(); // Initialize Payload general header + TPayloadIkev2::Cast(Transform)->SetNextPayload(IKEV2_PAYLOAD_TRANS); + Transform->SetReserved(); + Transform->SetType(IKEV2_ENCR); // Encryption Algorithm transform (1) + TranLth = (TUint16)Transform->Size(); + + switch ( aEncryptAlg ) + { + case ENCR_DES: + Transform->SetID(ENCR_DES); + break; + + case ENCR_3DES: + Transform->SetID(ENCR_3DES); + break; + + case ENCR_NULL: + Transform->SetID(ENCR_NULL); + break; + + case ENCR_AES_CBC: + Transform->SetID(ENCR_AES_CBC); + // + // Variable key length algorithm. Get key length + // attribute to transform data. + // + Attributes = Transform->Attributes(); + Attributes->SetType(IKEV2_ENCR_KEY_LTH); + Attributes->SetBasic(); + if ( aEncryptMaxbits ) + Attributes->SetValue(aEncryptMaxbits); + else Attributes->SetValue(128); //default AES key size + TranLth = (TUint16)(TranLth + Attributes->Size()); + break; + + default: + User::Leave(KErrNotSupported); + break; + } + TPayloadIkev2::Cast(Transform)->SetLength(TranLth); + PropLth = (TUint16)(PropLth + TranLth); + if ( aAuthAlg != SADB_AALG_NONE ) + IntegAlg = ETrue; + break; + + default: + User::Leave(KErrNotSupported); + break; + } + + if ( IntegAlg ) + { + TransCnt ++; + if ( Transform ) + Transform = (TTransformIkev2*)TPayloadIkev2::Cast(Transform)->Next(); + else Proposal->TransformPl(); + TPayloadIkev2::Cast(Transform)->Init(); // Initialize Payload general header + TPayloadIkev2::Cast(Transform)->SetNextPayload(IKEV2_PAYLOAD_TRANS); + Transform->SetType(IKEV2_INTEG); // Integrity Algorithm transform + Transform->SetReserved(); + TranLth = (TUint16)Transform->Size(); + switch ( aAuthAlg ) + { + case SADB_AALG_MD5HMAC: + Transform->SetID(AUTH_HMAC_MD5_96); + break; + + case SADB_AALG_SHA1HMAC: + Transform->SetID(AUTH_HMAC_SHA1_96); + break; + + default: + User::Leave(KErrNotSupported); + } + TPayloadIkev2::Cast(Transform)->SetLength(TranLth); + PropLth = (TUint16)(PropLth + TranLth); + } + + if ( (aDHGroup != 0 ) && (aFlags & SADB_SAFLAGS_PFS) ) + { + TransCnt ++; + Transform = (TTransformIkev2*)TPayloadIkev2::Cast(Transform)->Next(); + TPayloadIkev2::Cast(Transform)->Init(); // Initialize Payload general header + TPayloadIkev2::Cast(Transform)->SetNextPayload(IKEV2_PAYLOAD_TRANS); + Transform->SetType(IKEV2_DH); // Diffie-Hellman Group (4) + Transform->SetReserved(); + Transform->SetID(aDHGroup); + TranLth = (TUint16)Transform->Size(); + TPayloadIkev2::Cast(Transform)->SetLength(TranLth); + PropLth = (TUint16)(PropLth + TranLth); + } + // + // Add ESN trasnform to Proposal with fixed value not used (0) + // + TransCnt ++; + Transform = (TTransformIkev2*)TPayloadIkev2::Cast(Transform)->Next(); + TPayloadIkev2::Cast(Transform)->Init(); // Initialize Payload general header + TPayloadIkev2::Cast(Transform)->SetNextPayload(IKEV2_PAYLOAD_NONE); + Transform->SetType(IKEV2_ESN); // ESN (5) [64-bit sequence numbers with ESP] + Transform->SetReserved(); + Transform->SetID(0); + TranLth = (TUint16)Transform->Size(); + TPayloadIkev2::Cast(Transform)->SetLength(TranLth); + PropLth = (TUint16)(PropLth + TranLth); + + TPayloadIkev2::Cast(Transform)->SetNextPayload(IKEV2_PAYLOAD_NONE); + Proposal->SetNumTrans(TransCnt); + TPayloadIkev2::Cast(Proposal)->SetLength(PropLth); + SaLth = (TUint16)(SaLth + PropLth); + + proposal->Des().SetLength(SaLth); + + HBufC8 *reAllocatedProposal = proposal->ReAlloc(proposal->Length()); + if (reAllocatedProposal != NULL) + { + proposal = reAllocatedProposal; + } + + return proposal; +} + + +HBufC8* IpsecProposal::BuildIpsecSaFromPolicyL(const CIpsecSaSpecList& aSaList, TUint16 aDhGroup) +{ + __ASSERT_DEBUG(aSaList.Count() > 0, User::Invariant()); + + static const TUint KProposalMaxLength = 64; + static const TUint KSpiSize = 4; + HBufC8* saData = HBufC8::NewL(KProposalMaxLength); + TPtr8 saDataPtr = saData->Des(); + + const TIpsecSaSpec& saSpec = aSaList.At(0); + TProposalIkev2* proposal = TProposalIkev2::Cast(saDataPtr.Ptr()); + TPayloadIkev2::Cast(proposal)->Init(); // Initialize Payload general header + TPayloadIkev2::Cast(proposal)->SetNextPayload(IKEV2_PAYLOAD_NONE); + proposal->SetNum(1); + proposal->SetSPISize(KSpiSize); // SPI value shall be added later to proposal + + + TTransformIkev2* transform = NULL; + + TUint8 transformCount = 0; + switch ( saSpec.iType ) + { + case SADB_SATYPE_AH: + proposal->SetProtocol(IKEV2_IPSEC_AH); + saDataPtr.SetLength(proposal->Size() + KSpiSize); + break; + + case SADB_SATYPE_ESP: + { + transformCount++; + proposal->SetProtocol(IKEV2_IPSEC_ESP); + transform = proposal->TransformPl(); + TPayloadIkev2::Cast(transform)->Init(); // Initialize Payload general header + TPayloadIkev2::Cast(transform)->SetNextPayload(IKEV2_PAYLOAD_TRANS); + transform->SetReserved(); + transform->SetType(IKEV2_ENCR); // Encryption Algorithm transform (1) + + TUint16 tranformLength = transform->Size(); + + transform->SetID(saSpec.iEalg); + if ( saSpec.iEalg == ENCR_AES_CBC ) + { + // + // Variable key length algorithm. Get key length + // attribute to transform data. + // + TDataAttributes* attributes = transform->Attributes(); + attributes->SetType(IKEV2_ENCR_KEY_LTH); + attributes->SetBasic(); + if ( saSpec.iEalgLen ) + attributes->SetValue((TUint16)saSpec.iEalgLen); + else attributes->SetValue(128); //default AES key size + tranformLength += (TUint16)attributes->Size(); + } + TPayloadIkev2::Cast(transform)->SetLength(tranformLength); + saDataPtr.SetLength(proposal->Size() + KSpiSize + tranformLength); + } + break; + + default: + break; + + } + + if ( saSpec.iType == SADB_SATYPE_AH || + (saSpec.iType == SADB_SATYPE_ESP && saSpec.iAalg != SADB_AALG_NONE) ) + { + transformCount++; + if ( transform ) + { + transform = (TTransformIkev2*)TPayloadIkev2::Cast(transform)->Next(); + } + else + { + transform = proposal->TransformPl(); + } + + TPayloadIkev2::Cast(transform)->Init(); // Initialize Payload general header + TPayloadIkev2::Cast(transform)->SetNextPayload(IKEV2_PAYLOAD_TRANS); + transform->SetType(IKEV2_INTEG); // Integrity Algorithm transform + transform->SetReserved(); + switch ( saSpec.iAalg ) + { + case SADB_AALG_MD5HMAC: + transform->SetID(AUTH_HMAC_MD5_96); + break; + + case SADB_AALG_SHA1HMAC: + transform->SetID(AUTH_HMAC_SHA1_96); + break; + + default: + break; + } + TPayloadIkev2::Cast(transform)->SetLength(transform->Size()); + saDataPtr.SetLength(saDataPtr.Length() + transform->Size()); + } + + if ( (aDhGroup != 0 ) && saSpec.iPfs ) + { + transformCount++; + transform = (TTransformIkev2*)TPayloadIkev2::Cast(transform)->Next(); + TPayloadIkev2::Cast(transform)->Init(); // Initialize Payload general header + TPayloadIkev2::Cast(transform)->SetNextPayload(IKEV2_PAYLOAD_TRANS); + transform->SetType(IKEV2_DH); // Diffie-Hellman Group (4) + transform->SetReserved(); + transform->SetID(aDhGroup); + TPayloadIkev2::Cast(transform)->SetLength(transform->Size()); + saDataPtr.SetLength(saDataPtr.Length() + transform->Size()); + } + + transformCount++; + transform = (TTransformIkev2*)TPayloadIkev2::Cast(transform)->Next(); + TPayloadIkev2::Cast(transform)->Init(); // Initialize Payload general header + TPayloadIkev2::Cast(transform)->SetNextPayload(IKEV2_PAYLOAD_NONE); + transform->SetType(IKEV2_ESN); // ESN (5) [64-bit sequence numbers with ESP] + transform->SetReserved(); + transform->SetID(0); + TPayloadIkev2::Cast(transform)->SetLength(transform->Size()); + saDataPtr.SetLength(saDataPtr.Length() + transform->Size()); + + proposal->SetNumTrans(transformCount); + TPayloadIkev2::Cast(proposal)->SetLength(saDataPtr.Length()); + + return saData; +} + diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ipsecselectors.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ipsecselectors.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,585 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Ipsec Traffic Selector handling +* +*/ + +#include +#include +#include "ikedebug.h" +#include "ipsecselectors.h" +#include "ikev2payloads.h" +#include "ikev2pluginsession.h" +#include "ikev2proposal.h" +#include "ikemsgrec.h" +#include "ikev2const.h" +#include "ipsecproposal.h" +#include "pfkeymsg.h" +#include "ipsecsalist.h" +#include "ikev2trafficselector.h" +#include "ikev2acquire.h" +#include + +CIkev2Acquire* IpsecSelectors::GetIpsecPolicyL(CIkev2PluginSession& aPluginSession, CIkev2Payloads* aIkeMsg, TInt aDhGroup) +{ + ASSERT(aIkeMsg); + // + // Examine is there available policy for Traffic selectors present + // in current CREATE_CHILD_SA request. Use Initiator traffic + // selector for policy check. + + //If there is no traffic selector, we stop the processing + TTSPayloadIkev2* TsIPl = aIkeMsg->iTsI; + if ( !TsIPl || (TsIPl->GetNumberOfTs() < 1) ) + { + return NULL; + } + + TTSPayloadIkev2* TsRPl = aIkeMsg->iTsR; + if ( !TsRPl || (TsRPl->GetNumberOfTs() < 1) ) + { + return NULL; + } + + //Parse both selectors + CArrayFix* proposedTsI = new (ELeave) CArrayFixFlat(2); + CleanupStack::PushL(proposedTsI); + + CArrayFix* proposedTsR = new (ELeave) CArrayFixFlat(2); + CleanupStack::PushL(proposedTsR); + + TInt i = 0; + const TTrafficSelector* sel = TTrafficSelector::Cast(TsIPl->TrafficSelectors()); + for (i = 0; i < TsIPl->GetNumberOfTs(); ++i) + { + TPtrC8 selPtr(reinterpret_cast(sel), sel->Length()); + TIkeV2TrafficSelector* selector = TIkeV2TrafficSelector::NewL(selPtr); + CleanupStack::PushL(selector); + proposedTsI->AppendL(*selector); + CleanupStack::PopAndDestroy(selector); + + sel = reinterpret_cast(reinterpret_cast(sel) + sel->Length()); + } + + + i = 0; + sel = TTrafficSelector::Cast(TsRPl->TrafficSelectors()); + for (i = 0; i < TsRPl->GetNumberOfTs(); ++i) + { + TPtrC8 selPtr(reinterpret_cast(sel), sel->Length()); + TIkeV2TrafficSelector* selector = TIkeV2TrafficSelector::NewL(selPtr); + CleanupStack::PushL(selector); + proposedTsR->AppendL(*selector); + CleanupStack::PopAndDestroy(selector); + + sel = reinterpret_cast(reinterpret_cast(sel) + sel->Length()); + } + + __ASSERT_DEBUG(proposedTsI->Count() > 0, User::Invariant()); + //The policy is retrieved by using the firts initiator selector. + TInetAddr mask = (*proposedTsI)[0].Mask(); + + //Takes only the network part of the address + TInetAddr addr; + addr.SetAddress((*proposedTsI)[0].StartingAddress().Address() & mask.Address()); + addr.SetPort(0); + + TInetAddr DummyIp; + DummyIp.SetAddress(KInetAddrNone); // 0.0.0.0 + DummyIp.SetPort(0); + + CIpsecSaSpecList* SaList = NULL; + TRAPD(err, SaList = aPluginSession.GetIPsecSaSpecListL(DummyIp, DummyIp, // No local address/port info + addr, mask, // for any peer address and port + (*proposedTsI)[0].ProtocolId())); // Protocol + + if (err != KErrNone) + { + CleanupStack::PopAndDestroy(proposedTsR); + CleanupStack::PopAndDestroy(proposedTsI); + + return NULL; + } + CleanupStack::PushL(SaList); + const TIpsecSaSpec& Spec = SaList->At(0); + + __ASSERT_DEBUG(SaList->Count() > 0, User::Invariant()); + HBufC8* Sa = IpsecProposal::BuildIpsecSaFromPolicyL(*SaList, aDhGroup); + + CleanupStack::PushL(Sa); + + CIkev2Acquire* Acquire = CIkev2Acquire::NewL(aPluginSession.GetSAId(), Sa, proposedTsI, proposedTsR); + + CleanupStack::Pop(Sa); + CleanupStack::PushL(Acquire); + + TIpsecSALifetime hard(Spec.iHard.iAllocations, Spec.iHard.iBytes, Spec.iHard.iAddTime, Spec.iHard.iUseTime); + TIpsecSALifetime soft(Spec.iSoft.iAllocations, Spec.iSoft.iBytes, Spec.iSoft.iAddTime, Spec.iSoft.iUseTime); + Acquire->SetHardLifetime(hard); + Acquire->SetSoftLifetime(soft); + + // + // Set SrcSpecific information to correspond MOBIKE configuration. + // Actually SrcSpecific should be available in TIpsecSaSpec. + // + HBufC8* remoteId = NULL; + if ( Spec.iRemoteIdentity.Length() ) + { + // + // Copy remote identity from policy and queue it to CIkev2Acquire + // object + // + remoteId = Spec.iRemoteIdentity.AllocL(); + + } + else + { + remoteId = HBufC8::NewL(1); + } + Acquire->ReplaceRemoteId(remoteId); + + HBufC8* localId = NULL; + if ( Spec.iLocalIdentity.Length() ) + { + // + // Copy remote identity from policy and queue it to CIkev2Acquire + // object + // + localId = Spec.iLocalIdentity.AllocL(); + + } + else + { + localId = HBufC8::NewL(1); + } + Acquire->ReplaceLocalId(localId); + + CleanupStack::Pop(Acquire); + CleanupStack::PopAndDestroy(SaList); + CleanupStack::Pop(proposedTsR); + CleanupStack::Pop(proposedTsI); + + return Acquire; +} + +CIkev2Acquire* IpsecSelectors::BuildVirtualAcquireL(CIkev2PluginSession& aPluginSession) +{ + // + // Build CIkev2Acquire object and related Ipsec SA- ja Traffic selector + // Payloads. These payload is used in conjunction with CP payload + // in IKE_AUTH exchange. + // To get an Virtual Ip with CP payload we must also create (for + // some unintelligible reason) create an pair of Ipsec SA:s. + // The following actions are taken: + // -- Try first if the "all host" selector is available in + // current Ipsec policy and if it build Virtual acquire for full + // address range (0.0.0.0 - 255.255.255.255) + // -- If "all host" selector is not available, we going to use + // "UMA" Ipsec ESP profiles as Ipsec SA proposal. + // The traffic selectors are set so that we asking Ipsec SA:s + // between requested Virtual Ip and Remote SGW Ip + // (single address all ports and protocols) + // + HBufC8* Sa = 0; + + TIpsecSALifetime hard(0,0,0,0); + TIpsecSALifetime soft(0,0,0,0); + + TInetAddr StartIp(KInetAddrNone, 0); // 0.0.0.0 + TInetAddr EndIp(KInetAddrAll, 0xFFFF); // 255.255.255.255 + + CIpsecSaSpecList* SaList = aPluginSession.GetIPsecSaSpecListL(StartIp, StartIp, // for any local address and port + StartIp, StartIp, // for any peer address and port + 0); // Any protocol + CleanupStack::PushL(SaList); + __ASSERT_DEBUG(SaList->Count() > 0, User::Invariant()); + + // + // Build Ipsec proposal for implicit SA negotiatited within IKE + // SA AUTH exchange + // + const TIpsecSaSpec& Spec = SaList->At(0); + Sa = IpsecProposal::BuildIpsecSaFromPolicyL(*SaList, 0); // 0 = DH Group + CleanupStack::PushL(Sa); + + CArrayFix* TsI = new (ELeave) CArrayFixFlat(1); + CleanupStack::PushL(TsI); + TIkeV2TrafficSelector selector(StartIp, EndIp, 0); + TsI->AppendL(selector); + + CArrayFix* TsR = new (ELeave) CArrayFixFlat(1); + CleanupStack::PushL(TsR); + selector = TIkeV2TrafficSelector(StartIp, EndIp, 0); + TsR->AppendL(selector); + + hard.iAllocations = Spec.iHard.iAllocations; + hard.iBytes = Spec.iHard.iBytes; + hard.iAddtime = Spec.iHard.iAddTime; + hard.iUsetime = Spec.iHard.iUseTime; + soft.iAllocations = Spec.iSoft.iAllocations; + soft.iBytes = Spec.iSoft.iBytes; + soft.iAddtime = Spec.iSoft.iAddTime; + soft.iUsetime = Spec.iSoft.iUseTime; + + CIkev2Acquire* Acquire = CIkev2Acquire::NewL(aPluginSession.GetSAId(), Sa, TsI, TsR); + CleanupStack::Pop(TsR); + CleanupStack::Pop(TsI); + CleanupStack::Pop(Sa); + + CleanupStack::PushL(Acquire); + HBufC8* identity = Spec.iRemoteIdentity.AllocL(); + Acquire->ReplaceRemoteId(identity); + identity = NULL; + + identity = Spec.iLocalIdentity.AllocL(); + Acquire->ReplaceLocalId(identity); + identity = NULL; + + Acquire->SetVirtualIp(); + Acquire->SetHardLifetime(hard); + Acquire->SetSoftLifetime(soft); + + CleanupStack::Pop(Acquire); + CleanupStack::PopAndDestroy(); // SaList + + return Acquire; +} + +TBool IpsecSelectors::VerifyTrafficSelectorsL(CIkev2Acquire* aAcquire, TTSPayloadIkev2* aTsI, TTSPayloadIkev2* aTsR ) +{ + ASSERT(aAcquire); + + if (aTsI == NULL || aTsR == NULL) + { + return EFalse; + } + // + // Compare Traffic selectors CIkev2Acquire object to Traffic selectors + // received in CREATE_CHILD_SA response. + // + const CArrayFix& TsI_Ref = aAcquire->TS_i(); + const CArrayFix& TsR_Ref = aAcquire->TS_r(); + __ASSERT_DEBUG(TsI_Ref.Count() > 0 && TsR_Ref.Count() > 0, User::Invariant()); + + // + // Check has the peer been narrowed requested Traffic selectors + // + CArrayFix* TsI = new (ELeave)CArrayFixFlat(2); + CleanupStack::PushL(TsI); + CArrayFix* TsR = new (ELeave)CArrayFixFlat(2); + CleanupStack::PushL(TsR); + + TInt i = 0; + const TTrafficSelector* sel = TTrafficSelector::Cast(aTsI->TrafficSelectors()); + const TUint8* payloadEnd = reinterpret_cast(aTsI) + TPayloadIkev2::Cast(aTsI)->GetLength(); + for (i = 0; i < aTsI->GetNumberOfTs(); ++i) + { + if (reinterpret_cast(sel) > payloadEnd || + reinterpret_cast(sel) + sel->Length() > payloadEnd) + { + CleanupStack::PopAndDestroy(TsR); + CleanupStack::PopAndDestroy(TsI); + return EFalse; + } + + TPtrC8 selPtr(reinterpret_cast(sel), sel->Length()); + TIkeV2TrafficSelector* selector = TIkeV2TrafficSelector::NewL(selPtr); + CleanupStack::PushL(selector); + TsI->AppendL(*selector); + CleanupStack::PopAndDestroy(selector); + + sel = reinterpret_cast(reinterpret_cast(sel) + sel->Length()); + } + + + sel = TTrafficSelector::Cast(aTsR->TrafficSelectors()); + payloadEnd = reinterpret_cast(aTsR) + TPayloadIkev2::Cast(aTsR)->GetLength(); + for (i = 0; i < aTsR->GetNumberOfTs(); ++i) + { + if (reinterpret_cast(sel) > payloadEnd || + reinterpret_cast(sel) + sel->Length() > payloadEnd) + { + CleanupStack::PopAndDestroy(TsR); + CleanupStack::PopAndDestroy(TsI); + return EFalse; + } + TPtrC8 selPtr(reinterpret_cast(sel), sel->Length()); + TIkeV2TrafficSelector* selector = TIkeV2TrafficSelector::NewL(selPtr); + CleanupStack::PushL(selector); + TsR->AppendL(*selector); + CleanupStack::PopAndDestroy(selector); + + sel = reinterpret_cast(reinterpret_cast(sel) + sel->Length()); + } + + if ( !ValidataTs(TsI_Ref, *TsI) || + !ValidataTs(TsR_Ref, *TsR) ) + { + delete TsI; + delete TsR; + return EFalse; + } + aAcquire->ReplaceTS_i(TsI); + aAcquire->ReplaceTS_r(TsR); + + CleanupStack::Pop(TsR); + CleanupStack::Pop(TsI); + + return ETrue; +} + + + +void IpsecSelectors::BuildTrafficSelectorsL(CIkev2Acquire* aAcquire, const TInetAddr& aLocalAddr, + const TPfkeyIdentity& aSrcIdent, const TPfkeyIdentity& aDstIdent, + TUint8 aProtocol) +{ + // + // Build Traffic Selectors payload from PFKEY Acquire primitive + // Identity data + // + CArrayFix* TsIBfr = NULL; + CArrayFix* TsRBfr = NULL; + if ( aDstIdent.iExt && (aDstIdent.iExt->sadb_ident_type == SADB_IDENTTYPE_PREFIX)) + { + TsRBfr = new (ELeave) CArrayFixFlat(1); + CleanupStack::PushL(TsRBfr); + if ( ( !aLocalAddr.IsUnspecified()) || + ( aSrcIdent.iExt && (aSrcIdent.iExt->sadb_ident_type == SADB_IDENTTYPE_PREFIX))) + { + TsIBfr = new (ELeave) CArrayFixFlat(1); + CleanupStack::PushL(TsIBfr); + } + } + + if ( TsIBfr ) + { + ASSERT(aAcquire); + // + // If local address pointer defined, local address is used as + // initiator Traffic selector (single address "range") + // Else Use Source Identity data to build inititor Traffic selector + // + if ( !aLocalAddr.IsUnspecified() ) + { + TInetAddr startAddress = aLocalAddr; + startAddress.SetPort(0); + + TInetAddr endAddress = aLocalAddr; + endAddress.SetPort(0xffff); + + TIkeV2TrafficSelector selector(startAddress, endAddress, aProtocol); + TsIBfr->AppendL(selector); + } + else + { + TIkeV2TrafficSelector selector = IpsecSelectors::IdentityToSelectorL(aSrcIdent.iData, aProtocol); + TsIBfr->AppendL(selector); + + } + CleanupStack::Pop(TsIBfr); + aAcquire->ReplaceTS_i(TsIBfr); + } + + if ( TsRBfr ) + { + ASSERT(aAcquire); + // + // Build responder Traffic selector from destination Identity data + // + TIkeV2TrafficSelector selector = IpsecSelectors::IdentityToSelectorL(aDstIdent.iData, aProtocol); + TsRBfr->AppendL(selector); + CleanupStack::Pop(TsRBfr); // TsRBfr + aAcquire->ReplaceTS_r(TsRBfr); + } +} + + +TIkeV2TrafficSelector IpsecSelectors::IdentityToSelectorL(const TDesC8& aIdentity, TUint8 aProtocol) +{ + // + // Convert text format Identity data to Range start and end address + // needed into Traffic selector + // + TInetAddr StartAddr; + TInetAddr EndAddr; + TInt Lth = aIdentity.Length(); + + if (aIdentity.Length() == 0) + { + User::Leave(KErrArgument); + } + + TInt offset = aIdentity.Find(_L8("/")); + switch (offset) + { + case KErrNotFound: //Simple address + { + HBufC *unibuf = HBufC::NewL(aIdentity.Length()); + unibuf->Des().Copy(aIdentity); + if ( StartAddr.Input(unibuf->Des()) != KErrNone ) + { + delete unibuf; + User::Leave(KErrArgument); + } + delete unibuf; + EndAddr = StartAddr; // Range start and end addresses are same + break; + } + + default: //Subnet + { + //addr1 - Start address of range + TInt prefix_len; + HBufC *unibuf = HBufC::NewL(aIdentity.Length()); + unibuf->Des().Copy(aIdentity); + TPtrC addr_buf(unibuf->Ptr(), offset); + if ( StartAddr.Input(addr_buf) != KErrNone ) + { + delete unibuf; + User::Leave(KErrArgument); + } + TPtrC prefix_ptr(unibuf->Ptr() + offset + 1, unibuf->Length() - offset - 1); + //addr2 - End address of range + TLex lex(prefix_ptr); + if ( lex.Val(prefix_len) != KErrNone ) + { + delete unibuf; + User::Leave(KErrArgument); + } + delete unibuf; + if ( !IpsecSelectors::GetRangeEndAddresses(StartAddr, EndAddr, prefix_len) ) + User::Leave(KErrArgument); + } + + } //end switch + + StartAddr.SetPort(0x0); + EndAddr.SetPort(0xffff); + return TIkeV2TrafficSelector(StartAddr, EndAddr, aProtocol); +} + +TBool IpsecSelectors::GetRangeEndAddresses(TInetAddr& aStartAddr, TInetAddr& aEndAddr, TInt aPrefixLen) +{ + // + // Convert start address / prefix length to range start address / + // end address pair + // + if ( aStartAddr.Family() == KAfInet ) + { + TUint32 Mask; + if ( aPrefixLen > 32 ) + return EFalse; + if ( aPrefixLen ) + Mask = (~0UL << ((32 - (aPrefixLen & 31)) & 31)); + else Mask = 0; + TUint32 Start = (aStartAddr.Address() & Mask); + TUint32 End = Start | (~Mask); + aStartAddr.SetAddress(Start); + aEndAddr.SetAddress(End); + } + else //KAfInet6 + { + if ( aPrefixLen > 128 ) + return EFalse; + aStartAddr.Prefix(aStartAddr, aPrefixLen); // For sure + TUint32 M = (~0UL >> (aPrefixLen & 31)); + TIp6Addr S = aStartAddr.Ip6Address(); + TIp6Addr E; + aPrefixLen >>= 5; + TInt i; + for (i = 0; i < aPrefixLen; i++) + E.u.iAddr32[i] = S.u.iAddr32[i]; + + i <<= 2; + E.u.iAddr8[i] = (TUint8)(S.u.iAddr8[i] | (M >> 24)); i++; + E.u.iAddr8[i] = (TUint8)(S.u.iAddr8[i] | (M >> 16)); i++; + E.u.iAddr8[i] = (TUint8)(S.u.iAddr8[i] | (M >> 8)); i++; + E.u.iAddr8[i] = (TUint8)(S.u.iAddr8[i] | M); i++; + + i >>= 2; + while (i < 4) + E.u.iAddr32[i++] = ~0UL; + + aStartAddr.SetAddress(S); + aEndAddr.SetAddress(E); + } + + return ETrue; + +} + + +TBool IpsecSelectors::ValidataTs(const CArrayFix& aTsRef, + const CArrayFix& aTs) +{ + //For every selector in aTs, there must be a same or wider selector in aTsRef. + for (TInt i = 0; i < aTs.Count(); ++i) + { + TInt j; + const TIkeV2TrafficSelector& selector = aTs[i]; + for (j = 0; j < aTsRef.Count(); ++j) + { + const TIkeV2TrafficSelector& refSelector = aTsRef[j]; + if (selector <= refSelector) + { + break; + } + } + if (j == aTsRef.Count()) + { + //No selector found + return EFalse; + } + } + return ETrue; +} + + +TBool IpsecSelectors::CheckPorts(TUint16 aStartRef, TUint16 aEndRef, TUint16 aStart, TUint16 aEnd ) +{ + // + // Check that current port range narrowed intersection of reference + // port range + // + if ( (aStartRef > aStart) || (aEndRef < aEnd) || (aStart > aEnd) ) + return EFalse; + + return ETrue; + +} + +TBool IpsecSelectors::CheckAddresses(TUint8 aType, TUint8* aRefAddresses, TUint8* aAddresses ) +{ + // + // Check that current address range narrowed intersection of reference + // address range + // + if ( aType == TS_IPV4_ADDR_RANGE ) + { + ASSERT(aRefAddresses && aAddresses); + + // + // Comparison is done as 32 bit integers + // + TUint32 StartRef = GET32(aRefAddresses); + TUint32 EndRef = GET32(aRefAddresses + 4); + TUint32 Start = GET32(aAddresses); + TUint32 End = GET32(aAddresses + 4); + if ( (StartRef > Start) || (EndRef < End) || (Start > End) ) + return EFalse; + } + + return ETrue; +} diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdapi/EABI/kmdapiU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdapi/EABI/kmdapiU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,10 @@ +EXPORTS + _ZN4RKMD17StopVpnConnectionEmN18TKmdStopConnection5TTypeE @ 1 NONAME + _ZN4RKMD7ConnectEv @ 2 NONAME + _ZNK4RKMD13CancelResolveEv @ 3 NONAME + _ZNK4RKMD14CancelActivateEv @ 4 NONAME + _ZNK4RKMD14ResolveAddressEmRK7TDesC16R8TPckgBufI11TNameRecordER14TRequestStatus @ 5 NONAME + _ZNK4RKMD19StartRealConnectionEmR5TPckgI24TVpnRealConnectionParamsER14TRequestStatus @ 6 NONAME + _ZNK4RKMD25CancelStartRealConnectionEv @ 7 NONAME + _ZNK4RKMD8ActivateEmRK7TDesC16RK6TDesC8R5TPckgI11TVPNAddressER14TRequestStatus @ 8 NONAME + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdapi/bwins/kmdapiu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdapi/bwins/kmdapiu.def Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,10 @@ +EXPORTS + ?Activate@RKMD@@QBEXKABVTDesC16@@ABVTDesC8@@AAV?$TPckg@VTVPNAddress@@@@AAVTRequestStatus@@@Z @ 1 NONAME ; void RKMD::Activate(unsigned long, class TDesC16 const &, class TDesC8 const &, class TPckg &, class TRequestStatus &) const + ?CancelActivate@RKMD@@QBEXXZ @ 2 NONAME ; void RKMD::CancelActivate(void) const + ?CancelResolve@RKMD@@QBEXXZ @ 3 NONAME ; void RKMD::CancelResolve(void) const + ?CancelStartRealConnection@RKMD@@QBEXXZ @ 4 NONAME ; void RKMD::CancelStartRealConnection(void) const + ?Connect@RKMD@@QAEHXZ @ 5 NONAME ; int RKMD::Connect(void) + ?ResolveAddress@RKMD@@QBEXKABVTDesC16@@AAV?$TPckgBuf@VTNameRecord@@@@AAVTRequestStatus@@@Z @ 6 NONAME ; void RKMD::ResolveAddress(unsigned long, class TDesC16 const &, class TPckgBuf &, class TRequestStatus &) const + ?StartRealConnection@RKMD@@QBEXKAAV?$TPckg@VTVpnRealConnectionParams@@@@AAVTRequestStatus@@@Z @ 7 NONAME ; void RKMD::StartRealConnection(unsigned long, class TPckg &, class TRequestStatus &) const + ?StopVpnConnection@RKMD@@QAEHKW4TType@TKmdStopConnection@@@Z @ 8 NONAME ; int RKMD::StopVpnConnection(unsigned long, enum TKmdStopConnection::TType) + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdapi/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdapi/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Build information file +* +*/ + + +#include + +PRJ_PLATFORMS + +PRJ_EXPORTS + +PRJ_MMPFILES +kmdapi.mmp + +PRJ_TESTMMPFILES + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdapi/group/kmdapi.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdapi/group/kmdapi.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project kmdapi +* +*/ + +#include + +TARGET kmdapi.dll +TARGETTYPE DLL +UID 0x1000008d 0x101f5140 + +CAPABILITY ALL -Tcb +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE kmdapi.cpp + +SOURCEPATH ../../vpncommon/src +SOURCE clistatic.cpp + +USERINCLUDE ../inc +USERINCLUDE ../../kmdserver/inc +USERINCLUDE ../../ikesocket/inc +USERINCLUDE ../../vpnmanager/inc +USERINCLUDE ../../vpncommon/inc + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY euser.lib diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdapi/inc/kmdapi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdapi/inc/kmdapi.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,167 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: KMD api +* +*/ + +#ifndef R_KMD_H +#define R_KMD_H + +#include "vpnmandefs.h" + +// +// KMD API Error codes +// NOTE! The error code values below MUST be kept in sync with +// the corresponding error code values defined together by +// vpnapi/data/vpnerr.rss and vpnapi/data/vpnerr.ra +// +const TInt KKmdTooWeakCryptoLib = -5253; +const TInt KKmdNoAlgorithmsFile = -5254; +const TInt KKmdIkePolicyFileErr = -5255; +const TInt KKmdIkeNegotFailed = -5256; +const TInt KKmdIkeNoResponseErr = -5257; +const TInt KKmdIkeNoProposalErr = -5258; +const TInt KKmdIkeAuthFailedErr = -5259; +const TInt KKmdIkePeerAuthFailed = -5260; +const TInt KKmdIkeNoCertFoundErr = -5261; +const TInt KKmdIkeNoPolicyErr = -5262; + +/** + * VPN real connection parameters. + * + * @lib kmdapi.lib + */ +class TVpnRealConnectionParams + { +public: + /** + * Real IAP Id. + * Own. + */ + TUint32 iRealIapId; + + /** + * Real NET Id. + * Own. + */ + TUint32 iRealNetId; + }; + +/** + * Enumeration of VPN connection stopping types. + * + * @lib kmdapi.lib + */ +class TKmdStopConnection + { +public: + enum TType + { + ENormal = 0, + EForced + }; + }; + +/** + * KMD API. + * A handle to KMD server. + * + * @lib kmdapi.lib + */ +class RKMD : public RSessionBase + { +public: + + /** + * Creates session to KMD server. If server is not running, it is started. + */ + IMPORT_C TInt Connect(); + + /** + * Start a real network connection. + * Outstanding request can be cancelled any time by calling + * CancelStartConnection(). + * + * @param aVpnIapId Used VPN IAP Id + * @param aRealConfig If request completes with KErrNone, contains IAP + * and NET Ids of used real network connecetion + * (returned). + * @param aStatus Completes with KErrNone if real network connection + * is successfully opened (returned). + * + */ + IMPORT_C void StartRealConnection( TUint32 aVpnIapId, + TPckg& aRealConfig, + TRequestStatus& aStatus ) const; + + /** + * Cancel starting of real network connection. + */ + IMPORT_C void CancelStartRealConnection() const; + + + /** + * Asynchronous activation command to activate VPN connection (IKE policy). + * If there is no virtual IP address protocols configured the activate + * request completes immediatelly. + * + * @param aVpnIapId Used VPN IAP Id + * @param aVpnIfName VPN interface name + * @param aIkeConf IKE policy data + * @param aVPNAddress Contains the IP config of the VPN connection, when + * request completes (returned). + * @param aStatus Completion status, KErrNone if successfull (returned). + */ + IMPORT_C void Activate( TUint32 aVpnIapId, + const TDesC& aVpnIfName, + const TDesC8& aIkeConf, + TVPNAddressPckg& aVPNAddress, + TRequestStatus& aStatus ) const; + + /** + * Cancels ongoing activate request. + */ + IMPORT_C void CancelActivate() const; + + /** + * Stops VPN connection. + * @param aVpnIapId Used VPN IAP + * @param aType: Specifies stopping type. + * ENormal = All IKE and IPSEC SA:s related to VPN connection + * shall be deleted (= ISAKMP delete payload is transmitted + * to SA peer) + * EForced = Delete payload is not transmitted to SA peer. + */ + IMPORT_C TInt StopVpnConnection( TUint32 aVpnIapId, + TKmdStopConnection::TType aType = TKmdStopConnection::ENormal ); + + /** + * Resolve an IP address from FQDN. + * There can be only one outstanding query per session. + * @param aVpnIapId Used VPN IAP Id + * @param aFqdn: Domain Name to be resolved. + * @param aResult: Result of name resolution (returned) + * @param aStatus: Completion status (returned) + */ + IMPORT_C void ResolveAddress( TUint32 aVpnIapId, + const TDesC& aFqdn, + TNameEntry& aResult, + TRequestStatus& aStatus ) const; + /** + * Cancel outstanding resolve address query. + */ + IMPORT_C void CancelResolve() const; + }; + +#endif // R_KMD_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdapi/rom/kmdapi.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdapi/rom/kmdapi.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Image description file for project +* Key Management Daemon API +* +*/ + + + +#ifndef __KMDAPI_IBY__ +#define __KMDAPI_IBY__ + +#ifdef SYMBIAN_EXCLUDE_IPSEC + +REM Feature KMDAPI not included in this rom + +#else + +file=ABI_DIR\BUILD_DIR\kmdapi.dll SHARED_LIB_DIR\kmdapi.dll + +#endif // SYMBIAN_EXCLUDE_IPSEC + +#endif // __KMDSERVER_IBY__ + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdapi/src/kmdapi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdapi/src/kmdapi.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,148 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Key Management Daemon API +* +*/ + +// EXTERNAL INCLUDES +#include +#include + +// INTERNAL INCLUDES +#include "kmdserver.h" +#include "clistatic.h" + +// CLASS HEADER +#include "kmdapi.h" + +// --------------------------------------------------------------------------- +// Opens a session to KMD server and starts the server if it is not yet +// started. +// --------------------------------------------------------------------------- +// +EXPORT_C TInt RKMD::Connect() + { + TInt retry=2; + for ( ;; ) + { + TInt r = CreateSession( KKmdServerName, + TVersion( KKmdServMajorVersion, + KKmdServMinorVersion, + KKmdServBuildVersion), + KDefaultMessageSlots ); + + if ( r != KErrNotFound && r != KErrServerTerminated ) + { + return r; + } + if ( --retry == 0 ) + { + return r; + } + r = Launcher::LaunchServer( KKmdServerName, + KKmdServerImg, + KServerUid3, + KMyServerInitHeapSize, + KMyServerMaxHeapSize, + KMyServerStackSize ); + if ( r != KErrNone && r != KErrAlreadyExists ) + { + return r; + } + } + } + +// --------------------------------------------------------------------------- +// Start a real network connection. +// --------------------------------------------------------------------------- +// +EXPORT_C void RKMD::StartRealConnection( TUint32 aVpnIapId, + TPckg& aRealConfig, + TRequestStatus& aStatus ) const + { + SendReceive( CKmdServer::KKmdStartConnection, + TIpcArgs( aVpnIapId, &aRealConfig ), + aStatus ); + } + +// --------------------------------------------------------------------------- +// Cancels ongoing activate request. +// --------------------------------------------------------------------------- +// +EXPORT_C void RKMD::CancelStartRealConnection() const + { + SendReceive( CKmdServer::KKmdCancelStartConnection ); + } + +// --------------------------------------------------------------------------- +// Asynchronous Activate request. +// --------------------------------------------------------------------------- +// +EXPORT_C void RKMD::Activate( TUint32 aVpnIapId, + const TDesC& aVpnIfName, + const TDesC8& aIkeConf, + TVPNAddressPckg& aVPNAddress, + TRequestStatus& aStatus ) const + { + SendReceive( CKmdServer::KKmdActivateAsync, + TIpcArgs( aVpnIapId, + &aVpnIfName, + &aIkeConf, + &aVPNAddress ), + aStatus ); + } + +// --------------------------------------------------------------------------- +// Cancels ongoing Activate request. +// --------------------------------------------------------------------------- +// +EXPORT_C void RKMD::CancelActivate() const + { + SendReceive( CKmdServer::KKmdCancelActivateAsync ); + } + +// --------------------------------------------------------------------------- +// Stops specified VPN connection. +// --------------------------------------------------------------------------- +// +EXPORT_C TInt RKMD::StopVpnConnection( TUint32 aVpnIapId, + TKmdStopConnection::TType aType ) + { + return SendReceive( CKmdServer::KKmdStopConnection, + TIpcArgs( aVpnIapId, aType ) ); + } + +// --------------------------------------------------------------------------- +// Resolve an IP address from FQDN. +// --------------------------------------------------------------------------- +// +EXPORT_C void RKMD::ResolveAddress( TUint32 aVpnIapId, + const TDesC& aFqdn, + TNameEntry& aResult, + TRequestStatus& aStatus ) const + { + SendReceive( CKmdServer::KKmdResolveAddress, + TIpcArgs( aVpnIapId, &aFqdn, &aResult ), + aStatus ); + } + +// --------------------------------------------------------------------------- +// Cancel outstanding ResolveAddress query. +// --------------------------------------------------------------------------- +// +EXPORT_C void RKMD::CancelResolve() const + { + SendReceive( CKmdServer::KKmdCancelResolveAddress ); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/bwins/KMDSERVERU.DEF --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/bwins/KMDSERVERU.DEF Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?RunKmdServer@@YAHPAX@Z @ 1 NONAME ; int __cdecl RunKmdServer(void *) + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Build information file +* +*/ + + +#include + +PRJ_PLATFORMS + +PRJ_EXPORTS + + +PRJ_MMPFILES +#ifdef VPNCLIENT_USE_STUBS + kmdservertest.mmp +#else + kmdserver.mmp +#endif + +PRJ_TESTMMPFILES + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/group/kmdserver.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/group/kmdserver.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project kmdserver +* +*/ + +#include + +TARGET kmdserver.exe +TARGETTYPE exe +UID 0x1000008d 0x1000088A + +CAPABILITY CAP_SERVER CommDD NetworkControl +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE activationstarter.cpp +SOURCE connectionstarter.cpp +SOURCE connectionstopper.cpp +SOURCE disconnectionobserver.cpp +SOURCE fqdnresolver.cpp +SOURCE errorobserver.cpp +SOURCE iachangeobserver.cpp +SOURCE ikepluginhandler.cpp +SOURCE ikepluginsessionhandler.cpp +SOURCE ikepcaptrace.cpp +SOURCE kmddebuglogger.cpp +SOURCE kmdeventlogger.cpp +SOURCE kmdserver.cpp +SOURCE kmdsession.cpp +SOURCE kmdstarter.cpp +SOURCE secpolpayload.cpp +SOURCE secpolreader.cpp +SOURCE vpnconnection.cpp + +SOURCEPATH ../../vpncommon/src +SOURCE srvstatic.cpp + +USERINCLUDE ../inc +USERINCLUDE ../../kmdapi/inc +USERINCLUDE ../../ikepolparser/inc +USERINCLUDE ../../vpnmanager/inc +USERINCLUDE ../../eventmediatorapi/inc +USERINCLUDE ../../vpncommon/inc +USERINCLUDE ../../eventviewer/inc +USERINCLUDE ../../ikesocket/inc +USERINCLUDE ../../ikeutils/inc + +MW_LAYER_SYSTEMINCLUDE +SYSTEMINCLUDE /epoc32/include/networking + +LIBRARY bafl.lib +LIBRARY cmmanager.lib +LIBRARY efsrv.lib +LIBRARY euser.lib +LIBRARY esock.lib +LIBRARY eventmedapi.lib +LIBRARY eventviewer.lib +LIBRARY ikesocket.lib +LIBRARY ikepolparser.lib +LIBRARY insock.lib +LIBRARY ipsecpolapi.lib +DEBUGLIBRARY flogger.lib + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/group/kmdservertest.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/group/kmdservertest.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,77 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Test project definition file for project kmdserver +* +*/ + +#include + +TARGET kmdserver.exe +TARGETTYPE exe +UID 0x1000008d 0x1000088A + +CAPABILITY CAP_SERVER CommDD NetworkControl +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE activationstarter.cpp +SOURCE connectionstarter.cpp +SOURCE connectionstopper.cpp +SOURCE disconnectionobserver.cpp +SOURCE fqdnresolver.cpp +SOURCE errorobserver.cpp +SOURCE iachangeobserver.cpp +SOURCE ikepluginhandler.cpp +SOURCE ikepluginsessionhandler.cpp +SOURCE ikepcaptrace.cpp +SOURCE kmddebuglogger.cpp +SOURCE kmdeventlogger.cpp +SOURCE kmdserver.cpp +SOURCE kmdsession.cpp +SOURCE kmdstarter.cpp +SOURCE secpolpayload.cpp +SOURCE secpolreader.cpp +SOURCE vpnconnection.cpp + +SOURCEPATH ../../vpncommon/src +SOURCE srvstatic.cpp + +USERINCLUDE ../inc +USERINCLUDE ../../kmdapi/inc +USERINCLUDE ../../ikepolparser/inc +USERINCLUDE ../../vpnmanager/inc +USERINCLUDE ../../eventmediatorapi/inc +USERINCLUDE ../../vpncommon/inc +USERINCLUDE ../../eventviewer/inc +USERINCLUDE ../../ikesocket/inc +USERINCLUDE ../../ikeutils/inc + +MW_LAYER_SYSTEMINCLUDE +SYSTEMINCLUDE /epoc32/include/networking + +LIBRARY kmd_proxy.lib +LIBRARY ikesocket_proxy.lib +LIBRARY bafl.lib +LIBRARY cmmanager.lib +LIBRARY efsrv.lib +LIBRARY euser.lib +LIBRARY esock.lib +LIBRARY eventmedapi.lib +LIBRARY eventviewer.lib +LIBRARY ikesocket.lib +LIBRARY ikepolparser.lib +LIBRARY insock.lib +LIBRARY ipsecpolapi.lib +DEBUGLIBRARY flogger.lib + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/activationstarter.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/activationstarter.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,156 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: active object, that monitors activating +* +*/ + + +#ifndef C_ACTIVATIONSTARTER_H +#define C_ACTIVATIONSTARTER_H + +#include +#include + +#include "vpnmandefs.h" +#include "ikesocketdefs.h" + +// FORWARD DECLARATIONS +class CIkeData; +class CVpnConnection; +class MIkeDebug; +class TVPNAddress; + +/** + * Activation starter callback interface. + * Callback interface which is used by CActivationStarter object to notify + * about completion of activation. + * + * @lib internal (kmdserver.exe) + */ +class MActivationStarterCallback + { +public: + /** + * Notifies about completion of activation. + * @param aStatus Completion status + * @param aVirtualIp Internal address info + */ + virtual void ActivationCompleted( TInt aStatus, + const TVPNAddress& aVirtualIp ) = 0; + }; + + +/** + * Activating starter. + * Active object provides functionality for starting activating. + * + * @lib internal (kmdserver.exe) + */ +class CActivationStarter : public CActive + { +public: + /** + * Two-phased constructor. + * @param aConnection VPN connection object + * @param aCallback Callback interface + * @param aDebug Debug trace interface + */ + static CActivationStarter* NewL( CVpnConnection& aConnection, + MActivationStarterCallback& aCallback, + MIkeDebug& aDebug ); + + /** + * Destructor. + */ + ~CActivationStarter(); + + /** + * Starts activating. Completion is notified via + * MActivatingStarterCallback interface. + * @param aIkeConf IKE policy data + * @param aVpnIfName VPN interface name + */ + void Activate( CIkeData& aIkeData, + const TDesC& aVpnIfName ); + +private: + + CActivationStarter( CVpnConnection& aConnection, + MActivationStarterCallback& aCallback, + MIkeDebug& aDebug ); + + /** + * Gets VPN interface index. + * @param aVpnIfName VPN interface name + * @param aVpnInterfaceIndex VPN interface index (returned) + * @return Error code + */ + TInt GetVpnInterfaceIndex( const TDesC& aVpnIfName, + TUint32& aVpnInterfaceIndex ); + +// from base class CActive + + /** + * From CActive + * Handles completion of asynchronous activating. + */ + void RunL(); + + /** + * From CActive + * Handles cancellation of asynchronous activating. + */ + void DoCancel(); + +private: // data + + /** + * Internal address. + * Own. + */ + TVPNAddress iInternalAddress; + + /** + * IP version. + * Own. + */ + IkeSocket::TIpVersion iIpVersion; + + /** + * DNS server address from IKE policy data. + * Own. + */ + TInetAddr iDnsServerAddr; + + /** + * VPN connection object. + * Not own. + */ + CVpnConnection& iConnection; + + /** + * Callback interface. + * Not own. + */ + MActivationStarterCallback& iCallback; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + }; + + +#endif // C_ACTIVATIONSTARTER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/connectionstarter.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/connectionstarter.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,112 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: active object, that monitors the real connection starting +* +*/ + + +#ifndef C_CONNECTIONSTARTER_H +#define C_CONNECTIONSTARTER_H + +#include + +// FORWARD DECLARATIONS +class CVpnConnection; + +/** + * Connection starter callback interface. + * Callback interface which is used by CConnectionStarter object to notify + * about completion of real network connection's starting. + * + * @lib internal (kmdserver.exe) + */ +class MConnectionStarterCallback + { +public: + /** + * Notifies about completion of real connection starting. + * @param aStatus Completion status + * @param aRealIapId IAP Id of started connection + * @param aRealNetId Net Id of started connection + */ + virtual void RealConnectionStarted( TInt aStatus, + TInt aRealIapId, + TInt aRealNetId ) = 0; + }; + + +/** + * Connection starter. + * Active object provides functionality for starting of real network + * connection. + * + * @lib internal (kmdserver.exe) + */ +class CConnectionStarter : public CActive + { +public: + /** + * Two-phased constructor. + * @param aConnection VPN connection object + * @param aCallback Callback interface + */ + static CConnectionStarter* NewL( CVpnConnection& aConnection, + MConnectionStarterCallback& aCallback ); + + /** + * Destructor. + */ + ~CConnectionStarter(); + + /** + * Starts real network connection. Completion is notified via + * MConnectionStarterCallback interface. + */ + void StartRealConnection(); + +private: + + CConnectionStarter( CVpnConnection& aConnection, + MConnectionStarterCallback& aCallback ); + +// from base class CActive + + /** + * From CActive + * Handles completion of asynchronous connection starting request. + */ + void RunL(); + + /** + * From CActive + * Handles cancellation of asynchronous connection starting request. + */ + void DoCancel(); + +private: // data + + /** + * VPN connection object. + * Not own. + */ + CVpnConnection& iConnection; + + /** + * Callback interface. + * Not own. + */ + MConnectionStarterCallback& iCallback; + }; + +#endif // C_CONNECTIONSTARTER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/connectionstopper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/connectionstopper.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: active object, that monitors stopping of connection +* +*/ + + +#ifndef C_CONNECTIONSTOPPER_H +#define C_CONNECTIONSTOPPER_H + +#include + +// FORWARD DECLARATIONS +class CVpnConnection; + +/** + * Connection stopper callback interface. + * Callback interface which is used by CConnectionStopper object to notify + * about completion of VPN connection stopping. + * + * @lib internal (kmdserver.exe) + */ +class MConnectionStopperCallback + { +public: + /** + * Notifies about completion of VPN connection stopping. + * @param aStatus Completion status + */ + virtual void VpnConnectionStopped( TInt aStatus ) = 0; + }; + +/** + * Connection stopper. + * Active object provides functionality for stopping of VPN connection. + * + * @lib internal (kmdserver.exe) + */ +class CConnectionStopper : public CActive + { +public: + /** + * Two-phased constructor. + * @param aConnection VPN connection object + * @param aCallback Callback interface + */ + static CConnectionStopper* NewL( CVpnConnection& aVpnConnection, + MConnectionStopperCallback& aCallback ); + + /** + * Destructor. + */ + ~CConnectionStopper(); + + /** + * Stops VPN connection. Completion is notified via MConnectionStopperCallback + * interface. + * @param aSilentClose Specified if a silent close in question (Delete + * payloads not transmitted to remote host) + */ + void StopVpnConnection( TBool aSilentClose ); + +private: + CConnectionStopper( CVpnConnection& aVpnConnection, + MConnectionStopperCallback& aCallback ); + +// from base class CActive + + /** + * From CActive + * Handles completion of asynchronous connection stopping request. + */ + void RunL(); + + /** + * From CActive + * Handles cancellation of asynchronous connection stopping request. + */ + void DoCancel(); + +private: // data + + /** + * VPN connection object. + * Not own. + */ + CVpnConnection& iVpnConnection; + + /** + * Callback interface. + * Not own. + */ + MConnectionStopperCallback& iCallback; + }; + +#endif // C_CONNECTIONSTOPPER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/disconnectionobserver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/disconnectionobserver.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: active object, that monitors link disconnection +* +*/ + + +#ifndef C_DISCONNECTIONOBSERVER_H +#define C_DISCONNECTIONOBSERVER_H + +#include + +// FORWARD DECLARATIONS +class CIkeConnectionInterface; + +/** + * Disconnection observer callback interface. + * Callback interface which is used by CDisconnectionObserver object to notify + * about link disconnection. + * + * @lib internal (kmdserver.exe) + */ +class MDisconnectionObserverCallback + { +public: + /** + * Notifies about disconnection. + * @param aStatus Completion status + */ + virtual void DisconnectIndication( TInt aStatus ) = 0; + }; + +/** + * Disconnection observer. + * Active object provides functionality for notifying link disconnection. + * + * @lib internal (kmdserver.exe) + */ +class CDisconnectionObserver : public CActive + { +public: + /** + * Two-phased constructor. + * @param aIkeConnectionInterface IKE connection interface + * @param aCallback Callback interface + */ + static CDisconnectionObserver* NewL( CIkeConnectionInterface& aIkeConnectionInterface, + MDisconnectionObserverCallback& aCallback ); + + /** + * Destructor. + */ + ~CDisconnectionObserver(); + + /** + * Starts observing Link disconnection. Link disconnection is notified via + * MDisconnectionObserverCallback interface. + */ + void StartObserving(); + +private: + + CDisconnectionObserver( CIkeConnectionInterface& aIkeConnectionInterface, + MDisconnectionObserverCallback& aCallback ); + +// from base class CActive + + /** + * From CActive + * Handles completion of asynchronous notification request. + */ + void RunL(); + + /** + * From CActive + * Handles cancellation of asynchronous notification request. + */ + void DoCancel(); + +private: // data + + /** + * IKE connection interface. + * Not own. + */ + CIkeConnectionInterface& iIkeConnectionInterface; + + /** + * Callback interface. + * Not own. + */ + MDisconnectionObserverCallback& iCallback; + }; + + +#endif // C_DISCONNECTIONOBSERVER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/errorobserver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/errorobserver.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,103 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: active object, that monitors IKE plugin session error +* +*/ + + +#ifndef C_ERROROBSERVER_H +#define C_ERROROBSERVER_H + +#include + +// FORWARD DECLARATIONS +class MIkeDebug; +class MIkePluginSessionIf; +class MIkePluginSessionHandlerCallback; + +/** + * Error observer. + * Active object that provides functionality for observing IKE plugin session + * error. + * + * @lib internal (kmdserver.exe) + */ +class CErrorObserver : public CActive + { +public: + /** + * Two-phased constructor. + * @param aIkePluginSession IKE plugin session + * @param aCallback Callback interface + * @param aDebug Debug trace interface + */ + static CErrorObserver* NewL( MIkePluginSessionIf& aIkePluginSession, + MIkePluginSessionHandlerCallback& aCallback, + MIkeDebug& aDebug ); + + /** + * Destructor. + */ + ~CErrorObserver(); + + /** + * Starts observing internal address change. + */ + void StartObserving(); + +private: + + CErrorObserver( MIkePluginSessionIf& aIkePluginSession, + MIkePluginSessionHandlerCallback& aCallback, + MIkeDebug& aDebug ); + + void ConstructL(); + +// from base class CActive + + /** + * From CActive + * Handles completion of asynchronous notification request. + */ + void RunL(); + + /** + * From CActive + * Handles cancellation of asynchronous notification request. + */ + void DoCancel(); + +private: // data + + /** + * IKE plugin session. + * Not own. + */ + MIkePluginSessionIf& iIkePluginSession; + + /** + * Callback interface. + * Not own. + */ + MIkePluginSessionHandlerCallback& iCallback; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + }; + + +#endif // C_ERROROBSERVER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/fqdnresolver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/fqdnresolver.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,122 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: active object, that monitors the completion of FQDN resolve. +* +*/ + + +#ifndef C_FQDNRESOLVER_H +#define C_FQDNRESOLVER_H + +#include +#include + +// FORWARD DECLARATIONS +class CVpnConnection; + +/** + * FQDN resolver callback interface. + * Callback interface which is used by CFqdnResolver object to notify + * about completion of FQDN address resolving. + * + * @lib internal (kmdserver.exe) + */ +class MFqdnResolverCallback + { +public: + /** + * Notifies about completion of FQDN address resolving. + * @param aStatus Completion status + * @param aNameEntry Result of name resolution + */ + virtual void AddressResolveCompleted( const TInt aStatus, + const TNameEntry aNameEntry ) = 0; + }; + +/** + * FQDN address resolver. + * Active object provides functionality for resolving an IP address from FQDN + * address. + * + * @lib internal (kmdserver.exe) + */ +class CFqdnResolver : public CActive + { +public: + /** + * Two-phased constructor. + * @param aConnection VPN connection object + * @param aCallback Callback interface + */ + static CFqdnResolver* NewL( CVpnConnection& aConnection, + MFqdnResolverCallback& aCallback ); + /** + * Destructor. + */ + ~CFqdnResolver(); + + /** + * Resolves IP address from FQDN address. Completion is notified via + * MFqdnResolverCallback interface. + * @param aFqdn FQDN address. Ownership transferred. + */ + void ResolveAddress( HBufC* aFqdn ); + +private: + + CFqdnResolver( CVpnConnection& aConnection, + MFqdnResolverCallback& aCallback ); + +// from base class CActive + + /** + * From CActive + * Handles completion of asynchronous resolving request. + */ + void RunL(); + + /** + * From CActive + * Handles cancellation of asynchronous resolving request. + */ + void DoCancel(); + +private: // data + + /** + * VPN connection object. + * Not own. + */ + CVpnConnection& iConnection; + + /** + * FQDN address + * Own. + */ + HBufC* iFqdn; + + /** + * Name entry. + * Own. + */ + TNameEntry iNameEntry; + + /** + * Callback interface. + * Not own. + */ + MFqdnResolverCallback& iCallback; + }; + +#endif // C_FQDNRESOLVER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/iachangeobserver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/iachangeobserver.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,126 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: active object, that monitors internal address change +* +*/ + + +#ifndef C_IACHANGEOBSERVER_H +#define C_IACHANGEOBSERVER_H + +#include +#include "eventmediatorapi.h" + +// FORWARD DECLARATIONS +class CInternalAddress; +class MIkeDebug; +class MIkePluginSessionIf; +class TInetAddr; + +/** + * IA change observer. + * Active object that provides functionality for observing internal address + * change. + * + * @lib internal (kmdserver.exe) + */ +class CIaChangeObserver : public CActive + { +public: + /** + * Two-phased constructor. + * @param aVpnIapId VPN IAP id + * @param aDnsServerAddr DNS server address from IKE policy + * @param aIkePluginSession IKE plugin session + * @param aDebug Debug trace interface + */ + static CIaChangeObserver* NewL( TUint32 aVpnIapId, + const TInetAddr& aDnsServerAddr, + MIkePluginSessionIf& aIkePluginSession, + MIkeDebug& aDebug ); + + /** + * Destructor. + */ + ~CIaChangeObserver(); + + /** + * Starts observing internal address change. + */ + void StartObserving(); + +private: + + CIaChangeObserver( TUint32 aVpnIapId, + const TInetAddr& aDnsServerAddr, + MIkePluginSessionIf& aIkePluginSession, + MIkeDebug& aDebug ); + + void ConstructL(); + +// from base class CActive + + /** + * From CActive + * Handles completion of asynchronous notification request. + */ + void RunL(); + + /** + * From CActive + * Handles cancellation of asynchronous notification request. + */ + void DoCancel(); + +private: // data + + /** + * Event mediator. + * Own. + */ + REventMediator iEventMediator; + + /** + * VPN IAP Id. + * Own. + */ + TUint32 iVpnIapId; + + /** + * DNS server address. + * Own. + */ + TInetAddr iDnsServerAddr; + + /** + * Internal address. + * Own. + */ + TVPNAddress iInternalAddress; + + /** + * IKE plugin session. + * Not own. + */ + MIkePluginSessionIf& iIkePluginSession; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + }; + + +#endif // C_IACHANGEOBSERVER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/ikedebug.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/ikedebug.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Definitions for logging in debug builds +* +*/ + +#ifndef M_IKEDEBUG_H +#define M_IKEDEBUG_H + +#include + +#ifndef _DEBUG + +class MIkeDebug + { +public: + }; + + +#define DEBUG_LOG(a) +#define DEBUG_LOG1(a, b) +#define DEBUG_LOG2(a, b, c) +#define DEBUG_LOG3(a, b, c, d) +#define DEBUG_LOG_ARRAY(a, b) +#define DEBUG_LOG_NUM(a) +#define TRACE_MSG(aMsg, aSrcAddr, aDstAddr, aEncryptType) + +#else + +#include "ikepcaptrace.h" + +// FORWARD DECLARATIONS +class TInetAddr; + +/** + * KMD debug interface for logging in debug builds. + * @lib internal (kmdserver.exe) + */ +class MIkeDebug + { +public: + + virtual void LogWrite( const TDesC& aText ) = 0; + virtual void LogWrite( const TDesC8& aText ) = 0; + + virtual void LogWriteF( TRefByValue aFmt, ... ) = 0; + virtual void LogWriteF( TRefByValue aFmt, ... ) = 0; + + virtual void LogWriteArray( const TUint8* aArray, TInt aLength ) = 0; + + virtual void LogWriteNum( TUint aNum ) = 0; + + virtual void TraceMessage( const TDesC8& aMessage, + const TInetAddr& aSourceAddress, + const TInetAddr& aDestinationAddress, + CIkePcapTrace::TEncryptionType aEncryptionType ) = 0; + + }; + +#define DEBUG_LOG(a) iDebug.LogWrite((a)) +#define DEBUG_LOG1(a, b) iDebug.LogWriteF((a), (b)) +#define DEBUG_LOG2(a, b, c) iDebug.LogWriteF((a), (b), (c)) +#define DEBUG_LOG3(a, b, c, d) iDebug.LogWriteF((a), (b), (c), (d)) +#define DEBUG_LOG_ARRAY(a, b) iDebug.LogWriteArray((a), (b)) +#define DEBUG_LOG_NUM(a) iDebug.LogWriteNum((a)) + +#define TRACE_MSG(aMsg, aSrcAddr, aDstAddr, aEncryptType) iDebug.TraceMessage((aMsg), (aSrcAddr), (aDstAddr), (aEncryptType)) +#define TRACE_MSG_IKEV1(aMsg, aSrcAddr, aDstAddr ) iDebug.TraceMessage((aMsg), (aSrcAddr), (aDstAddr), (CIkePcapTrace::EEncrDes)) + +#endif //_DEBUG +#endif //M_IKEDEBUG_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/ikepcaptrace.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/ikepcaptrace.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,90 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class that logs ike messages in pcap format +* +*/ + +#ifndef IKEPCAPTRACE_H +#define IKEPCAPTRACE_H + +#include + +class TInetAddr; + +/** + * PCap tracer of IKE messages. + * + * Class that logs ike messages in pcap format + * + */ +class CIkePcapTrace : public CBase + { +public: + enum TEncryptionType + { + EEncrDes = 2, + EEncrDes3 = 3, + EEncrAesCbc = 12 + }; + + static CIkePcapTrace* NewL(const TDesC& aLogFolder); + ~CIkePcapTrace(); + + + /** + * Traces the IKE message. + * + * @param aMessage Traced IKE message + * @param aSourceAddress IP address of the message sender (only IPv4 is supported) + * @param aDestinationAddress IP address of the message receiver (only IPv4 is supported) + * @param aEncryptionType Used encryption algorithm. + * If the aMessage datagram is IKEv1 or if the IKEv2 datagram + * does not contain encryption payload this parameter is not used. + */ + void TraceMessage(const TDesC8& aMessage, + const TInetAddr& aSourceAddress, + const TInetAddr& aDestinationAddress, + TEncryptionType aEncryptionType); + +private: + CIkePcapTrace(); + void ConstructL(const TDesC& aLogFolder); + + void DoTraceMessage(TPtr8& aMsgCopy, + const TInetAddr& aSourceAddress, + const TInetAddr& aDestinationAddress, + TEncryptionType aEncryptionType); + + + TInt WritePcapHeader(); + + TInt WriteRecordHeader(TUint32 aIkeMsgLength); + TInt WriteIpAndUdpHeader(const TDesC8& aMessage, + TInetAddr aSourceAddress, + TInetAddr aDestinationAddress); + TInt WriteNonEspMarker(); + TInt WriteIkeMessage(TPtr8& aMsgCopy, TEncryptionType aEncryptionType); + TInt WriteIkeV1Message(TPtr8& aMsgCopy); + TInt WriteIkeV2Message(TPtr8& aMsgCopy, TEncryptionType aEncryptionType); + + + RFs iFileServer; + RFile iPcapFile; + + TBool iWriteTrace; + }; + +#endif //IKEPCAPTRACE_H + + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/ikeplugindefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/ikeplugindefs.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE plugin definitions +* +*/ + + +#ifndef IKEPLUGINDEFS_H +#define IKEPLUGINDEFS_H + +#include + +typedef TUid TIkePluginId; + +const TUid KIkePluginUid1 = { KDynamicLibraryUidValue }; +const TUid KIkePluginUid2 = { KSharedLibraryUidValue }; + +const TUid KIkeV1PluginUid3 = { 0x10206994 }; +const TUid KIkeV2PluginUid3 = { 0x10206993 }; + +const TInt KIkeV1( 1 ); +const TInt KIkeV2( 2 ); +const TInt KIkePluginMaxCount( 2 ); + +#endif // IKEPLUGINDEFS_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/ikepluginhandler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/ikepluginhandler.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,155 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Handler of an IKE protocol plugin +* +*/ + + +#ifndef C_IKEPLUGINHANDLER_H +#define C_IKEPLUGINHANDLER_H + +#include +#include "ikepluginsessionhandler.h" +#include "ikesocketdefs.h" + +// FORWARD DECLARATIONS +class CIkePluginSessionHandler; +class MIkeDebug; +class MIkePluginIf; +class MKmdEventLoggerIf; + +/** + * IKE plugin handler. + * IKE plugin specific handler for creating and deleting IKE plugin sessions. + * + * @lib internal (kmdserver.exe) + */ +class CIkePluginHandler : public CBase + { +public: + /** + * Two-phased constructor. + * @param aIkeVersion IKE version + * @param aEventLogger Event logger + * @param aDebug Debug trace interface + */ + static CIkePluginHandler* NewL( TInt aIkeVersion, + MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ); + + /** + * Destructor. + */ + ~CIkePluginHandler(); + + /** + * Creates IKE plugin session. + * @param aVpnIapId VPN IAP id + * @param aVpnNetId VPN NET id + * @param aVpnInterfaceIndex VPN interface index + * @param aIpVersion IP version + * @param aDnsServer DNS server from IKE policy + * @param aConnection IKE connection interface + * @param aCallback Callback interface + * @return Handler of IKE plugin session + */ + CIkePluginSessionHandler& CreateIkePluginSessionL( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + IkeSocket::TIpVersion aIpVersion, + const TInetAddr& aDnsServer, + CIkeConnectionInterface& aConnection, + MIkePluginSessionHandlerCallback& aCallback ); + + /** + * Deletes IKE plugin session which matches VPN IAP id. Does nothing if + * session is not found. + * @param aVpnIapId VPN IAP Id + */ + void DeleteIkePluginSession( TUint32 aVpnIapId ); + +private: + CIkePluginHandler( TInt aIkeVersion, + MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ); + + /** + * Creates IKE plugin session. + * @param aVpnIapId VPN IAP id + * @param aVpnNetId VPN NET id + * @param aVpnInterfaceIndex VPN interface index + * @param aIpVersion IP version + * @param aDnsServerAddr DNS server address from IKE policy + * @param aConnection IKE connection interface + * @param aCallback Callback interface + */ + CIkePluginSessionHandler& DoCreateIkePluginSessionL( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + IkeSocket::TIpVersion aIpVersion, + const TInetAddr& aDnsServerAddr, + CIkeConnectionInterface& aConnection, + MIkePluginSessionHandlerCallback& aCallback ); + + /** + * Loads IKE plugin. + */ + void LoadIkePluginL(); + + /** + * Unloads IKE plugin. + */ + void UnloadIkePlugin(); + +private: // data + + /** + * IKE version. + * Own. + */ + TInt iIkeVersion; + + /** + * Handle for IKE plugin library. + * Own. + */ + RLibrary iLibrary; + + /** + * IKE plugin. + * Own. + */ + MIkePluginIf* iIkePlugin; + + /** + * IKE plugin session handlers. + * Own. + */ + RPointerArray iIkePluginSessions; + + /** + * Event logger. + * Not own. + */ + MKmdEventLoggerIf& iEventLogger; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + }; + + +#endif // C_IKEPLUGINHANDLER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/ikepluginif.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/ikepluginif.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE protocol plugin interface +* +*/ + + +#ifndef M_IKEPLUGINIF_H +#define M_IKEPLUGINIF_H + +#include + +// FORWARD DECLARATIONS +class MIkeDataInterface; +class MIkeDebug; +class MIkePluginSessionIf; +class MKmdEventLoggerIf; + +/** + * IKE protocol plugin interface. + * + * IKE protocol plugin interface provides functionality for creating IKE + * protocol plugin sessions. + * + * @lib internal (kmdserver.exe) + */ +class MIkePluginIf + { +public: + + /** + * Destructor. + */ + virtual ~MIkePluginIf() {}; + + /** + * Creates IKE protocol plugin session. + * @param aVpnIapId VPN IAP id + * @param aVpnNetId VPN NET id + * @param aVpnInterfaceIndex VPN interface index + * @param aDataInterface IKE data interface + * @return IKE protocol plugin session interface. Ownership transferred. + */ + virtual MIkePluginSessionIf* CreateSessionL( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + MIkeDataInterface& aIkeDataInterface ) = 0; + }; + + +/** + * Method prototype to create new protocol plugin + */ +typedef MIkePluginIf* (*CreateIkePluginL)(MKmdEventLoggerIf&, MIkeDebug&); + +#endif // M_IKEPLUGINIF_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/ikepluginsessionhandler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/ikepluginsessionhandler.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,242 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Handler of an IKE protocol plugin session +* +*/ + + +#ifndef C_IKEPLUGINSESSIONHANDLER_H +#define C_IKEPLUGINSESSIONHANDLER_H + +#include +#include "vpnmandefs.h" +#include "ikesocketdefs.h" + +// FORWARD DECLARATIONS +class CErrorObserver; +class CIaChangeObserver; +class CIkeData; +class CIkeConnectionInterface; +class CIkePluginSessionCloser; +class CInternalAddress; +class MIkeDataInterface; +class MIkeDebug; +class MIkePluginIf; +class MIkePluginSessionIf; +class TInetAddr; + +/** + * IKE plugin session handler callback interface. + * Callback interface which is used by CIkePluginSessionHandler object to + * notify about completion of negotiate and delete session requests. + * + * @lib internal (kmdserver.exe) + */ +class MIkePluginSessionHandlerCallback + { +public: + /** + * Notifies about completion of negotiate request. + * @param aStatus Completion status + * @param aInternalAddress Internal address + */ + virtual void NegotiationStarted( TInt aStatus, + const TVPNAddress& aInternalAddress ) = 0; + /** + * Notifies about completion of delete session request. + * @param aStatus Completion status + */ + virtual void IkePluginSessionClosed( TInt aStatus ) = 0; + + /** + * Notifies about IKE plugin session error. + * @param aStatus Completion status + */ + virtual void IkePluginSessionError( TInt aStatus ) = 0; + }; + +/** + * IKE plugin session handler. + * Provides functionality for handling IKE plugin session. + * + * @lib internal (kmdserver.exe) + */ +class CIkePluginSessionHandler : public CActive + { +public: + /** + * Two-phased constructor. + * @param aVpnIapId VPN IAP id + * @param aVpnNetId VPN NET id + * @param aVpnInterfaceIndex VPN interface index + * @param aIkeVersion IKE version + * @param aIpVersion IP version + * @param aDnsServerAddr DNS server address from IKE policy + * @param aConnection IKE connection interface + * @param aIkePlugin IKE plugin + * @param aCallback Callback interface + * @param aDebug Debug trace interface + */ + static CIkePluginSessionHandler* NewLC( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + IkeSocket::TIkeMajorVersion aIkeVersion, + IkeSocket::TIpVersion aIpVersion, + const TInetAddr& aDnsServerAddr, + CIkeConnectionInterface& aConnection, + MIkePluginIf& aIkePlugin, + MIkePluginSessionHandlerCallback& aCallback, + MIkeDebug& aDebug ); + /** + * Destructor. IKE plugin session object is deleted. + */ + ~CIkePluginSessionHandler(); + + /** + * Starts negotiation with a remote host. + * @param aIkeData IKE policy data + */ + void NegotiateWithHost( const CIkeData& aIkeData ); + + /** + * Cancels negotiation request. + */ + void CancelNegotiateWithHost(); + + /** + * Deletes session. Silent close can be requested when normal close is + * already active. IKE plugin session object is not deleted. + * @param aSilentClose Specified if a silent close in question (Delete + * payloads not transmitted to remote host) + */ + void DeleteSession( TBool aSilentClose ); + + /** + * Cancels session deletion requests. IKE/IPSec SA:s are deleted. IKE + * plugin session object is not deleted. + */ + void CancelDeleteSession(); + + /** + * Returns VPN IAP Id. + * @return VPN IAP Id + */ + TInt VpnIapId() const; + +// from base class CActive + + /** + * From CActive + * Handles completion of asynchronous request. + */ + void RunL(); + + /** + * From CActive + * Handles cancellation of asynchronous request. + */ + void DoCancel(); + +private: + enum TState + { + EIdle, + ENegotiatingWithHost, + ENegotiated, + EDeletingSession + }; + + CIkePluginSessionHandler( TUint32 aVpnIapId, + IkeSocket::TIkeMajorVersion aIkeVersion, + IkeSocket::TIpVersion aIpVersion, + MIkePluginSessionHandlerCallback& aCallback, + MIkeDebug& aDebug ); + + void ConstructL( TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + const TInetAddr& aDnsServer, + CIkeConnectionInterface& aConnection, + MIkePluginIf& aIkePlugin ); + +private: // data + + /** + * State. + * Own. + */ + TState iState; + + /** + * VPN IAP Id. + * Own. + */ + TUint32 iVpnIapId; + + /** + * IKE version. + * Own. + */ + IkeSocket::TIkeMajorVersion iIkeVersion; + + /** + * IP version. + * Own. + */ + IkeSocket::TIpVersion iIpVersion; + + /** + * IKE plugin session interface. + * Own. + */ + MIkePluginSessionIf* iIkePluginSession; + + /** + * Internal address. + * Own. + */ + TVPNAddress iInternalAddress; + + /** + * IKE plugin session error observer. + * Own. + */ + CErrorObserver* iErrorObserver; + + /** + * Internal address change observer. + * Own. + */ + CIaChangeObserver* iIaChangeObserver; + + /** + * IKE data interface. + * Not own. + */ + MIkeDataInterface* iIkeDataInterface; + + /** + * Callback interface. + * Not own. + */ + MIkePluginSessionHandlerCallback& iCallback; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + }; + + +#endif // C_IKEPLUGINSESSIONHANDLER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/ikepluginsessionif.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/ikepluginsessionif.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,106 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKE protocol plugin session interface +* +*/ + + +#ifndef M_IKEPLUGINSESSIONIF_H +#define M_IKEPLUGINSESSIONIF_H + +#include +#include "vpnmandefs.h" + +// FORWARD DECLARATIONS +class CIkeData; +class MIkeDataInterface; + +/** + * IKE protocol plugin session interface. + * + * Session interface for handling an IKE connection with a remote host. + * Separate session is required for each VPN connection. + * + * @lib internal (kmdserver.exe) + */ +class MIkePluginSessionIf + { +public: + + /** + * Destructor. + */ + virtual ~MIkePluginSessionIf() {}; + + /** + * Starts negotiation with a remote host. + * @param aIkeData IKE policy data + * @param aInternalAddress Internal address (returned) + * @param aStatus Completion status (returned) + */ + virtual void NegotiateWithHost( const CIkeData& aIkeData, + TVPNAddress& aInternalAddress, + TRequestStatus& aStatus ) = 0; + + /** + * Cancels negotiate request. DeleteSession() method needs to be called + * after this method to delete session. + */ + virtual void CancelNegotiateWithHost() = 0; + + /** + * Deletes session. IKE/IPSec SA:s are deleted. + * @param aSilentClose Specified if a silent close in question (Delete + * payloads not transmitted to remote host) + * @param aStatus Completion status (returned) + */ + virtual void DeleteSession( const TBool aSilentClose, + TRequestStatus& aStatus ) = 0; + + /** + * Cancels deletion requests. IKE/IPSec SA:s are deleted. + */ + virtual void CancelDeleteSession() = 0; + + /** + * Requests notification about error condition. Error notification causes + * IKE plugin session to be deleted silently and link disconnected. IKE + * plugin session needs to cleanup session, before notifying error. + * @param aStatus Completion status (returned) + */ + virtual void NotifyError( TRequestStatus& aStatus ) = 0; + + /** + * Cancels error notification request. + */ + virtual void CancelNotifyError() = 0; + + /** + * Requests notification about change of internal address. + * @param aInternalAddress Internal address (returned) + * @param aStatus KErrNone or KErrCancel. Error condition needs to be + * indicated via NotifyError() method. (returned) + */ + virtual void NotifyInternalAddressChanged( TVPNAddress& aInternalAddress, + TRequestStatus& aStatus ) = 0; + + /** + * Cancels internal address change notification request. + */ + virtual void CancelNotifyInternalAddressChanged() = 0; + + }; + + +#endif // M_IKEPLUGINSESSIONIF_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/kmddebuglogger.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/kmddebuglogger.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Write logs in debug builds +* +*/ + + +#ifndef C_KMDDEBUGLOGGER_H +#define C_KMDDEBUGLOGGER_H + +#include +#include + +#include "ikedebug.h" + +/** + * KMD debug logger. + * Logger for writing logs in debug builds. + * @lib internal (kmdserver.exe) + */ +class CKmdDebugLogger : public CBase, + public MIkeDebug + { +public: + + /** + * Two-phased constructor. + */ + static CKmdDebugLogger* NewL(); + + /** + * Destructor. + */ + ~CKmdDebugLogger(); + +#ifdef _DEBUG + + void LogWrite( const TDesC& aText ); + void LogWrite( const TDesC8& aText ); + + void LogWriteF( TRefByValue aFmt, ... ); + void LogWriteF( TRefByValue aFmt, ... ); + + void LogWriteArray( const TUint8* aArray, TInt aLength ); + + void LogWriteNum( TUint aNum ); + + void TraceMessage( const TDesC8& aMessage, + const TInetAddr& aSourceAddress, + const TInetAddr& aDestinationAddress, + CIkePcapTrace::TEncryptionType aEncryptionType ); + +private: + void ConstructL(); + + /** + * File logger. + * Own. + */ + RFileLogger iFileLogger; + + /** + * PCap tracer. + * Own. + */ + CIkePcapTrace* iIkePcapTrace; + +#endif // _DEBUG + }; + +#endif // C_KMDDEBUGLOGGER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/kmdeventlogger.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/kmdeventlogger.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,110 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: KMD event logger +* +*/ + + +#ifndef C_KMDEVENTLOGGER_H +#define C_KMDEVENTLOGGER_H + +#include "kmdeventloggerif.h" + +// FORWARD DECLARATIONS +class MIkeDebug; + +/** + * KMD event logger. + * + * Handles logging of KMD specific events to event log. + * + * @lib internal (kmdserver.exe) + */ +class CKmdEventLogger : public CBase, + public MKmdEventLoggerIf + { +public: + + /** + * Two-phased constructor. + * @param aDebug Debug trace interface + */ + static CKmdEventLogger* NewL( MIkeDebug& aDebug ); + + /** + * Destructor. + */ + ~CKmdEventLogger(); + +// from base class MKmdEventLoggerIf + + /** + * From MKmdEventLoggerIf + * Writes event to event log. + * + * @param aCategory Log event category + * @param aMsgId Msg Id + * @param aStatus Status + * @param aVpnIapId VPN IAP Id + * @param aSgwIp SGW IP address + * @param aLocalAddr Local IP address + */ + void LogEvent( TLogCategory aCategory, + TInt aMsgId, + TInt aStatus, + TUint32 aVpnIapId, + const TInetAddr* aGwIp, + const TInetAddr* aLocalAddr = NULL ); + + /** + * From MKmdEventLoggerIf + * Writes event to event log. + * + * @param aCategory Log event category + * @param aMsgId Msg Id + * @param aStatus Status + * @param aVpnIapId VPN IAP Id + * @param aSgwIp SGW IP address + * @param aLocalAddr Local IP address + */ + void LogEvent( TKmdLogCategory aCategory, + TInt aMsgId, + TInt aStatus, + TUint32 aVpnIapId, + const TInetAddr* aGwIp, + const TInetAddr* aLocalAddr = NULL ); + +private: + CKmdEventLogger( MIkeDebug& aDebug ); + + void ConstructL(); + +private: // data + + /** + * Event mediator. + * Own. + */ + REventMediator iEventMediator; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + + }; + + +#endif // C_KMDEVENTLOGGER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/kmdeventloggerif.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/kmdeventloggerif.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,89 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: KMD event logger interface +* +*/ + + +#ifndef M_KMDEVENTLOGGERIF_H +#define M_KMDEVENTLOGGERIF_H + +#include + +#include "eventlogger.h" +#include "eventmediatorapi.h" + +// FORWARD DECLARATIONS +class TInetAddr; + +#define LOG_KMD_EVENT(a,b,c,d,e) EventLogger().LogEvent(a,b,c,d,e); +#define LOG_KMD_EVENT2(a,b,c,d,e,f) EventLogger().LogEvent(a,b,c,d,e,f); + +/** + * KMD event logger interface. + * + * Logger interface for logging KMD specific events to event log. + * + * @lib internal (kmdserver.exe) + */ +class MKmdEventLoggerIf + { +public: + + enum TKmdLogCategory + { + KLogInfo = 0, + KLogWarning, + KLogError, + KLogDebug + }; + + /** + * Writes event to event log. + * + * @param aCategory Log event category + * @param aMsgId Msg Id + * @param aStatus Status + * @param aVpnIapId VPN IAP Id + * @param aSgwIp SGW IP address + * @param aLocalAddr Local IP address + */ + virtual void LogEvent( TLogCategory aCategory, + TInt aMsgId, + TInt aStatus, + TUint32 aVpnIapId, + const TInetAddr* aSgwIp, + const TInetAddr* aLocalAddr = NULL ) = 0; + + /** + * Writes event to event log. + * + * @param aCategory Log event category + * @param aMsgId Msg Id + * @param aStatus Status + * @param aVpnIapId VPN IAP Id + * @param aSgwIp SGW IP address + * @param aLocalAddr Local IP address + */ + virtual void LogEvent( TKmdLogCategory aCategory, + TInt aMsgId, + TInt aStatus, + TUint32 aVpnIapId, + const TInetAddr* aSgwIp, + const TInetAddr* aLocalAddr = NULL ) = 0; + + }; + + +#endif // M_KMDEVENTLOGGERIF_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/kmdserver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/kmdserver.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,230 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: KMD server +* +*/ + + +#ifndef C_KMDSERVER_H +#define C_KMDSERVER_H + +#include + +#include "ikesocketdefs.h" +#include "vpnmandefs.h" + +_LIT( KKmdServerName, "!KMD server" ); +_LIT( KKmdServerImg, "kmdserver" ); + +const TUid KServerUid3 = { 0x1000088A }; + +const TInt KMyServerStackSize = 0x2000; // 8KB +const TInt KMyServerInitHeapSize = 0x1000; // 4KB +const TInt KMyServerMaxHeapSize = 0x1000000; // 16MB + +const TInt KKmdServMajorVersion = 1; +const TInt KKmdServMinorVersion = 0; +const TInt KKmdServBuildVersion = 0; + +// FORWARD DECLARATIONS +class CIkeConnectionInterface; +class CIkePluginHandler; +class CIkePluginSessionHandler; +class CKmdSession; +class CVpnConnection; +class CKmdDebugLogger; +class CKmdEventLogger; +class CSecpolReader; +class MIkeDebug; +class MIkePluginSessionHandlerCallback; + +/** + * KMD server. + * Implementation of KMD (Key Management Daemon) server. Handles creating of + * server-side client sessions. + * + * @lib internal (kmdserver.exe) + */ +class CKmdServer : public CPolicyServer + { +public: + + /** KMD commands */ + enum + { + KKmdStartConnection, + KKmdCancelStartConnection, + KKmdActivateAsync, + KKmdCancelActivateAsync, + KKmdStopConnection, + KKmdResolveAddress, + KKmdCancelResolveAddress + }; + + /** + * Two-phased constructor. Called from kmd_starter. + */ + static CKmdServer* NewL(); + + /** + * Destructor. + */ + ~CKmdServer(); + + /** + * Informs KMD server that KMD session has been closed. + */ + void KmdSessionClosed(); + + /** + * Creates VPN connection object. + * @param aVpnIapId VPN IAP Id + */ + CVpnConnection& CreateVpnConnectionL( TUint32 aVpnIapId ); + + /** + * Gets VPN connection object. + * @param aVpnIapId VPN IAP Id + */ + CVpnConnection& GetVpnConnectionL( TUint32 aVpnIapId ); + + /** + * Deletes VPN connection object. + * @param aVpnIapId VPN IAP Id + */ + void DeleteVpnConnection( TUint32 aVpnIapId ); + + /** + * Creates IKE plugin session. + * @param aIkeVersion IKE version + * @param aIpVersion IP version + * @param aConnection IKE connection interface + * @param aVpnIapId VPN IAP id + * @param aVpnNetId VPN NET id + * @param aVpnInterfaceIndex VPN interface index + * @param aDnsServerAddr DNS server address from IKE policy. + * @param aCallback Callback interface + * @return IKE plugin session handler + */ + CIkePluginSessionHandler& CreateIkePluginSessionL( TInt aIkeVersion, + IkeSocket::TIpVersion aIpVersion, + CIkeConnectionInterface& aConnection, + TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + const TInetAddr& aDnsServerAddr, + MIkePluginSessionHandlerCallback& aCallback ); + /** + * Deletes IKE plugin session. + * @param aIkeVersion IKE version + * @param aVpnIapId VPN IAP Id + */ + void DeleteIkePluginSession( TInt aIkeVersion, + TUint32 aVpnIapId ); + + /** + * Returns debug trace interface. + */ + MIkeDebug& Debug(); + +// from base class CPolicyServer + + CSession2* NewSessionL( const TVersion& aVersion, + const RMessage2& aMessage ) const; + +private: + CKmdServer(); + void ConstructL(); + + /** + * Stops KMD server if there are no more KMD sessions or VPN connections. + */ + void StopKmdServer(); + +private: // data + + /** + * KMD session count. + * Own. + */ + mutable TInt32 iSessionCount; + + /** + * VPN connections. + * Own. + */ + RPointerArray iVpnConnections; + + /** + * IKE plugin handlers. + * Own. + */ + CIkePluginHandler* iIkePluginHandlers[2]; + + /** + * Debug logger. + * Own. + */ + CKmdDebugLogger* iDebugLogger; + + /** + * Event logger. + * Own. + */ + CKmdEventLogger* iEventLogger; + + /** + * Secpol reader. + * Own. + */ + CSecpolReader* iSecpolReader; + + /** + * Policy server. + * Own. + */ + RIpsecPolicyServ iIpsecPolicyServ; + + /** + * KMD server range count. + * Own. + */ + static const TUint iKmdServerRangeCount; + + /** + * KMD server ranges. + * Own. + */ + static const TInt iKmdServerRanges[]; + + /** + * KMD server element index. + * Own. + */ + static const TUint8 iKmdServerElementIndex[]; + + /** + * KMD server elements. + * Own. + */ + static const CPolicyServer::TPolicyElement iKmdServerElements[]; + + /** + * KMD server policy. + * Own. + */ + static const CPolicyServer::TPolicy iKmdServerPolicy; + }; + +#endif // C_KMDSERVER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/kmdserver.pan --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/kmdserver.pan Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: KMD server panic definitions +* +*/ + + +#ifndef KMDSERVER_PAN +#define KMDSERVER_PAN + +_LIT( KKmdPanicCategory, "KMDServerPanic" ); + +enum TKmdServerPanics + { + EKmdPanicIllegalCommand = 0, + EKmdPanicRequestAlreadyPending + }; + +#endif // KMDSERVER_PAN diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/kmdsession.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/kmdsession.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,209 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Server side session of KMD server +* +*/ + + +#ifndef C_KMDSESSION_H +#define C_KMDSESSION_H + +#include +#include + +#include "activationstarter.h" +#include "connectionstarter.h" +#include "connectionstopper.h" +#include "fqdnresolver.h" + +// FORWARD DECLARATIONS +class CKmdServer; +class CKmdSessionHandler; +class MIkeDebug; +class TVPNAddress; + +/** + * KMD session. + * Server side session of KMD server. Handles client requests. + * + * @lib internal (kmdserver.exe) + */ +class CKmdSession : public CSession2, + public MActivationStarterCallback, + public MConnectionStarterCallback, + public MConnectionStopperCallback, + public MFqdnResolverCallback + { +public: + + /** + * Two-phased constructor. + * @param aServer KMD server + * @param aDebug Debug trace interface + */ + static CKmdSession* NewL( CKmdServer& aServer, + MIkeDebug& aDebug ); + + /** + * Destructor. + */ + ~CKmdSession(); + +// from base class CSession2 + + /** + * From CSession2 + * Handles client request. + * + * @param aMessage Message request + */ + void ServiceL( const RMessage2& aMessage ); + +// from base class MConnectionStarterCallback + + /** + * From MConnectionStarterCallback + * Notification about completion of real connection starting. + * + * @param aStatus Completion status + * @param aRealIapId IAP Id of started connection + * @param aRealNetId Net Id of started connection + */ + void RealConnectionStarted( TInt aStatus, + TInt aRealIapId, + TInt aRealNetId ); + +// from base class MConnectionStopperCallback + + /** + * From MConnectionStopperCallback + * Notification about completion of VPN connection stopping. + * + * @param aStatus Completion status + */ + void VpnConnectionStopped( TInt aStatus ); + +// from base class MFqdnResolverCallback + + /** + * From MFqdnResolverCallback + * Notifies about completion of FQDN address resolving. + * + * @param aStatus Completion status + * @param aNameEntry Result of name resolution + */ + void AddressResolveCompleted( TInt aStatus, + TNameEntry aNameEntry ); + +// from base class MActivationStarterCallback + + /** + * From MActivationStarterCallback + * Notification about completion of activation. + * + * @param aStatus Completion status + * @param aVirtualIp Internal address info + */ + void ActivationCompleted( TInt aStatus, + const TVPNAddress& aVirtualIp ); + +private: + CKmdSession( CKmdServer& aServer, + MIkeDebug& aDebug ); + + /** + * Cancels real connection starting. + */ + void DoCancelStartConnection(); + + /** + * Cancels activating + */ + void DoCancelActivate(); + + /** + * Cancels FQDN address resolving. + */ + void DoCancelResolveAddress(); + +private: // data + /** + * KMD server. + * Not own. + */ + CKmdServer& iServer; + + /** + * VPN IAP Id. + * Not own. + */ + TUint32 iVpnIapId; + + /** + * Connection starter active object. + * Own. + */ + CConnectionStarter* iConnectionStarter; + + /** + * Connection stopper active object. + * Own. + */ + CConnectionStopper* iConnectionStopper; + + /** + * FQDN address resolver active object. + * Own. + */ + CFqdnResolver* iFqdnResolver; + + /** + * Activation starter active object. + * Own. + */ + CActivationStarter* iActivationStarter; + + /** + * Pending start connection message. + * Own. + */ + RMessage2 iPendingStartConnection; + + /** + * Pending stop connection message. + * Own. + */ + RMessage2 iPendingStopConnection; + + /** + * Pending FQDN resolve message. + * Own. + */ + RMessage2 iPendingFqdnResolve; + + /** + * Pending activate message. + * Own. + */ + RMessage2 iPendingActivate; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + + }; + +#endif // C_KMDSESSION_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/secpolpayload.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/secpolpayload.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,91 @@ +/* +* Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Security policy module payload structures +* +*/ + + +#ifndef T_SECPOLPAYLOAD_H +#define T_SECPOLPAYLOAD_H + +#include +#include + +// FORWARD DECLARATIONS +class TInet6Options; +class TInet6HeaderFragment; +class TInet6HeaderRouting; +class TInet6HeaderAH; +class TInet6HeaderESP; +class TInet6HeaderICMP; +class TInet6HeaderTCP; +class TInet6HeaderUDP; + +/** + * THdrIP4 class. + * Class for dumping IPv4 IP header. + * + * @lib internal (kmdserver.exe) + */ +class THdrIP4 : public TInet6HeaderIP4 + { +public: + void Dump( TDes& aStr, TInt aLength ); + TBool IsUnicast(); + }; + +/** + * THdrIP6 class. + * Class for dumping IPv6 IP header. + * + * @lib internal (kmdserver.exe) + */ +class THdrIP6 : public TInet6HeaderIP + { +public: + void Dump( TDes &aStr, TInt aLength ); + TBool IsUnicast(); + }; + +/** + * Secpol payload. + * Payload structure for reading message from Secpol reader. + * + * @lib internal (kmdserver.exe) + */ +class TSecpolPayload + { +public: + TSecpolPayload( const TUint8* aPtr ); + + void Dump( TDes &aStr, TInt aLength, TInt aProtocol ); + +public: // data + union + { + const TUint8* iRaw; + const TInet6HeaderESP* iESP; + const TInet6HeaderAH* iAH; + const TInet6HeaderIP* iIP6; + const TInet6HeaderIP4* iIP4; + const TInet6HeaderTCP* iTCP; + const TInet6HeaderUDP* iUDP; + const TInet6HeaderICMP* iICMP; + const TInet6Options* iOPT; + const TInet6HeaderRouting* iRTH; + const TInet6HeaderFragment* iFRH; + }; + }; + +#endif // T_SECPOLPAYLOAD_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/secpolreader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/secpolreader.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,117 @@ +/* +* Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Security policy module +* +*/ + + +#ifndef C_SECPOLREADER_H +#define C_SECPOLREADER_H + +#include +#include + +// FORWARD DECLARATIONS +class MIkeDebug; +class MKmdEventLoggerIf; + +const TInt KMaxSecpolMsgSize( 1000 ); + +/** + * Secpol reader. + * Class for reading messages from SECPOL socket. + * + * @lib internal (kmdserver.exe) + */ +class CSecpolReader : public CActive + { +public: + /** + * Two-phased constructor. + * @param aEventLogger Event logger + * @param aDebug Debug trace interface + */ + static CSecpolReader* NewL( MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ); + + /** + * Destructor. + */ + ~CSecpolReader(); + +// from base class CActive + + /** + * From CActive + * Handles completion of asynchronous reading. + */ + void RunL(); + + /** + * From CActive + * Handles cancellation of asynchronous reading. + */ + void DoCancel(); + +private: + CSecpolReader( MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ); + void ConstructL(); + + /** + * Returns event logger. + * @return Event logger + */ + MKmdEventLoggerIf& EventLogger(); + +private: // data + + /** + * Socket server. + * Own. + */ + RSocketServ iSocketServer; + + /** + * Secpol socket. + * Own. + */ + RSocket iSocket; + + /** + * Secpol message. + * Own. + */ + TBuf8 iMsg; + + /** + * Remote source address. + * Own. + */ + TInetAddr iAddr; + + /** + * Event logger. + * Not own. + */ + MKmdEventLoggerIf& iEventLogger; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + }; + +#endif // C_SECPOLREADER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/inc/vpnconnection.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/inc/vpnconnection.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,328 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: VPN connection specific structures +* +*/ + + +#ifndef C_VPNCONNECTION_H +#define C_VPNCONNECTION_H + +#include +#include +#include "vpnmandefs.h" +#include "disconnectionobserver.h" +#include "eventmediatorapi.h" +#include "ikepluginsessionhandler.h" +#include "ikesocketdefs.h" + +// FORWARD DECLARATIONS +class CIkeConnectionInterface; +class CIkeData; +class CIkePluginSessionInterface; +class CKmdServer; +class MIkeDebug; + +/** + * VPN connection. + * VPN connection class provides VPN connection specific functionality for + * managing real network connection and connection with remote IKE host. + * + * @lib internal (kmdserver.exe) + */ +class CVpnConnection : public CBase, + public MDisconnectionObserverCallback, + public MIkePluginSessionHandlerCallback + { +public: + /** + * Two-phased constructor. + * @param aVpnIapId VPN IAP Id + * @param aServer KMD server + * @param aDebug Debug trace interface + */ + static CVpnConnection* NewLC( TUint32 aVpnIapId, + CKmdServer& aServer, + MIkeDebug& aDebug ); + /** + * Destructor. + */ + ~CVpnConnection(); + + /** + * Starts real network connection. + * @param aStatus Completion status (returned) + */ + void StartRealConnection( TRequestStatus& aStatus ); + + /** + * Cancels connection starting. + */ + void CancelStartRealConnection(); + + /** + * Resolves an IP address from FQDN address. + * @param aFqdn FQDN address + * @param aNameEntry Result of name resolution (returned) + * @param aStatus Completion status (returned) + */ + void ResolveAddress( const TDesC& aFqdn, + TNameEntry& aNameEntry, + TRequestStatus& aStatus ); + + /** + * Cancels resolving. + */ + void CancelResolveAddress(); + + /** + * Starts negotiation with a remote host. + * @param aIkeData IKE policy data + * @param aVpnInterfaceIndex + * @param aIpVersion IP version + * @param aInternalAddress Internal address (returned) + * @param aStatus Completion status (returned) + */ + void NegotiateWithHost( CIkeData& aIkeData, + TUint32 aVpnInterfaceIndex, + IkeSocket::TIpVersion aIpVersion, + TVPNAddress& aInternalAddress, + TRequestStatus& aStatus ); + + /** + * Cancels negotiation. + */ + void CancelNegotiateWithHost(); + + /** + * Stops VPN connection. + * @param aSilentClose Specified if a silent close in question (Delete + * payloads not transmitted to remote host) + * @param aStatus Completion status (returned) + */ + void StopVpnConnection( TBool aSilentClose, + TRequestStatus& aStatus ); + + /** + * Cancels VPN connection stopping. VPN connection is stopped silently. + */ + void CancelStopVpnConnection(); + + /** + * Gets local IP address of real network interface. + * + * @param aIpVersion IP version of local IP address + * @param aLocalIp Local IP address (returned) + * @return Error status. KErrNotFound if address is not found. + */ + TInt GetLocalAddress( const IkeSocket::TIpVersion aIpVersion, + TInetAddr& aLocalIp ); + + /** + * Returns VPN IAP Id. + * @return VPN IAP Id + */ + TInt VpnIapId() const; + + /** + * Returns real IAP Id. + * @return Real IAP Id + */ + TInt RealIapId() const; + + /** + * Returns real NET Id. + * @return Real NET Id + */ + TInt RealNetId() const; + +// from base class MDisconnectionObserverCallback + + /** + * Notification about link disconnection. VPN connection is stopped silently. + * @param aStatus Completion status + */ + void DisconnectIndication( TInt aStatus ); + +// from base class MIkePluginSessionHandlerCallback + + /** + * From MIkePluginSessionHandlerCallback + * Notification about completion of negotiate request. + * @param aStatus Completion status + * @param aInternalAddress Internal address. + */ + void NegotiationStarted( TInt aStatus, + const TVPNAddress& aInternalAddress ); + /** + * From MIkePluginSessionHandlerCallback + * Notification about completion of delete session request. Real + * network connection is closed. + * @param aStatus Completion status + */ + void IkePluginSessionClosed( TInt aStatus ); + + /** + * From MIkePluginSessionHandlerCallback + * Notification about IKE plugin session error. + * @param aStatus Completion status + */ + void IkePluginSessionError( TInt aStatus ); + + +private: + CVpnConnection( TUint32 aVpnIapId, + CKmdServer& aServer, + MIkeDebug& aDebug ); + void ConstructL(); + + /** + * Cancels negotiation.. + */ + void DoCancelNegotiateWithHost(); + + /** + * Stops VPN connection. + */ + void DoStopVpnConnection( TBool aSilentClose ); + + /** + * Cancels VPN connection stopping. VPN connection is stopped silently. + */ + void DoCancelStopVpnConnection(); + + /** + * Deletes IKE plugin session. + * @param aSilentClose Specified if a silent close in question (Delete + * payloads not transmitted to remote host) + */ + void DoDeleteSession( TBool aSilentClose ); + + /** + * Cancels session deletion. + */ + void DoCancelDeleteSession(); + + /** + * Stops real network connection. + * @param aStatus Disconnect event status to be reported. + */ + void DoStopRealConnection( TInt aStatus ); + + /** + * Reports disconnect event via Event Mediator API. + * @param aStatus Completion status + */ + void DoReportDisconnectEvent( TInt aStatus ); + +private: // data + + /** + * KMD server. + * Not own. + */ + CKmdServer& iServer; + + /** + * IKE version. + * Own. + */ + TInt iIkeVersion; + + /** + * VPN IAP id. + * Own. + */ + TUint32 iVpnIapId; + + /** + * VPN NET id. + * Own. + */ + TUint32 iVpnNetId; + + /** + * Real IAP id. + * Own. + */ + TInt iRealIapId; + + /** + * Real NET id. + * Own. + */ + TInt iRealSnapId; + + /** + * Informs if disconnect event has been received. + * Own. + */ + TInt iDisconnectEventReceived; + + /** + * Disconnection status. + * Own. + */ + TInt iDisconnectionStatus; + + /** + * IKE connection interface. + * Own. + */ + CIkeConnectionInterface* iIkeConnection; + + /** + * Disconnection observer. + * Own. + */ + CDisconnectionObserver* iDisconnectionObserver; + + /** + * IKE plugin session handler. + * Not own. + */ + CIkePluginSessionHandler* iIkePluginSessionHandler; + + /** + * Event mediator. + * Own. + */ + REventMediator iEventMediator; + + /** + * Client's request status for starting of negotiation. + * Not own. + */ + TRequestStatus* iClientStatusNegotiate; + + /** + * Client's internal address. + * Not own. + */ + TVPNAddress* iClientInternalAddress; + + /** + * Client's request status for VPN connection's stopping. + * Not own. + */ + TRequestStatus* iClientStatusStopVpnConnection; + + /** + * Debug trace interface. + * Not own. + */ + MIkeDebug& iDebug; + }; + +#endif // C_VPNCONNECTION_H diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/rom/kmdserver.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/rom/kmdserver.iby Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2006-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Image description file for project +* Key Management Daemon +* +*/ + + + +#ifndef __KMDSERVER_IBY__ +#define __KMDSERVER_IBY__ + +#ifdef SYMBIAN_EXCLUDE_IPSEC + +REM Feature KMDSERVER not included in this rom + +#else + +file=ABI_DIR\BUILD_DIR\kmdserver.exe PROGRAMS_DIR\kmdserver.exe + +#endif // SYMBIAN_EXCLUDE_IPSEC + +#endif // __KMDSERVER_IBY__ + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/activationstarter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/activationstarter.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,197 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: active object, that monitors activating +* +*/ + + +#include "ikedebug.h" +#include "ikepolparser.h" +#include "internaladdress.h" +#include "vpnconnection.h" + +// CLASS HEADER +#include "activationstarter.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CActivationStarter* CActivationStarter::NewL( CVpnConnection& aConnection, + MActivationStarterCallback& aCallback, + MIkeDebug& aDebug ) + { + CActivationStarter* self = new ( ELeave ) CActivationStarter( aConnection, + aCallback, + aDebug ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CActivationStarter::~CActivationStarter() + { + Cancel(); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CActivationStarter::CActivationStarter( CVpnConnection& aConnection, + MActivationStarterCallback& aCallback, + MIkeDebug& aDebug ) + : CActive( EPriorityStandard ), + iConnection( aConnection ), + iCallback( aCallback ), + iDebug( aDebug ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------------------------- +// Starts asynchronous activating. +// --------------------------------------------------------------------------- +// +void CActivationStarter::Activate( CIkeData& aIkeData, + const TDesC& aVpnIfName ) + { + TUint32 vpnInterfaceIndex( 0 ); + TInt err = GetVpnInterfaceIndex( aVpnIfName, + vpnInterfaceIndex ); + + if ( err != KErrNone ) + { + TRequestStatus* status = &iStatus; + *status = KRequestPending; + SetActive(); + + User::RequestComplete( status, err ); + return; + } + + TInetAddr remoteAddr = aIkeData.iAddr; + iIpVersion = IkeSocket::EIPv4; + if ( remoteAddr.Family() == KAfInet6 && + !remoteAddr.IsV4Mapped() ) + { + iIpVersion = IkeSocket::EIPv6; + } + iDnsServerAddr = aIkeData.iDnsServer; + + iConnection.NegotiateWithHost( aIkeData, + vpnInterfaceIndex, + iIpVersion, + iInternalAddress, + iStatus ); + SetActive(); + } + +// --------------------------------------------------------------------------- +// Gets VPN interface index. +// --------------------------------------------------------------------------- +// +TInt CActivationStarter::GetVpnInterfaceIndex( const TDesC& aVpnIfName, + TUint32& aVpnInterfaceIndex ) + { + TInt err( KErrNone ); + RSocketServ ss; + err = ss.Connect(); + + if ( err == KErrNone ) + { + RSocket socket; + err = socket.Open( ss, + KAfInet, + KSockDatagram, + KProtocolInetIp ); + + if ( err == KErrNone ) + { + TPckgBuf opt; + opt().iName = aVpnIfName; + + err = socket.GetOpt( KSoInetIfQueryByName, + KSolInetIfQuery, + opt ); + if ( err == KErrNone ) + { + aVpnInterfaceIndex = opt().iZone[0]; // VPN Interface index + } + } + socket.Close(); + } + + ss.Close(); + return err; + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles completion of asynchronous activating. +// --------------------------------------------------------------------------- +// +void CActivationStarter::RunL() + { + TInt err( iStatus.Int() ); + + if ( err == KErrNone ) + { + if ( iInternalAddress.iVPNIfAddr.IsUnspecified() ) + { + TInetAddr localAddr; + err = iConnection.GetLocalAddress( iIpVersion, localAddr ); + + if ( err == KErrNone ) + { + iInternalAddress.iVPNIfAddr = localAddr; + } + } + } + + if ( err == KErrNone && + iInternalAddress.iVPNIfDNS1.IsUnspecified() ) + { + if ( iDnsServerAddr.Address() != KAFUnspec ) + { +#ifdef _DEBUG + TBuf<39> addrBuf; + iDnsServerAddr.OutputWithScope( addrBuf ); + DEBUG_LOG1(_L("DNS Server Address in IKE data %S"), &addrBuf); +#endif //_DEBUG + iInternalAddress.iVPNIfDNS1 = iDnsServerAddr; + } + else + { + DEBUG_LOG(_L("DNS server not defined in policy")); + } + } + + iCallback.ActivationCompleted( err, iInternalAddress ); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles cancellation of asynchronous activating. +// --------------------------------------------------------------------------- +// +void CActivationStarter::DoCancel() + { + iConnection.CancelNegotiateWithHost(); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/connectionstarter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/connectionstarter.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,102 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: active object, that monitors the real connection starting +* +*/ + + +// INTERNAL HEADERS +#include "vpnconnection.h" + +// CLASS HEADER +#include "connectionstarter.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CConnectionStarter* CConnectionStarter::NewL( CVpnConnection& aConnection, + MConnectionStarterCallback& aCallback ) + { + CConnectionStarter* self = new ( ELeave ) CConnectionStarter( aConnection, + aCallback ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CConnectionStarter::~CConnectionStarter() + { + Cancel(); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CConnectionStarter::CConnectionStarter( CVpnConnection& aConnection, + MConnectionStarterCallback& aCallback ) + : CActive( EPriorityStandard ), + iConnection( aConnection ), + iCallback( aCallback ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------------------------- +// Starts connection asynchronously. +// --------------------------------------------------------------------------- +// +void CConnectionStarter::StartRealConnection() + { + iConnection.StartRealConnection( iStatus ); + SetActive(); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles completion of asynchronous connection starting. +// --------------------------------------------------------------------------- +// +void CConnectionStarter::RunL() + { + TInt realIapId = 0; + TInt realNetworkId = 0; + + if ( iStatus.Int() == KErrNone ) + { + realIapId = iConnection.RealIapId(); + realNetworkId = iConnection.RealNetId(); + } + + iCallback.RealConnectionStarted( iStatus.Int(), + realIapId, + realNetworkId ); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles cancellation of asynchronous connection starting. +// --------------------------------------------------------------------------- +// +void CConnectionStarter::DoCancel() + { + iConnection.CancelStartRealConnection(); + } + + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/connectionstopper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/connectionstopper.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,90 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: active object, that monitors stopping of connection +* +*/ + + +// INTERNAL INCLUDES +#include "vpnconnection.h" + +// CLASS HEADER +#include "connectionstopper.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CConnectionStopper* CConnectionStopper::NewL( CVpnConnection& aVpnConnection, + MConnectionStopperCallback& aCallback ) + { + CConnectionStopper* self = new ( ELeave ) CConnectionStopper( aVpnConnection, + aCallback ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CConnectionStopper::~CConnectionStopper() + { + Cancel(); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CConnectionStopper::CConnectionStopper( CVpnConnection& aVpnConnection, + MConnectionStopperCallback& aCallback ) + : CActive( EPriorityStandard ), + iVpnConnection( aVpnConnection ), + iCallback( aCallback ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------------------------- +// Stops VPN connection asynchronously. +// --------------------------------------------------------------------------- +// +void CConnectionStopper::StopVpnConnection( TBool aSilentClose ) + { + iVpnConnection.StopVpnConnection( aSilentClose, iStatus ); + SetActive(); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles completion of asynchronous connection stopping. +// --------------------------------------------------------------------------- +// +void CConnectionStopper::RunL() + { + iCallback.VpnConnectionStopped( iStatus.Int() ); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles cancellation of asynchronous connection stopping. +// --------------------------------------------------------------------------- +// +void CConnectionStopper::DoCancel() + { + iVpnConnection.CancelStopVpnConnection(); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/disconnectionobserver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/disconnectionobserver.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,91 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: active object, that monitors link disconnection +* +*/ + + +// INTERNAL HEADERS +#include "ikeconnectioninterface.h" +#include "vpnconnection.h" + +// CLASS HEADER +#include "disconnectionobserver.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CDisconnectionObserver* CDisconnectionObserver::NewL( CIkeConnectionInterface& aIkeConnectionInterface, + MDisconnectionObserverCallback& aCallback ) + { + CDisconnectionObserver* self = new (ELeave) CDisconnectionObserver( aIkeConnectionInterface, + aCallback ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CDisconnectionObserver::~CDisconnectionObserver() + { + Cancel(); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CDisconnectionObserver::CDisconnectionObserver( CIkeConnectionInterface& aIkeConnectionInterface, + MDisconnectionObserverCallback& aCallback ) + : CActive( EPriorityStandard ), + iIkeConnectionInterface( aIkeConnectionInterface ), + iCallback( aCallback ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------------------------- +// Requests asynchronous link disconnection notification. +// --------------------------------------------------------------------------- +// +void CDisconnectionObserver::StartObserving() + { + iIkeConnectionInterface.NotifyDisconnect( iStatus ); + SetActive(); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles completion of asynchronous notification request. +// --------------------------------------------------------------------------- +// +void CDisconnectionObserver::RunL() + { + iCallback.DisconnectIndication( iStatus.Int() ); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles cancellation of asynchronous notification request. +// --------------------------------------------------------------------------- +// +void CDisconnectionObserver::DoCancel() + { + iIkeConnectionInterface.CancelNotifyDisconnect(); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/errorobserver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/errorobserver.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: active object, that monitors IKE plugin session error +* +*/ + + +#include "ikedebug.h" +#include "ikepluginsessionif.h" +#include "ikepluginsessionhandler.h" + +// CLASS HEADER +#include "errorobserver.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CErrorObserver* CErrorObserver::NewL( MIkePluginSessionIf& aIkePluginSession, + MIkePluginSessionHandlerCallback& aCallback, + MIkeDebug& aDebug ) + { + CErrorObserver* self = new (ELeave) CErrorObserver( aIkePluginSession, + aCallback, + aDebug ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CErrorObserver::~CErrorObserver() + { + Cancel(); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CErrorObserver::CErrorObserver( MIkePluginSessionIf& aIkePluginSession, + MIkePluginSessionHandlerCallback& aCallback, + MIkeDebug& aDebug ) + : CActive( EPriorityStandard ), + iIkePluginSession( aIkePluginSession ), + iCallback( aCallback ), + iDebug( aDebug ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +void CErrorObserver::ConstructL() + { + } + +// --------------------------------------------------------------------------- +// Requests asynchronous error notification. +// --------------------------------------------------------------------------- +// +void CErrorObserver::StartObserving() + { + iIkePluginSession.NotifyError( iStatus ); + SetActive(); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles completion of asynchronous notification request. +// --------------------------------------------------------------------------- +// +void CErrorObserver::RunL() + { + DEBUG_LOG1(_L("IKE plugin session error=%d"), iStatus.Int()); + iCallback.IkePluginSessionError( iStatus.Int() ); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles cancellation of asynchronous notification request. +// --------------------------------------------------------------------------- +// +void CErrorObserver::DoCancel() + { + iIkePluginSession.CancelNotifyError(); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/fqdnresolver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/fqdnresolver.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: active object, that monitors the completion of FQDN resolve. +* +*/ + + +// INTERNAL INCLUDES +#include "vpnconnection.h" + +// CLASS HEADER +#include "fqdnresolver.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CFqdnResolver* CFqdnResolver::NewL( CVpnConnection& aConnection, + MFqdnResolverCallback& aCallback ) + { + CFqdnResolver* self = new (ELeave) CFqdnResolver( aConnection, aCallback ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CFqdnResolver::~CFqdnResolver() + { + Cancel(); + + __ASSERT_DEBUG( iFqdn == NULL, User::Invariant() ); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CFqdnResolver::CFqdnResolver( CVpnConnection& aConnection, + MFqdnResolverCallback& aCallback ) + : CActive( EPriorityStandard ), + iConnection( aConnection ), + iCallback( aCallback ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------------------------- +// Resolves an IP address from FQDN address asynchronously. +// --------------------------------------------------------------------------- +// +void CFqdnResolver::ResolveAddress( HBufC* aFqdn ) + { + iFqdn = aFqdn; + iConnection.ResolveAddress( *iFqdn, iNameEntry, iStatus ); + SetActive(); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles completion of asynchronous FQDN address resolving. +// --------------------------------------------------------------------------- +// +void CFqdnResolver::RunL() + { + delete iFqdn; + iFqdn = NULL; + + iCallback.AddressResolveCompleted( iStatus.Int(), iNameEntry ); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Cancels FQDN address resolving. +// --------------------------------------------------------------------------- +// +void CFqdnResolver::DoCancel() + { + iConnection.CancelResolveAddress(); + + delete iFqdn; + iFqdn = NULL; + } diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/iachangeobserver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/iachangeobserver.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,139 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: active object, that monitors internal address change +* +*/ + + +#include "ikedebug.h" +#include "ikepluginsessionif.h" +#include "internaladdress.h" +#include "eventmediatorapi.h" + +// CLASS HEADER +#include "iachangeobserver.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CIaChangeObserver* CIaChangeObserver::NewL( TUint32 aVpnIapId, + const TInetAddr& aDnsServerAddr, + MIkePluginSessionIf& aIkePluginSession, + MIkeDebug& aDebug ) + { + CIaChangeObserver* self = new (ELeave) CIaChangeObserver( aVpnIapId, + aDnsServerAddr, + aIkePluginSession, + aDebug ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CIaChangeObserver::~CIaChangeObserver() + { + Cancel(); + iEventMediator.Close(); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CIaChangeObserver::CIaChangeObserver( TUint32 aVpnIapId, + const TInetAddr& aDnsServerAddr, + MIkePluginSessionIf& aIkePluginSession, + MIkeDebug& aDebug ) + : CActive( EPriorityStandard ), + iVpnIapId( aVpnIapId ), + iDnsServerAddr( aDnsServerAddr ), + iIkePluginSession( aIkePluginSession ), + iDebug( aDebug ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +void CIaChangeObserver::ConstructL() + { + User::LeaveIfError( iEventMediator.Connect() ); + } + +// --------------------------------------------------------------------------- +// Requests asynchronous internal address change notification. +// --------------------------------------------------------------------------- +// +void CIaChangeObserver::StartObserving() + { + iIkePluginSession.NotifyInternalAddressChanged( iInternalAddress, + iStatus ); + SetActive(); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles completion of asynchronous notification request. +// --------------------------------------------------------------------------- +// +void CIaChangeObserver::RunL() + { + __ASSERT_DEBUG( iStatus.Int() == KErrNone || + iStatus.Int() == KErrCancel, + User::Invariant() ); + + if ( iStatus.Int() == KErrNone ) + { + // VPN NET id is not needed in reporting internal address change. + TConnectionInfo connectionInfo( iVpnIapId, 0 ); + TConnectionInfoBuf pckgConnectionInfo( connectionInfo ); + + TVPNAddressPckg pckgVpnAddress( iInternalAddress ); + TInt err = iEventMediator.ReportEvent( EKmdAddressChangeEvent, + pckgConnectionInfo, + pckgVpnAddress ); + err = err; + +#ifdef _DEBUG + TBuf<80> txt_addr; + iInternalAddress.iVPNIfAddr.OutputWithScope(txt_addr); + DEBUG_LOG3(_L("Internal address changed to %S, VPN IAP id=%d, err=%d"), + &txt_addr, iVpnIapId, err ); +#endif + + StartObserving(); + } + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles cancellation of asynchronous notification request. +// --------------------------------------------------------------------------- +// +void CIaChangeObserver::DoCancel() + { + iIkePluginSession.CancelNotifyInternalAddressChanged(); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/ikepcaptrace.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/ikepcaptrace.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,417 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class that logs ike messages in pcap format +* +*/ + +#include +#include + +#include "ikepcaptrace.h" + +_LIT(KLogDirectoryFormat, "c:\\logs\\%S\\"); +_LIT(KTraceFileName, "ikemsg.pcap"); + +static const TUint KIpAndUdpHeaderLength = 28; +static const TUint KFixedHdrLength = 28; +static const TUint KNonEspMarkerLength = 4; +static const TInt KNatPort = 4500; + +_LIT(KUnixTimeZeroDes, "19700101:000000.000000"); +static const TTime KUnixTimeZero(KUnixTimeZeroDes); + +#define SWAP_BYTE_ORDER32(a) ((a) >> 24) | ((a) >> 8 & 0xff00) |((a) << 8 & 0xff0000) | ((a) << 24); +#define SWAP_BYTE_ORDER16(a) ((a) >> 8 | (a) << 8) + +CIkePcapTrace* CIkePcapTrace::NewL(const TDesC& aLogFolder) + { + CIkePcapTrace* self = new (ELeave) CIkePcapTrace(); + CleanupStack::PushL(self); + self->ConstructL(aLogFolder); + CleanupStack::Pop(self); + + return self; + } + + +CIkePcapTrace::CIkePcapTrace() + { + } + + +void CIkePcapTrace::ConstructL(const TDesC& aLogFolder) + { + User::LeaveIfError(iFileServer.Connect()); + + TFileName* traceFileName = new (ELeave) TFileName; + CleanupDeletePushL(traceFileName); + traceFileName->Format(KLogDirectoryFormat, &aLogFolder); + + if (BaflUtils::FolderExists(iFileServer, *traceFileName)) + { + traceFileName->Append(KTraceFileName); + + if (BaflUtils::FileExists(iFileServer, *traceFileName)) + { + TInt position = 0; + User::LeaveIfError(iPcapFile.Open(iFileServer, *traceFileName, EFileWrite)); + User::LeaveIfError(iPcapFile.Seek(ESeekEnd, position)); + } + else + { + User::LeaveIfError(iPcapFile.Create(iFileServer, *traceFileName, EFileWrite)); + TInt err = WritePcapHeader(); + if (err != KErrNone) + { + iPcapFile.Close(); + User::LeaveIfError(iFileServer.Delete(*traceFileName)); + User::Leave(err); + } + } + iWriteTrace = ETrue; + } + else + { + iWriteTrace = EFalse; + } + CleanupStack::PopAndDestroy(traceFileName); + } + + +CIkePcapTrace::~CIkePcapTrace() + { + iPcapFile.Close(); + iFileServer.Close(); + } + +void CIkePcapTrace::TraceMessage(const TDesC8& aMessage, + const TInetAddr& aSourceAddress, + const TInetAddr& aDestinationAddress, + TEncryptionType aEncryptionType) + { + if (iWriteTrace) + { + HBufC8* msgCopy = aMessage.Alloc(); + if (msgCopy != NULL) + { + TPtr8 msgCopyPtr = msgCopy->Des(); + DoTraceMessage(msgCopyPtr, aSourceAddress, aDestinationAddress, + aEncryptionType); + } + delete msgCopy; + msgCopy = NULL; + } + } + + + +void CIkePcapTrace::DoTraceMessage(TPtr8& aMsgCopy, + const TInetAddr& aSourceAddress, + const TInetAddr& aDestinationAddress, + TEncryptionType aEncryptionType) + { + + if ((aSourceAddress.Family() == KAfInet || + aSourceAddress.IsV4Compat() || + aSourceAddress.IsV4Mapped()) && + (aDestinationAddress.Family() == KAfInet || + aDestinationAddress.IsV4Compat() || + aDestinationAddress.IsV4Mapped())) + { + TInt length = aMsgCopy.Length(); + if (aSourceAddress.Port() == KNatPort) + { + length+=KNonEspMarkerLength; + } + WriteRecordHeader(length); + WriteIpAndUdpHeader(aMsgCopy, aSourceAddress, aDestinationAddress); + if ( aSourceAddress.Port() == KNatPort ) + { + WriteNonEspMarker(); + } + WriteIkeMessage(aMsgCopy, aEncryptionType); + iPcapFile.Flush(); + } + } + + +TInt CIkePcapTrace::WriteRecordHeader(TUint32 aIkeMsgLength) + { + static const TUint KRecordHeaderLength = 4; + TUint32 recordHeader[KRecordHeaderLength]; + + TUint32 currentSeconds = 0; + TTime currentTime; + currentTime.HomeTime(); + + TTimeIntervalSeconds secondsFrom; + if (currentTime.SecondsFrom(KUnixTimeZero, secondsFrom) == KErrNone) + { + currentSeconds = secondsFrom.Int(); + } + + TUint32 microseconds = currentTime.DateTime().MicroSecond(); + + recordHeader[0] = currentSeconds; + recordHeader[1] = microseconds; + recordHeader[2] = aIkeMsgLength + KIpAndUdpHeaderLength; + recordHeader[3] = aIkeMsgLength + KIpAndUdpHeaderLength; + + TPtrC8 recordHdrPtr((TUint8*)recordHeader, KRecordHeaderLength * sizeof(TUint32)); + return iPcapFile.Write(recordHdrPtr); + } + +TInt CIkePcapTrace::WriteIpAndUdpHeader(const TDesC8& aMessage, + TInetAddr aSourceAddress, + TInetAddr aDestinationAddress) + { + static const TUint KIpHeaderLength = 20; + static const TUint KUdpHeaderLength = KIpAndUdpHeaderLength - KIpHeaderLength; + + //Generate IP header + aSourceAddress.ConvertToV4(); + aDestinationAddress.ConvertToV4(); + + TUint32 source = SWAP_BYTE_ORDER32(aSourceAddress.Address()); + TUint32 destination = SWAP_BYTE_ORDER32(aDestinationAddress.Address()); + + TUint8 ipAndUdpHeader[] = { 0x45, 0x00, 0x13, 0x88, + 0x00, 0x28, 0x00, 0x00, + 0xfe, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, //source IP address + 0x00, 0x00, 0x00, 0x00, //destination IP address + 0x00, 0x00, 0x00, 0x00, //udp header + 0x00, 0x00, 0x00, 0x00}; + + Mem::Copy(ipAndUdpHeader + 12, &source, sizeof(source)); //copies the source address to header + Mem::Copy(ipAndUdpHeader + 16, &destination, sizeof(destination)); //copies the source address to header + + + //Generate UDP header + TUint16 sourcePort = aSourceAddress.Port(); + TUint16 destinationPort = aDestinationAddress.Port(); + TUint16 udpDatagramLength = KUdpHeaderLength + aMessage.Length(); + if ( sourcePort == KNatPort ) + { + udpDatagramLength += KNonEspMarkerLength; + } + sourcePort = SWAP_BYTE_ORDER16(sourcePort); + destinationPort = SWAP_BYTE_ORDER16(destinationPort); + udpDatagramLength = SWAP_BYTE_ORDER16(udpDatagramLength); + + TUint8* udpHeader = ipAndUdpHeader + KIpHeaderLength; + Mem::Copy(udpHeader, &sourcePort, sizeof(sourcePort)); + Mem::Copy(udpHeader + 2, &destinationPort, sizeof(destinationPort)); + Mem::Copy(udpHeader + 4, &udpDatagramLength, sizeof(udpDatagramLength)); + + TPtrC8 headerPtr(ipAndUdpHeader, KIpAndUdpHeaderLength); + return iPcapFile.Write(headerPtr); + } + +TInt CIkePcapTrace::WriteNonEspMarker() + { + TUint8 nonEspMarker[] = { 0x00, 0x00, 0x00, 0x00 }; + + TPtrC8 ptr(nonEspMarker, KNonEspMarkerLength); + return iPcapFile.Write(ptr); + } + +TInt CIkePcapTrace::WriteIkeMessage(TPtr8& aMsgCopy, TEncryptionType aEncryptionType) + { + const TInt KVersionPosition = 17; + + TInt err = KErrNone; + if (aMsgCopy.Length() < KFixedHdrLength) + { + //This is a bit too short for an IKE packet. + //Just write the packet to log anyway. It might give some info to someone. + err = iPcapFile.Write(aMsgCopy); + } + else + { + //Version check: + if (aMsgCopy[KVersionPosition] == 0x10) + { + err = WriteIkeV1Message(aMsgCopy); + } + else + { + err = WriteIkeV2Message(aMsgCopy, aEncryptionType); + } + } + + return err; + } + + +TInt CIkePcapTrace::WriteIkeV1Message(TPtr8& aMsgCopy) + { + //This should already be checked by the caller. + __ASSERT_DEBUG(aMsgCopy.Length() >= KFixedHdrLength, User::Invariant()); + + const TUint KEncryptionBitPosition = 19; + const TUint KFirstNextPayloadPosition = 16; + const TUint KFixedPayloadHdrLength = 4; + + const TUint8 KPayloadNone = 0x00; + const TUint8 KPayloadHash = 0x08; + const TUint8 KPayloadSignature = 0x09; + const TUint8 KPayloadReservedRangeStart = 0x0E; + + aMsgCopy[KEncryptionBitPosition] = aMsgCopy[KEncryptionBitPosition] & 0xFE; + + TUint8 nextPayloadId = aMsgCopy[KFirstNextPayloadPosition]; + TPtr8 msgEnd(aMsgCopy.MidTPtr(KFixedHdrLength)); + + while(nextPayloadId != KPayloadNone && + msgEnd.Length() > KFixedPayloadHdrLength) + { + //Read the lenght of the payload + TUint16 payloadLength = ((TUint16)msgEnd[2]) << 8 | msgEnd[3]; + + if (nextPayloadId == KPayloadHash || + nextPayloadId == KPayloadSignature || + nextPayloadId >= KPayloadReservedRangeStart) + { + if(msgEnd.Length() >= payloadLength && + payloadLength >= KFixedPayloadHdrLength ) + { + // Zero out payload data. + TUint16 dataLength = payloadLength - KFixedPayloadHdrLength; + TPtr8 payloadData = msgEnd.MidTPtr(KFixedPayloadHdrLength, dataLength); + payloadData.FillZ(); + } + else + { + //There seems to be something wrong with the packet. + //Zero out the rest of the packet and write it to the log. + msgEnd.FillZ(); + msgEnd[0] = KPayloadNone; + } + } + + nextPayloadId = msgEnd[0]; + if (nextPayloadId != KPayloadNone && + msgEnd.Length() >= payloadLength) + { + msgEnd.Set(msgEnd.MidTPtr(payloadLength)); + } + else + { + msgEnd.Set(msgEnd.MidTPtr(msgEnd.Length())); + } + } + + return iPcapFile.Write(aMsgCopy); + } + + +TInt CIkePcapTrace::WriteIkeV2Message(TPtr8& aMsgCopy, TEncryptionType aEncryptionType) + { + //This should already be checked by the caller. + __ASSERT_DEBUG(aMsgCopy.Length() >= KFixedHdrLength, User::Invariant()); + + const TUint KFirstNextPayloadPosition = 16; + const TUint KFixedPayloadHdrLength = 4; + + const TUint8 KPayloadNone = 0x00; + const TUint8 KEncryptedPayload = 0x2e; + const TUint8 KAuthPayload = 0x27; + const TUint8 KEapPayload = 0x30; + + TUint8 nextPayloadId = aMsgCopy[KFirstNextPayloadPosition]; + TPtr8 msgEnd(aMsgCopy.MidTPtr(KFixedHdrLength)); + while(nextPayloadId != KPayloadNone && + msgEnd.Length() > KFixedPayloadHdrLength) + { + //Read the lenght of the payload + TUint16 payloadLength = ((TUint16)msgEnd[2]) << 8 | msgEnd[3]; + + switch(nextPayloadId) + { + case KEncryptedPayload: + //change the encrypted payload length to match + //the initialization vector length. + msgEnd[2] = 0x00; + switch(aEncryptionType) + { + case EEncrDes: //falls through + case EEncrDes3: + msgEnd[3] = 0x0c; + break; + case EEncrAesCbc: + msgEnd[3] = 0x14; + break; + } + payloadLength = msgEnd[3]; + break; + case KAuthPayload: + { + const TUint8 KAuthPayloadHdrLength = 8; + if (payloadLength > KAuthPayloadHdrLength && + msgEnd.Length() >= payloadLength) + { + // Zero out payload data. + TPtr8 authData = msgEnd.MidTPtr(KAuthPayloadHdrLength, + payloadLength - KAuthPayloadHdrLength); + authData.FillZ(); + } + } + break; + case KEapPayload: + { + const TUint8 KTotalFixEapHdrLength = 9; + if (payloadLength > KTotalFixEapHdrLength && + msgEnd.Length() >= payloadLength) + { + // Zero out payload data. + TPtr8 eapTypeData = msgEnd.MidTPtr(KTotalFixEapHdrLength, + payloadLength - KTotalFixEapHdrLength); + eapTypeData.FillZ(); + } + } + break; + } + nextPayloadId = msgEnd[0]; + if (nextPayloadId != KPayloadNone && + msgEnd.Length() >= payloadLength) + { + msgEnd.Set(msgEnd.MidTPtr(payloadLength)); + } + else + { + msgEnd.Set(msgEnd.MidTPtr(msgEnd.Length())); + } + } + + return iPcapFile.Write(aMsgCopy); + } + + +TInt CIkePcapTrace::WritePcapHeader() + { + static const TUint KPcapHeaderLength = 24; + TUint8 pCapHeader[] = { 0xd4, 0xc3, 0xb2, 0xa1, // magic number + 0x02, 0x00, 0x04, 0x00, //major, minor version + 0x00, 0x00, 0x00, 0x00, //time offset + 0x00, 0x00, 0x00, 0x00, // accuracy of timestamps + 0xff, 0xff, 0x00, 0x00, // max length of captured packets, in octets + 0x0c, 0x00, 0x00, 0x00, // data link type + }; + + TPtrC8 pCapHeaderPtr(pCapHeader, KPcapHeaderLength); + return iPcapFile.Write(pCapHeaderPtr); + } + + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/ikepluginhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/ikepluginhandler.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,218 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Handler of an IKE protocol plugin +* +*/ + + +#include "ikedebug.h" +#include "ikeplugindefs.h" +#include "ikepluginif.h" +#include "ikepluginsessionhandler.h" +#include "kmdeventloggerif.h" + +// CLASS HEADER +#include "ikepluginhandler.h" + +_LIT( KIkePluginPaths, "" ); // No additional paths. +_LIT( KIkeV1Library, "ikev1lib" ); +_LIT( KIkeV2Library, "ikev2lib" ); + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CIkePluginHandler* CIkePluginHandler::NewL( TInt aIkeVersion, + MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ) + { + CIkePluginHandler* self = new ( ELeave ) CIkePluginHandler( aIkeVersion, + aEventLogger, + aDebug ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CIkePluginHandler::~CIkePluginHandler() + { + __ASSERT_DEBUG( iIkePluginSessions.Count() == 0, + User::Invariant() ); + iIkePluginSessions.Close(); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CIkePluginHandler::CIkePluginHandler( TInt aIkeVersion, + MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ) + : iIkeVersion( aIkeVersion ), + iEventLogger( aEventLogger ), + iDebug( aDebug ) + { + __ASSERT_DEBUG( ( iIkeVersion == KIkeV1 || + iIkeVersion == KIkeV2 ), + User::Invariant() ); + } + +// --------------------------------------------------------------------------- +// Creates IKE plugin session. +// --------------------------------------------------------------------------- +// +CIkePluginSessionHandler& CIkePluginHandler::CreateIkePluginSessionL( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + IkeSocket::TIpVersion aIpVersion, + const TInetAddr& aDnsServer, + CIkeConnectionInterface& aConnection, + MIkePluginSessionHandlerCallback& aCallback ) + { + CIkePluginSessionHandler* sessionHandler = NULL; + TRAPD( err, sessionHandler = &DoCreateIkePluginSessionL( aVpnIapId, + aVpnNetId, + aVpnInterfaceIndex, + aIpVersion, + aDnsServer, + aConnection, + aCallback ) ); + + if ( err != KErrNone ) + { + DeleteIkePluginSession( aVpnIapId ); + User::Leave( err ); + } + + return *sessionHandler; + } + +// --------------------------------------------------------------------------- +// Deletes IKE plugin session. IKE plugin is unloaded if there are no more +// sessions. +// --------------------------------------------------------------------------- +// +void CIkePluginHandler::DeleteIkePluginSession( TUint32 aVpnIapId ) + { + TInt count = iIkePluginSessions.Count(); + + for ( TInt i=0; iVpnIapId() == aVpnIapId ) + { + CIkePluginSessionHandler* sessionHandler = iIkePluginSessions[i]; + iIkePluginSessions.Remove( i ); + delete sessionHandler; + sessionHandler = NULL; + break; + } + } + + if ( iIkePluginSessions.Count() == 0 ) + { + UnloadIkePlugin(); + } + } + +// --------------------------------------------------------------------------- +// Creates IKE plugin session. IKE plugin is loaded if not yet loaded. +// --------------------------------------------------------------------------- +// +CIkePluginSessionHandler& CIkePluginHandler::DoCreateIkePluginSessionL( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + IkeSocket::TIpVersion aIpVersion, + const TInetAddr& aDnsServerAddr, + CIkeConnectionInterface& aConnection, + MIkePluginSessionHandlerCallback& aCallback ) + { + if ( iIkePluginSessions.Count() == 0 ) + { + LoadIkePluginL(); + } + + CIkePluginSessionHandler* sessionHandler = CIkePluginSessionHandler::NewLC( aVpnIapId, + aVpnNetId, + aVpnInterfaceIndex, + IkeSocket::TIkeMajorVersion(iIkeVersion), + aIpVersion, + aDnsServerAddr, + aConnection, + *iIkePlugin, + aCallback, + iDebug ); + iIkePluginSessions.AppendL( sessionHandler ); + CleanupStack::Pop( sessionHandler ); + + return *sessionHandler; + } + +// --------------------------------------------------------------------------- +// Loads IKE plugin. +// --------------------------------------------------------------------------- +// +void CIkePluginHandler::LoadIkePluginL() + { + TInt status( KErrNone ); + + switch( iIkeVersion ) + { + case KIkeV1: + { + TUidType uidType( KIkePluginUid1, KIkePluginUid2, KIkeV1PluginUid3 ); + status = iLibrary.Load( KIkeV1Library, KIkePluginPaths, uidType ); + break; + } + case KIkeV2: + { + TUidType uidType( KIkePluginUid1, KIkePluginUid2, KIkeV2PluginUid3 ); + status = iLibrary.Load( KIkeV2Library, KIkePluginPaths, uidType ); + break; + } + default: + { + status = KErrNotSupported; + break; + } + } + + DEBUG_LOG2( _L("Loading IKE plugin library, IKE version=%d, status=%d"), iIkeVersion, status ); + User::LeaveIfError( status ); + + CreateIkePluginL factoryMethodL = reinterpret_cast( iLibrary.Lookup(1) ); + TRAPD( err, ( iIkePlugin = factoryMethodL( iEventLogger, iDebug ) ) ); + if ( err != KErrNone ) + { + DEBUG_LOG1( _L("Could not create IKE plugin, err=%d"), err ); + UnloadIkePlugin(); + User::Leave( err ); + } + } + +// --------------------------------------------------------------------------- +// Unloads IKE plugin. +// --------------------------------------------------------------------------- +// +void CIkePluginHandler::UnloadIkePlugin() + { + DEBUG_LOG1( _L("Unloading IKE Plugin library, IKE version=%d"), iIkeVersion ); + delete iIkePlugin; + iIkePlugin = NULL; + iLibrary.Close(); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/ikepluginsessionhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/ikepluginsessionhandler.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,287 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Handler of an IKE protocol plugin session +* +*/ + + +#include + +#include "errorobserver.h" +#include "iachangeobserver.h" +#include "ikeconnectioninterface.h" +#include "ikedebug.h" +#include "ikepluginif.h" +#include "ikepluginsessionif.h" +#include "ikesocketdefs.h" +#include "internaladdress.h" + +// CLASS HEADER +#include "ikepluginsessionhandler.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CIkePluginSessionHandler* CIkePluginSessionHandler::NewLC( TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + IkeSocket::TIkeMajorVersion aIkeVersion, + IkeSocket::TIpVersion aIpVersion, + const TInetAddr& aDnsServerAddr, + CIkeConnectionInterface& aConnection, + MIkePluginIf& aIkePlugin, + MIkePluginSessionHandlerCallback& aCallback, + MIkeDebug& aDebug ) + { + CIkePluginSessionHandler* self = new (ELeave) CIkePluginSessionHandler( aVpnIapId, + aIkeVersion, + aIpVersion, + aCallback, + aDebug ); + CleanupStack::PushL( self ); + self->ConstructL( aVpnNetId, + aVpnInterfaceIndex, + aDnsServerAddr, + aConnection, + aIkePlugin ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CIkePluginSessionHandler::~CIkePluginSessionHandler() + { + Cancel(); + + delete iErrorObserver; + delete iIaChangeObserver; + delete iIkePluginSession; + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CIkePluginSessionHandler::CIkePluginSessionHandler( TUint32 aVpnIapId, + IkeSocket::TIkeMajorVersion aIkeVersion, + IkeSocket::TIpVersion aIpVersion, + MIkePluginSessionHandlerCallback& aCallback, + MIkeDebug& aDebug ) + : CActive( EPriorityStandard ), + iVpnIapId( aVpnIapId ), + iIkeVersion( aIkeVersion ), + iIpVersion( aIpVersion ), + iCallback( aCallback ), + iDebug( aDebug ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CIkePluginSessionHandler::ConstructL( TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + const TInetAddr& aDnsServerAddr, + CIkeConnectionInterface& aConnection, + MIkePluginIf& aIkePlugin ) + { + if ( iIkeDataInterface == NULL ) + { + iIkeDataInterface = &aConnection.OpenDataInterfaceL( iIkeVersion, + iIpVersion ); + } + + iIkePluginSession = aIkePlugin.CreateSessionL( iVpnIapId, + aVpnNetId, + aVpnInterfaceIndex, + *iIkeDataInterface ); + + iErrorObserver = CErrorObserver::NewL( *iIkePluginSession, + iCallback, + iDebug ); + + iIaChangeObserver = CIaChangeObserver::NewL( iVpnIapId, + aDnsServerAddr, + *iIkePluginSession, + iDebug ); + + DEBUG_LOG(_L("IKE plugin session created.")); + } + +// --------------------------------------------------------------------------- +// Starts negotiation with a remote host asynchronously. +// --------------------------------------------------------------------------- +// +void CIkePluginSessionHandler::NegotiateWithHost( const CIkeData& aIkeData ) + { + __ASSERT_DEBUG( iState == EIdle, + User::Invariant() ); + iIkePluginSession->NegotiateWithHost( aIkeData, + iInternalAddress, + iStatus ); + SetActive(); + iState = ENegotiatingWithHost; + } + +// --------------------------------------------------------------------------- +// Cancels negotiation request. +// --------------------------------------------------------------------------- +// +void CIkePluginSessionHandler::CancelNegotiateWithHost() + { + if ( iState == ENegotiatingWithHost && + IsActive() ) + { + Cancel(); + TVPNAddress empty; + iCallback.NegotiationStarted( KErrCancel, + empty ); + } + } + +// --------------------------------------------------------------------------- +// Deletes session. +// --------------------------------------------------------------------------- +// +void CIkePluginSessionHandler::DeleteSession( TBool aSilentClose ) + { + iErrorObserver->Cancel(); + iIaChangeObserver->Cancel(); + + if ( iState == ENegotiated ) + { + // Delete session asynchronously. + iIkePluginSession->DeleteSession( aSilentClose, iStatus ); + SetActive(); + iState = EDeletingSession; + } + else if ( iState == EDeletingSession ) + { + // Session deletion is already in progress. Cancelling it deletes + // session silently. + CancelDeleteSession(); + } + else if ( iState == EIdle ) + { + // Session deletion can be requested, if negotiate request has failed. + // In this case, it is enough to complete request. + TRequestStatus* ownStatus = &iStatus; + *ownStatus = KRequestPending; + SetActive(); + + User::RequestComplete( ownStatus, KErrNone ); + } + else + { + ASSERT( EFalse ); + } + } + +// --------------------------------------------------------------------------- +// Cancels session deletion request. +// --------------------------------------------------------------------------- +// +void CIkePluginSessionHandler::CancelDeleteSession() + { + if ( IsActive() ) + { + Cancel(); + iCallback.IkePluginSessionClosed( KErrCancel ); + } + } + +// --------------------------------------------------------------------------- +// Returns VPN IAP Id. +// --------------------------------------------------------------------------- +// +TInt CIkePluginSessionHandler::VpnIapId() const + { + return iVpnIapId; + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles completion of asynchronous request. +// --------------------------------------------------------------------------- +// +void CIkePluginSessionHandler::RunL() + { + DEBUG_LOG2( _L("CIkePluginSessionHandler::RunL, iState=%d, iStatus=%d"), + iState, iStatus.Int() ); + + switch ( iState ) + { + case ENegotiatingWithHost: + if ( iStatus.Int() == KErrNone ) + { + iErrorObserver->StartObserving(); + iIaChangeObserver->StartObserving(); + iState = ENegotiated; + } + else + { + iState = EIdle; + } + // Ownership of internal address transferred. + iCallback.NegotiationStarted( iStatus.Int(), + iInternalAddress ); + break; + case EDeletingSession: // Fall through + case EIdle: + iState = EIdle; + iCallback.IkePluginSessionClosed( iStatus.Int() ); + break; + default: + ASSERT( EFalse ); + break; + } + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles cancellation of asynchronous request. +// --------------------------------------------------------------------------- +// +void CIkePluginSessionHandler::DoCancel() + { + DEBUG_LOG1( _L("CIkePluginSessionHandler::DoCancel, iState=%d"), + iState ); + + switch ( iState ) + { + case ENegotiatingWithHost: + iIkePluginSession->CancelNegotiateWithHost(); + iInternalAddress = TVPNAddress(); + // Session deletion is needed later, if negotiate request has + // already been completed from IKE plugin session. + iState = ENegotiated; + break; + case EDeletingSession: + iIkePluginSession->CancelDeleteSession(); + iState = EIdle; + break; + case EIdle: + break; + default: + ASSERT( EFalse ); + break; + } + } diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/kmddebuglogger.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/kmddebuglogger.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,217 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Write logs in debug builds +* +*/ + + +// CLASS HEADER +#include "kmddebuglogger.h" + +#if defined(_DEBUG) +_LIT(KLogFolder,"vpn"); +_LIT(KLogFile,"kmd.txt"); +#endif + +// ======== MEMBER FUNCTIONS ======== + +#ifndef _DEBUG +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CKmdDebugLogger* CKmdDebugLogger::NewL() + { + CKmdDebugLogger* self = new ( ELeave ) CKmdDebugLogger; + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CKmdDebugLogger::~CKmdDebugLogger() + { + } + +#else + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CKmdDebugLogger* CKmdDebugLogger::NewL() + { + CKmdDebugLogger* self = new ( ELeave ) CKmdDebugLogger; + self->ConstructL(); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CKmdDebugLogger::~CKmdDebugLogger() + { + delete iIkePcapTrace; + iFileLogger.Close(); + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CKmdDebugLogger::ConstructL() + { + User::LeaveIfError( iFileLogger.Connect() ); + iFileLogger.SetDateAndTime( ETrue, ETrue ); + iFileLogger.CreateLog( KLogFolder, KLogFile, EFileLoggingModeAppend ); + + iIkePcapTrace = CIkePcapTrace::NewL(KLogFolder); + } + +// --------------------------------------------------------------------------- +// Writes to log. +// --------------------------------------------------------------------------- +// +void CKmdDebugLogger::LogWrite( const TDesC& aText ) + { + const TInt KMaxLineWidth( 100 ); + const TInt textLength( aText.Length() ); + TInt charsLeft( textLength ); + + while ( charsLeft ) + { + if ( charsLeft >= KMaxLineWidth ) + { + // Write next KMaxLineWidth chars. + iFileLogger.Write( aText.Mid( textLength-charsLeft, KMaxLineWidth ) ); + charsLeft -= KMaxLineWidth; + } + else + { + // Write remaining chars (= KMaxLineWidth ) + { + // Write next KMaxLineWidth chars. + iFileLogger.Write( aText.Mid( textLength-charsLeft, KMaxLineWidth ) ); + charsLeft -= KMaxLineWidth; + } + else + { + // Write remaining chars ( aFmt, ... ) + { + VA_LIST list; + VA_START( list, aFmt ); + + iFileLogger.WriteFormat( aFmt, list ); + } + +// --------------------------------------------------------------------------- +// Writes to log. +// --------------------------------------------------------------------------- +// +void CKmdDebugLogger::LogWriteF( TRefByValue aFmt, ... ) + { + VA_LIST list; + VA_START( list,aFmt ); + + iFileLogger.WriteFormat( aFmt, list ); + } + +// --------------------------------------------------------------------------- +// Writes array to log. +// --------------------------------------------------------------------------- +// +void CKmdDebugLogger::LogWriteArray( const TUint8* aArray, TInt aLength ) + { + ASSERT(aArray); + HBufC *buf = HBufC::New( aLength*4+1 ); // max 3 num and a blank (+1 for /n) + if ( !buf ) + { + return; + } + + for ( TInt i=0; iDes().AppendFormat(_L(" ")); + } + buf->Des().AppendFormat( _L("%02.2x"), aArray[i] ); // key Data byte2byte + } + + LogWrite( buf->Des() ); + + delete buf; + buf = NULL; + } + +// --------------------------------------------------------------------------- +// Writes number to log. +// --------------------------------------------------------------------------- +// +void CKmdDebugLogger::LogWriteNum( TUint aNum ) + { + const TInt KMaxNumLength( 20 ); + TBuf buf; + buf.AppendFormat( _L("%u\n"), aNum ); // key Data byte2byte + LogWrite( buf ); + } + +// --------------------------------------------------------------------------- +// Writes message to PCap log. +// --------------------------------------------------------------------------- +// +void CKmdDebugLogger::TraceMessage(const TDesC8& aMessage, + const TInetAddr& aSourceAddress, + const TInetAddr& aDestinationAddress, + CIkePcapTrace::TEncryptionType aEncryptionType) + { + iIkePcapTrace->TraceMessage(aMessage, + aSourceAddress, aDestinationAddress, + aEncryptionType); + } + + +#endif //_DEBUG diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/kmdeventlogger.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/kmdeventlogger.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,305 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: KMD event logger +* +*/ + + +#include +#include +#include "eventviewer.h" +#include "ikedebug.h" +#include "vpnclientuids.h" + +// CLASS HEADER +#include "kmdeventlogger.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CKmdEventLogger* CKmdEventLogger::NewL( MIkeDebug& aDebug ) + { + CKmdEventLogger* self = new ( ELeave ) CKmdEventLogger( aDebug ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CKmdEventLogger::~CKmdEventLogger() + { + iEventMediator.Close(); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CKmdEventLogger::CKmdEventLogger( MIkeDebug& aDebug ) + : iDebug( aDebug ) + { + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CKmdEventLogger::ConstructL() + { + User::LeaveIfError( iEventMediator.Connect() ); + } + +// --------------------------------------------------------------------------- +// From class MKmdEventLoggerIf +// Writes event to event log. +// --------------------------------------------------------------------------- +// +void CKmdEventLogger::LogEvent( TLogCategory aCategory, + TInt aMsgId, + TInt aStatus, + TUint32 aVpnIapId, + const TInetAddr* aGwIp, + const TInetAddr* aLocalAddr ) + { + TUid uid = TUid::Uid( KUidKmdServer ); + + TBuf<40> ipAddr16; + TBuf8<40> ipAddr; + TBuf8<40> localIpAddr; + TIapName vpnAccessPointName; + TInt addrIndex = KErrNotFound; + TInt iapIndex = KErrNotFound; + TInt statusIndex = KErrNotFound; + TInt realIpIndex = KErrNotFound; + TInt desCount = 0; + TUint8* pointers[4]; + TInt lengths[4]; + + switch ( aMsgId ) + { + case R_VPN_MSG_VPN_GW_NO_RESP: + case R_VPN_MSG_VPN_GW_AUTH_FAIL: + case R_VPN_MSG_VPN_GW_AUTH_OK: + addrIndex = 0; + iapIndex = 1; + break; + + case R_VPN_MSG_VPN_GW_ERR_RESP_RECEIVED: + case R_VPN_MSG_SENT_ERROR_RESPONSE: + addrIndex = 0; + iapIndex = 1; + statusIndex = 2; + break; + + case R_VPN_MSG_DATA_DROPPED_DUE_POLICY: + addrIndex = 0; + statusIndex = 1; + break; + + case R_VPN_MSG_ADDR_INFO_FOR_VPN_AP: + iapIndex = 0; + addrIndex = 1; + realIpIndex = 2; + statusIndex = 3; + break; + + case R_VPN_MSG_REAL_IAP_ACT_FAILED: + realIpIndex = 0; + iapIndex = 1; + statusIndex = 2; + break; + + default: + break; + } + + if ( addrIndex != KErrNotFound ) + { + desCount ++; + pointers[addrIndex] = (TUint8*)ipAddr.Ptr(); + if ( aGwIp ) + { + aGwIp->Output(ipAddr16); + ipAddr.Copy(ipAddr16); + lengths[addrIndex] = ipAddr.Length(); + } + else + { + lengths[addrIndex] = 0; + } + } + + if ( statusIndex != KErrNotFound ) + { + desCount ++; + pointers[statusIndex] = (TUint8*)&aStatus; + lengths[statusIndex] = sizeof(aStatus); + } + + if ( iapIndex != KErrNotFound ) + { + // + // VPN IAP id shall be converted to VPN access point name using + // eventviewer API. + // + desCount ++; + pointers[iapIndex] = (TUint8*)vpnAccessPointName.Ptr(); + if ( aVpnIapId != 0 ) + { + EventViewer::GetIapName(aVpnIapId, vpnAccessPointName); + lengths[iapIndex] = vpnAccessPointName.Length(); + } + else + { + lengths[iapIndex] = 0; + } + } + + if ( realIpIndex != KErrNotFound ) + { + desCount ++; + pointers[realIpIndex] = (TUint8*)localIpAddr.Ptr(); + ipAddr16.SetLength(0); + if ( aLocalAddr != NULL ) + { + aLocalAddr->Output(ipAddr16); + } + localIpAddr.Copy(ipAddr16); + lengths[realIpIndex] = localIpAddr.Length(); + } + + TInt ret( KErrNone ); + + switch ( desCount ) + { + case 0: + { + ret = iEventMediator.ReportLogEvent( uid, + aCategory, + aMsgId, + 0 ); + } + break; + + case 1: + { + TPtr8 parm1(pointers[0], lengths[0], lengths[0]); + ret = iEventMediator.ReportLogEvent( uid, + aCategory, + aMsgId, + 1, + &parm1 ); + } + break; + + case 2: + { + TPtr8 parm1(pointers[0], lengths[0], lengths[0]); + TPtr8 parm2(pointers[1], lengths[1], lengths[1]); + ret = iEventMediator.ReportLogEvent( uid, + aCategory, + aMsgId, + 2, + &parm1, + &parm2 ); + } + break; + + case 3: + { + TPtr8 parm1(pointers[0], lengths[0], lengths[0]); + TPtr8 parm2(pointers[1], lengths[1], lengths[1]); + TPtr8 parm3(pointers[2], lengths[2], lengths[2]); + ret = iEventMediator.ReportLogEvent( uid, + aCategory, + aMsgId, + 3, + &parm1, + &parm2, + &parm3 ); + } + break; + + case 4: + { + TPtr8 parm1(pointers[0], lengths[0], lengths[0]); + TPtr8 parm2(pointers[1], lengths[1], lengths[1]); + TPtr8 parm3(pointers[2], lengths[2], lengths[2]); + TPtr8 parm4(pointers[3], lengths[3], lengths[3]); + ret = iEventMediator.ReportLogEvent( uid, + aCategory, + aMsgId, + 4, + &parm1, + &parm2, + &parm3, + &parm4 ); + } + break; + + default: + ret = ret; + break; + + } + + DEBUG_LOG3( _L("Logging event %x with %d parameters, report status = %d"), + aMsgId, desCount, ret ); + + } + +// --------------------------------------------------------------------------- +// From class MKmdEventLoggerIf +// Writes event to event log. +// --------------------------------------------------------------------------- +// +void CKmdEventLogger::LogEvent( TKmdLogCategory aCategory, + TInt aMsgId, + TInt aStatus, + TUint32 aVpnIapId, + const TInetAddr* aGwIp, + const TInetAddr* aLocalAddr ) + { + TLogCategory logCategory; + switch ( aCategory ) + { + case KLogInfo: + logCategory = EInfo; + break; + case KLogWarning: + logCategory = EWarning; + break; + case KLogError: + logCategory = EError; + break; + default: + logCategory = EDebug; + break; + } + + LogEvent( logCategory, + aMsgId, + aStatus, + aVpnIapId, + aGwIp, + aLocalAddr ); + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/kmdserver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/kmdserver.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,329 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: KMD server +* +*/ + + +// INTERNAL INCLUDES +#include "ikedebug.h" +#include "ikeplugindefs.h" +#include "ikepluginhandler.h" +#include "kmddebuglogger.h" +#include "kmdeventlogger.h" +#include "kmdsession.h" +#include "secpolreader.h" +#include "vpnconnection.h" + +// CLASS HEADER +#include "kmdserver.h" + +const TUint CKmdServer::iKmdServerRangeCount = 2; + +const TInt CKmdServer::iKmdServerRanges[iKmdServerRangeCount] = + { + CKmdServer::KKmdStartConnection, + CKmdServer::KKmdCancelResolveAddress+1 + }; + +const TUint8 CKmdServer::iKmdServerElementIndex[iKmdServerRangeCount] = + { + 0, + CPolicyServer::ENotSupported + }; + +const CPolicyServer::TPolicyElement CKmdServer::iKmdServerElements[] = + { + {_INIT_SECURITY_POLICY_C1(ECapabilityNetworkControl), + CPolicyServer::EFailClient}, + }; + +const CPolicyServer::TPolicy CKmdServer::iKmdServerPolicy = + { + 0, // All connect attempts are checked + iKmdServerRangeCount, // Count of ranges + iKmdServerRanges, // 0-6, 7... + iKmdServerElementIndex, // Only range 0-6 are checked + iKmdServerElements // The list of policy elements + }; + +const TInt KIkeV1PluginHandlerIndex( 0 ); +const TInt KIkeV2PluginHandlerIndex( 1 ); + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CKmdServer* CKmdServer::NewL() + { + CKmdServer* self = new ( ELeave ) CKmdServer; + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CKmdServer::~CKmdServer() + { + iIpsecPolicyServ.Close(); + iVpnConnections.ResetAndDestroy(); + iVpnConnections.Close(); + delete iIkePluginHandlers[0]; + delete iIkePluginHandlers[1]; + delete iSecpolReader; + delete iEventLogger; + +#ifdef _DEBUG + if ( iDebugLogger != NULL ) + { + iDebugLogger->LogWrite(_L("KMD server stopped.")); + } +#endif + delete iDebugLogger; + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CKmdServer::CKmdServer() : + CPolicyServer( EPriorityStandard, iKmdServerPolicy ) + { + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CKmdServer::ConstructL() + { + iDebugLogger = CKmdDebugLogger::NewL(); + +#ifdef _DEBUG + iDebugLogger->LogWrite(_L("------------------------------------------------------")); + iDebugLogger->LogWrite(_L("Starting KMD server.")); + iDebugLogger->LogWrite(_L("------------------------------------------------------")); +#endif + + User::LeaveIfError( iIpsecPolicyServ.Connect() ); + iEventLogger = CKmdEventLogger::NewL( *iDebugLogger ); + iSecpolReader = CSecpolReader::NewL( *iEventLogger, + *iDebugLogger ); + iIkePluginHandlers[KIkeV1PluginHandlerIndex] = CIkePluginHandler::NewL( KIkeV1, + *iEventLogger, + *iDebugLogger ); + iIkePluginHandlers[KIkeV2PluginHandlerIndex] = CIkePluginHandler::NewL( KIkeV2, + *iEventLogger, + *iDebugLogger ); + + StartL( KKmdServerName ); + +#ifdef _DEBUG + iDebugLogger->LogWrite(_L("KMD server started.")); +#endif + } + +// --------------------------------------------------------------------------- +// Information that KMD session has been closed. +// --------------------------------------------------------------------------- +// +void CKmdServer::KmdSessionClosed() + { + iSessionCount--; + __ASSERT_DEBUG(iSessionCount >= 0, User::Invariant()); + + StopKmdServer(); + } + +// --------------------------------------------------------------------------- +// Creates VPN connection object. +// --------------------------------------------------------------------------- +// +CVpnConnection& CKmdServer::CreateVpnConnectionL(TUint32 aVpnIapId) + { +#ifndef _DEBUG + for ( TInt i = 0; i < iVpnConnections.Count(); ++i ) + { + __ASSERT_DEBUG( iVpnConnections[i]->VpnIapId() != aVpnIapId, User::Invariant() ); + } +#endif //_DEBUG + + CVpnConnection* newConnection = CVpnConnection::NewLC( aVpnIapId, + *this, + *iDebugLogger ); + User::LeaveIfError( iVpnConnections.Append( newConnection ) ); + CleanupStack::Pop( newConnection ); + + return *newConnection; + } + +// --------------------------------------------------------------------------- +// Gets VPN connection object. +// --------------------------------------------------------------------------- +// +CVpnConnection& CKmdServer::GetVpnConnectionL( TUint32 aVpnIapId ) + { + CVpnConnection* connection = NULL; + for ( TInt i = 0; i < iVpnConnections.Count(); ++i ) + { + CVpnConnection* c = iVpnConnections[i]; + if ( c->VpnIapId() == aVpnIapId ) + { + connection = c; + break; + } + } + + if ( connection == NULL ) + { + User::Leave( KErrNotFound ); + } + return *connection; + } + +// --------------------------------------------------------------------------- +// Deletes VPN connection object. +// --------------------------------------------------------------------------- +// +void CKmdServer::DeleteVpnConnection( TUint32 aVpnIapId ) + { + TInt connectionCount = iVpnConnections.Count(); + for ( TInt i = 0; i < connectionCount; ++i ) + { + CVpnConnection* c = iVpnConnections[i]; + if ( c->VpnIapId() == aVpnIapId ) + { + iVpnConnections.Remove( i ); + delete c; + break; + } + } + + StopKmdServer(); + } + +// --------------------------------------------------------------------------- +// Creates IKE plugin session. +// --------------------------------------------------------------------------- +// +CIkePluginSessionHandler& CKmdServer::CreateIkePluginSessionL( TInt aIkeVersion, + IkeSocket::TIpVersion aIpVersion, + CIkeConnectionInterface& aConnection, + TUint32 aVpnIapId, + TUint32 aVpnNetId, + TUint32 aVpnInterfaceIndex, + const TInetAddr& aDnsServerAddr, + MIkePluginSessionHandlerCallback& aCallback ) + { + TInt index( 0 ); + switch ( aIkeVersion ) + { + case KIkeV1: + { + index = KIkeV1PluginHandlerIndex; + break; + } + case KIkeV2: + { + index = KIkeV2PluginHandlerIndex; + break; + } + default: + { + ASSERT( EFalse ); + } + } + return iIkePluginHandlers[index]->CreateIkePluginSessionL( aVpnIapId, + aVpnNetId, + aVpnInterfaceIndex, + aIpVersion, + aDnsServerAddr, + aConnection, + aCallback ); + } + +// --------------------------------------------------------------------------- +// Deletes IKE plugin session. +// --------------------------------------------------------------------------- +// +void CKmdServer::DeleteIkePluginSession( TInt aIkeVersion, + TUint32 aVpnIapId ) + { + TInt index( 0 ); + switch ( aIkeVersion ) + { + case KIkeV1: + { + index = KIkeV1PluginHandlerIndex; + break; + } + case KIkeV2: + { + index = KIkeV2PluginHandlerIndex; + break; + } + default: + { + ASSERT( EFalse ); + break; + } + } + iIkePluginHandlers[index]->DeleteIkePluginSession( aVpnIapId ); + } + +// --------------------------------------------------------------------------- +// Returns debug trace interface. +// --------------------------------------------------------------------------- +// +MIkeDebug& CKmdServer::Debug() + { + __ASSERT_DEBUG( iDebugLogger != NULL, + User::Invariant() ); + + return *iDebugLogger; + } + +// --------------------------------------------------------------------------- +// Creates a server-side session object. +// --------------------------------------------------------------------------- +// +CSession2* CKmdServer::NewSessionL( const TVersion& /*aVersion*/, + const RMessage2& /*aMessage*/) const + { + CKmdSession* session = CKmdSession::NewL( *const_cast( this ), + *iDebugLogger ); + iSessionCount++; + return session; + } + +// --------------------------------------------------------------------------- +// Stops KMD server if there exist neither client sessions nor active +// connections. +// --------------------------------------------------------------------------- +// +void CKmdServer::StopKmdServer() + { + if ( iSessionCount == 0 && + iVpnConnections.Count() == 0 ) + { + // Stop scheduluder that was started by RunServerL(). + CActiveScheduler::Stop(); + } + } diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/kmdsession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/kmdsession.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,423 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Server side session of KMDServer +* +*/ + + +#include "ikedebug.h" +#include "ikepolparser.h" +#include "kmdserver.h" +#include "kmdapi.h" +#include "kmdserver.pan" + +// CLASS HEADER +#include "kmdsession.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CKmdSession* CKmdSession::NewL( CKmdServer& aServer, + MIkeDebug& aDebug ) + { + CKmdSession* self = new ( ELeave ) CKmdSession( aServer, aDebug ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CKmdSession::~CKmdSession() + { + DEBUG_LOG( _L("CKmdSession::~CKmdSession") ); + + DoCancelStartConnection(); + DoCancelActivate(); + DoCancelResolveAddress(); + + iServer.KmdSessionClosed(); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CKmdSession::CKmdSession( CKmdServer& aServer, + MIkeDebug& aDebug ) + : iServer( aServer ), + iDebug( aDebug ) + { + DEBUG_LOG( _L("CKmdSession::CKmdSession") ); + } + +// --------------------------------------------------------------------------- +// From class CSession2. +// Handles the servicing of a client request from KMD API. +// --------------------------------------------------------------------------- +// +void CKmdSession::ServiceL( const RMessage2& aMessage ) + { + switch ( aMessage.Function() ) + { + case CKmdServer::KKmdStartConnection: + { + DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdStartConnection")); + + if ( iConnectionStarter != NULL ) + { + aMessage.Panic( KKmdPanicCategory, + EKmdPanicRequestAlreadyPending ); + } + else + { + __ASSERT_DEBUG( iPendingStartConnection.IsNull(), + User::Invariant() ); + iVpnIapId = aMessage.Int0(); + + // Create new VPN connection object and start connection. + CVpnConnection& vpnConnection = iServer.CreateVpnConnectionL( iVpnIapId ); + TRAPD( err, iConnectionStarter = CConnectionStarter::NewL( vpnConnection, *this ) ); + if ( err != KErrNone ) + { + iServer.DeleteVpnConnection( iVpnIapId ); + User::Leave( err ); + } + iPendingStartConnection = aMessage; + iConnectionStarter->StartRealConnection(); + } + break; + } + case CKmdServer::KKmdCancelStartConnection: + { + DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdCancelStartConnection")); + + DoCancelStartConnection(); + aMessage.Complete( KErrNone ); + break; + } + case CKmdServer::KKmdActivateAsync: + { + DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdActivateAsync")); + + if ( iActivationStarter != NULL ) + { + aMessage.Panic( KKmdPanicCategory, + EKmdPanicRequestAlreadyPending ); + } + else + { + __ASSERT_DEBUG( iPendingActivate.IsNull(), + User::Invariant() ); + iVpnIapId = aMessage.Int0(); + CVpnConnection* vpnConnection = NULL; + TRAPD( err, vpnConnection = &iServer.GetVpnConnectionL( iVpnIapId ) ); + + if ( err != KErrNone ) + { + __ASSERT_DEBUG( err == KErrNotFound, User::Invariant() ); + aMessage.Complete( KErrArgument ); + } + else + { + // Read VPN interface name. + HBufC* vpnIfName = HBufC::NewLC( aMessage.GetDesLength( 1 ) ); + TPtr vpnIfNameDes = vpnIfName->Des(); + aMessage.ReadL( 1, vpnIfNameDes ); + + CIkeDataArray* ikeList = CIkeDataArray::NewL( 1 ); + CleanupStack::PushL( ikeList ); + + // Read 8 bit IKE policy data. + HBufC8* ikePolicy8 = HBufC8::NewLC( aMessage.GetDesLength( 2 ) ); + TPtr8 policyDes8 = ikePolicy8->Des(); + aMessage.ReadL( 2, policyDes8 ); + + // Copy read IKE policy data to 16 bit buffer. + HBufC* ikeConf = HBufC::NewL( policyDes8.Length() ); + TPtr ikeConfPtr = ikeConf->Des(); + ikeConfPtr.Copy( policyDes8 ); + CleanupStack::PopAndDestroy( ikePolicy8 ); + CleanupStack::PushL( ikeConf ); + + // Parse IKE policy data. + TIkeParser ikeParser( *ikeConf ); + ikeParser.MainParseL( ikeList ); + CleanupStack::PopAndDestroy( ikeConf ); + + // Get first IKE policy section. + CIkeData* ikeData = NULL; + if (ikeList->Count() > 0) + { + ikeData = (*ikeList)[0]; + } + else + { + User::Leave( KKmdIkePolicyFileErr ); + } + + // Start negotiation. + iActivationStarter = CActivationStarter::NewL( *vpnConnection, + *this, + iServer.Debug() ); + iPendingActivate = aMessage; + iActivationStarter->Activate( *ikeData, + vpnIfNameDes ); + + CleanupStack::PopAndDestroy( ikeList ); + CleanupStack::PopAndDestroy( vpnIfName ); + } + } + break; + } + case CKmdServer::KKmdCancelActivateAsync: + { + DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdCancelActivateAsync")); + + DoCancelActivate(); + aMessage.Complete( KErrNone ); + break; + } + case CKmdServer::KKmdStopConnection: + { + DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdStopConnection")); + + if ( iConnectionStopper != NULL ) + { + aMessage.Panic( KKmdPanicCategory, + EKmdPanicRequestAlreadyPending ); + } + else + { + __ASSERT_DEBUG( iPendingStopConnection.IsNull(), + User::Invariant() ); + + TUint32 vpnIapId = aMessage.Int0(); + TKmdStopConnection::TType type = (TKmdStopConnection::TType)aMessage.Int1(); + + CVpnConnection& connection = iServer.GetVpnConnectionL( vpnIapId ); + iConnectionStopper = CConnectionStopper::NewL( connection, *this ); + + iPendingStopConnection = aMessage; + iConnectionStopper->StopVpnConnection( type == TKmdStopConnection::EForced ); + } + break; + } + case CKmdServer::KKmdResolveAddress: + { + DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdResolveAddress")); + + if ( iFqdnResolver != NULL ) + { + aMessage.Panic( KKmdPanicCategory, + EKmdPanicRequestAlreadyPending ); + } + else + { + __ASSERT_DEBUG( iPendingFqdnResolve.IsNull(), + User::Invariant() ); + iVpnIapId = aMessage.Int0(); + CVpnConnection* vpnConnection = NULL; + TRAPD( err, vpnConnection = &iServer.GetVpnConnectionL( iVpnIapId ) ); + if ( err != KErrNone ) + { + __ASSERT_DEBUG( err == KErrNotFound, User::Invariant() ); + aMessage.Complete( KErrArgument ); + } + else + { + HBufC* fqdn = HBufC::NewLC( aMessage.GetDesLengthL( 1 ) ); + TPtr fqdnDes = fqdn->Des(); + aMessage.ReadL( 1, fqdnDes ); + + iFqdnResolver = CFqdnResolver::NewL( *vpnConnection, *this ); + iPendingFqdnResolve = aMessage; + iFqdnResolver->ResolveAddress( fqdn ); + CleanupStack::Pop( fqdn ); + } + } + break; + } + case CKmdServer::KKmdCancelResolveAddress: + { + DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdCancelResolveAddress")); + + DoCancelResolveAddress(); + aMessage.Complete( KErrNone ); + break; + } + default: + { + DEBUG_LOG1(_L("CKmdSession::ServiceL, illegal command=%d"), + aMessage.Function()); + + aMessage.Panic( KKmdPanicCategory, EKmdPanicIllegalCommand ); + break; + } + } + + } + +// --------------------------------------------------------------------------- +// From class MConnectionStarterCallback. +// Notification about completion of real connection starting. +// --------------------------------------------------------------------------- +// +void CKmdSession::RealConnectionStarted( TInt aStatus, + TInt aRealIap, + TInt aRealNetwork ) + { + DEBUG_LOG3(_L("Real connection started, status=%d, IAP id=%d, NET id=%d"), + aStatus, aRealIap, aRealNetwork ); + + __ASSERT_DEBUG( !iPendingStartConnection.IsNull(), User::Invariant() ); + + delete iConnectionStarter; + iConnectionStarter = NULL; + + if ( aStatus == KErrNone ) + { + TVpnRealConnectionParams realConfig = { aRealIap, aRealNetwork }; + TPckg realConfigPckg( realConfig ); + + aStatus = iPendingStartConnection.Write( 1, realConfigPckg ); + } + iPendingStartConnection.Complete( aStatus ); + } + +// --------------------------------------------------------------------------- +// From class MConnectionStopperCallback. +// Notification about completion of VPN connection stopping. +// --------------------------------------------------------------------------- +// +void CKmdSession::VpnConnectionStopped( TInt aStatus ) + { + DEBUG_LOG1(_L("VPN connection stopped, status=%d"), aStatus ); + + __ASSERT_DEBUG( !iPendingStopConnection.IsNull(), User::Invariant() ); + + delete iConnectionStopper; + iConnectionStopper = NULL; + + iPendingStopConnection.Complete( aStatus ); + } + +// --------------------------------------------------------------------------- +// From class MFqdnResolverCallback. +// Notifies about completion of FQDN address resolving. +// --------------------------------------------------------------------------- +// +void CKmdSession::AddressResolveCompleted( TInt aStatus, + TNameEntry aNameEntry ) + { + DEBUG_LOG1(_L("FQDN address resolving completed, status=%d"), aStatus ); + + __ASSERT_DEBUG( !iPendingFqdnResolve.IsNull(), + User::Invariant() ); + + delete iFqdnResolver; + iFqdnResolver = NULL; + + if ( aStatus == KErrNone ) + { + aStatus = iPendingFqdnResolve.Write( 2, aNameEntry ); + } + + iPendingFqdnResolve.Complete( aStatus ); + } + +// --------------------------------------------------------------------------- +// From class MActivationStarterCallback. +// Notification about completion of activation. +// --------------------------------------------------------------------------- +// +void CKmdSession::ActivationCompleted( TInt aStatus, + const TVPNAddress& aVirtualIp ) + { + DEBUG_LOG1(_L("Activation completed, status=%d"), aStatus ); + + __ASSERT_DEBUG( !iPendingActivate.IsNull(), + User::Invariant() ); + + if ( aStatus == KErrNone ) + { + TVPNAddressPckg addrPkcg( aVirtualIp ); + aStatus = iPendingActivate.Write( 3, addrPkcg ); + } + iPendingActivate.Complete( aStatus ); + + delete iActivationStarter; + iActivationStarter = NULL; + } + +// --------------------------------------------------------------------------- +// Cancels real connection starting. +// --------------------------------------------------------------------------- +// +void CKmdSession::DoCancelStartConnection() + { + if ( iConnectionStarter ) + { + __ASSERT_DEBUG( !iPendingStartConnection.IsNull(), + User::Invariant() ); + + delete iConnectionStarter; // Cancels ongoing connection starting. + iConnectionStarter = NULL; + + iPendingStartConnection.Complete( KErrCancel ); + + // Delete VPN connection object. + iServer.DeleteVpnConnection( iVpnIapId ); + } + } + +// --------------------------------------------------------------------------- +// Cancels activating. +// --------------------------------------------------------------------------- +// +void CKmdSession::DoCancelActivate() + { + if ( iActivationStarter ) + { + __ASSERT_DEBUG( !iPendingActivate.IsNull(), + User::Invariant() ); + + delete iActivationStarter; // Cancels ongoing activation. + iActivationStarter = NULL; + + iPendingActivate.Complete( KErrCancel ); + } + } + +// --------------------------------------------------------------------------- +// Cancels FQDN address resolving. +// --------------------------------------------------------------------------- +// +void CKmdSession::DoCancelResolveAddress() + { + if ( iFqdnResolver ) + { + __ASSERT_DEBUG( !iPendingFqdnResolve.IsNull(), + User::Invariant() ); + + delete iFqdnResolver; // Cancels ongoing resolving. + iFqdnResolver = NULL; + + iPendingFqdnResolve.Complete( KErrCancel ); + } + } + diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/kmdstarter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/kmdstarter.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: KMD starter +* +*/ + + +#include "srvstarter.h" +#include "kmdserver.h" + +CServer2* Starter::CreateAndStartServerL() + { + return CKmdServer::NewL(); + } + +TPtrC Starter::ServerName() + { + return KKmdServerName().Mid(0); + } diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/secpolpayload.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/secpolpayload.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,275 @@ +/* +* Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Security policy module payload structures +* +*/ + + +#include +#include +#include +#include + +// CLASS HEADER +#include "secpolpayload.h" + +// ======== LOCAL FUNCTIONS ======== + +#ifdef _DEBUG +static TInt IsShort( TDes &aStr, const TDesC &aName, TInt aMin, TInt aLength ) + { + aStr.Append( aName ); + if ( aMin <= aLength ) + { + return 0; + } + aStr.Append(_L(".. truncated")); + return 1; + } +#endif + +// ======== MEMBER FUNCTIONS ======== + +// +// IPv4 HDR Dump routine +// +void THdrIP4::Dump( TDes &aStr, TInt /*aLength*/ ) + { +#ifndef _DEBUG + (void)aStr; +#endif + +#ifdef _DEBUG + const TInt KMaxBufLength( 40 ); + TBuf buf; + TInetAddr addr; + + addr.SetAddress( SrcAddr() ); + addr.OutputWithScope( buf ); + aStr.Append( _L(" src=") ); + aStr.Append( buf ); + addr.SetAddress( DstAddr() ); + addr.OutputWithScope( buf ); + aStr.Append( _L(" dst=") ); + aStr.Append( buf ); +#endif + } + +TBool THdrIP4::IsUnicast() + { + TInetAddr addr; + TUint32 ip4Addr = DstAddr(); + addr.SetAddress( ip4Addr ); + TBool status = addr.IsUnicast(); + if ( status != KErrNone ) + { + // + // If at least 7 leftmost bits in address are set to 1 this + // address is interpreted to be IPv4 subnet broadcast + // + status = ( ( ip4Addr & 0x7f ) != 0x7f ); + } + return status; + } + +// +// IPv6 HDR Dump routine +// +void THdrIP6::Dump( TDes &aStr, TInt /*aLength*/ ) + { +#ifndef _DEBUG + (void)aStr; +#endif + +#ifdef _DEBUG + const TInt KMaxBufLength( 40 ); + TBuf buf; + TInetAddr addr; + + addr.SetAddress( SrcAddr() ); + addr.OutputWithScope( buf ); + aStr.Append( _L(" src=") ); + aStr.Append( buf ); + addr.SetAddress( DstAddr() ); + addr.OutputWithScope( buf ); + aStr.Append( _L(" dst=") ); + aStr.Append( buf ); +#endif + } + +TBool THdrIP6::IsUnicast() + { + TInetAddr addr; + addr.SetAddress( DstAddr() ); + return addr.IsUnicast(); + } + +TSecpolPayload::TSecpolPayload( const TUint8* aPtr ) + : iRaw( aPtr ) + { + } + +void TSecpolPayload::Dump( TDes &aStr, TInt aLength, TInt aProtocol ) + { +#ifndef _DEBUG + (void)aStr; + (void)aLength; + (void)aProtocol; +#endif + +#ifdef _DEBUG + for (;;) + { + TInt skip; + switch ( aProtocol ) + { + case 50: // ESP + if ( IsShort( aStr, + _L(" ESP"), + iESP->MinHeaderLength(), + aLength ) ) + { + return; + } + aStr.AppendFormat( _L("(spi=%x,seq=%d)"), + ByteOrder::Swap32( iESP->SPI() ), + iESP->Sequence() ); + return; // Cannot go past ESP + case 51: + if ( IsShort( aStr, + _L(" AH"), + iAH->MinHeaderLength(), + aLength ) ) + { + return; + } + aStr.AppendFormat(_L("(spi=%x,seq=%d,protcol=%d)"), + iAH->SPI(), iAH->Sequence(), iAH->NextHeader() ); + skip = iAH->HeaderLength(); + aProtocol = iAH->NextHeader(); + break; // AH + case 4: + if ( IsShort( aStr, + _L(" IP4-in-IP"), + iIP4->MinHeaderLength(), + aLength ) ) + { + return; + } + ((THdrIP4 *)iIP4)->Dump(aStr, aLength); + skip = iIP4->HeaderLength(); + aProtocol = iIP4->Protocol(); + break; + case 1: // Fall through + case 58: + if ( IsShort( aStr, + _L(" ICMP"), + iICMP->MinHeaderLength(), + aLength ) ) + { + return; + } + aStr.AppendFormat(_L("(type=%d,code=%d)"), + iICMP->Type(), iICMP->Code() ); + return; + case 6: + if ( IsShort( aStr, + _L(" TCP"), + iTCP->MinHeaderLength(), + aLength ) ) + { + return; + } + aStr.AppendFormat(_L("(src=%d,dst=%d)"), + iTCP->SrcPort(), iTCP->DstPort()); + return; + case 17: + if ( IsShort( aStr, + _L(" UDP"), + iUDP->MinHeaderLength(), + aLength ) ) + return; + aStr.AppendFormat(_L("(src=%d,dst=%d)"), + iUDP->SrcPort(), iUDP->DstPort()); + return; + case KProtocolInet6Ipip: + if ( IsShort( aStr, + _L(" IP6-in-IP"), + iIP6->MinHeaderLength(), + aLength ) ) + { + return; + } + ((THdrIP6 *)iIP6)->Dump( aStr, aLength ); + skip = iIP6->HeaderLength(); + aProtocol = iIP6->NextHeader(); + break; + case KProtocolInet6HopOptions: + if ( IsShort( aStr, + _L(" HBH"), + iOPT->MinHeaderLength(), + aLength ) ) + { + return; + } + skip = iOPT->HeaderLength(); + aProtocol = iOPT->NextHeader(); + break; + case KProtocolInet6RoutingHeader: + if ( IsShort( aStr, + _L(" RTH"), + iRTH->MinHeaderLength(), + aLength ) ) + { + return; + } + aProtocol = iRTH->NextHeader(); + skip = iRTH->HeaderLength(); + break; + case KProtocolInet6Fragment: + if ( IsShort( aStr, + _L(" FRAG"), + iFRH->MinHeaderLength(), + aLength ) ) + { + return; + } + aStr.AppendFormat(_L("(prot=%d,id=%d,offset=%d)"), + iFRH->NextHeader(), iFRH->Id(), iFRH->FragmentOffset()); + if ( iFRH->MFlag() ) + { + aStr.Append(_L(" More")); + } + return; + case KProtocolInet6NoNextHeader: + aStr.AppendFormat(_L(" NNH")); + return; + case KProtocolInet6DestinationOptions: + if ( IsShort( aStr, + _L(" DOP"), + iOPT->MinHeaderLength(), + aLength ) ) + return; + skip = iOPT->HeaderLength(); + aProtocol = iOPT->NextHeader(); + break; + default: + aStr.AppendFormat(_L(" protocol=%d"), aProtocol); + return; + } + aLength -= skip; + iRaw += skip; + } +#endif + } diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/secpolreader.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/secpolreader.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,287 @@ +/* +* Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Security policy module +* +*/ + + +#include +#include +#include +#include +#include "ikedebug.h" +#include "kmdeventloggerif.h" +#include "secpolpayload.h" + +// CLASS HEADER +#include "secpolreader.h" + +// ======== LOCAL FUNCTIONS ======== + +#ifdef _DEBUG + +// --------------------------------------------------------------------------- +// Returns error description. +// --------------------------------------------------------------------------- +// +static const TPtrC IpsecError( TInt aReason ) + { + switch ( aReason ) + { + case EIpsec_RMBUF: return _L("RMBUF operation failed unexcpectedly"); + // + // AH and ESP + // + case EIpsec_CorruptPacketIn: return _L("Truncated or corrupt packet or header"); + case EIpsec_CorruptPacketOut: return _L("Corrupt packet after IPSEC operations"); + case EIpsec_EspInboundSA: return _L("The inbound SA for ESP does not exist"); + case EIpsec_EspAuthentication: return _L("Authentication check failed in ESP"); + case EIpsec_EspAuthAlg: return _L("Required auth algorithm for ESP not available/installed"); + case EIpsec_EspEncrAlg: return _L("Required encrypt algorithm for ESP not available/installed"); + case EIpsec_AhAuthAlg: return _L("Required auth algorithm for AH not available/installed"); + case EIpsec_AhInboundSA: return _L("The inbound SA for AH does not exist"); + case EIpsec_AhIcvLength: return _L("ICV length in packet does not match algorithm"); + case EIpsec_AhAuthentication: return _L("Authentication check failed in AH"); + case EIpsec_PacketLength: return _L("Invalid/corrupt length of the packet"); + case EIpsec_DataAlignment: return _L("Data not aligned by block size (ESP)"); + case EIpsec_EspPadByte: return _L("The ESP pad byte content is invalid"); + case EIpsec_EspPadLength: return _L("The ESP pad length is corrupt (probably wrong key)"); + case EIpsec_ReplayDuplicate: return _L("Duplicate packet (replay window test)"); + // + // SECPOL + // + case EIpsec_OutboundNotFound: return _L("Outbound SA does not exist, ACQUIRE started"); + case EIpsec_OutboundPending: return _L("Outbooud SA does not exits, ACQUIRE pending"); + case EIpsec_NoSelectorMatch: return _L("None of the policy selectors matched"); + case EIpsec_MaxTransforms: return _L("Incoming packet exceed configured max limit of transforms"); + case EIpsec_TooFewTransforms: return _L("Policy requires IPSEC, none or too little was present"); + case EIpsec_TunnelMismatch: return _L("Tunnelmode does not match the policy"); + case EIpsec_MismatchedSA: return _L("Applied SA does not match the policy"); + case EIpsec_UnrequiredSA: return _L("Applied SA where policy has none"); + case EIpsec_TooManyTransforms: return _L("Incoming packet had more transforms than policy requires"); + case EIpsec_NoBundle: return _L("Incoming packet had transforms, but policy doesn't require any"); + // + // IPv6 additions + // + case EIpsec_AhRMBufSplit: return _L("Inbound AH processing failed (Memory?)"); + case EIpsec_AhPacketTooLong: return _L("Outbound packet would exeed 2**16-1 with AH"); + case EIpsec_AhSequenceWrap: return _L("Outbound sequence # wrapped around for this SA"); + case EIpsec_EspSequenceWrap: return _L("Outbound sequence # wrapped around for this SA"); + case EIpsec_EspBadCipherBlockSize: return _L("Configuration error, cipher block size must be < 256"); + case EIpsec_AcquireFailed: return _L("Acquiring SA failed (no SA available or negotiated)"); + // + // Detail reasons for SA not matching the SA spec in the policy + // (replace one EIpsec_MismatchedSA with multiple detail errors) + // + case EIpsec_MismatchedDestination: return _L("SA destination does not match (internal error?)"); + case EIpsec_MismatchedType: return _L("SA Type (AH/ESP) does not match"); + case EIpsec_MismatchedPFS: return _L("PFS bit is not same"); + case EIpsec_MismatchedAuthAlg: return _L("Auth algorithm doesn't match"); + case EIpsec_MismatchedEncryptAlg: return _L("Encrypt algorithm doesn't match"); + case EIpsec_MismatchReplayWindow: return _L("ReplayWindow length is shorter than required"); + case EIpsec_MismatchSource: return _L("source address does not match"); + case EIpsec_MismatchProxy: return _L("proxy address does not match"); + case EIpsec_MismatchSourcePort: return _L("source port does not match"); + case EIpsec_MismatchDestinationPort:return _L("destination port does not match"); + case EIpsec_MismatchProtocol: return _L("protocol does not match"); + case EIpsec_MismatchSourceIdentity: return _L("source identity does not match"); + case EIpsec_MismatchDestinationIdentity: return _L("destination identity does not match"); + + case EIpsec_BadCipherKey: return _L("Key in SA is too short (for the algorithm) or is weak"); + case EIpsec_UnknownCipherNumber: return _L("Attempting to use algorithm number that is not known"); + case EIpsec_UnknownDigestNumber: return _L("Attempting to use algorithm number that is not known"); + case EIpsec_UnavailableCipher: return _L("No installed library implements the cipher"); + case EIpsec_UnavailableDigest: return _L("No installed library implements the digest"); + // + // Temporary place for new errors + // + case EIpsec_IcmpError: return _L("An ICMP error report containing AH or ESP (for INET6)"); + case EIpsec_LostSA: return _L("An SA has been lost between Apply and Verify, expired? (for SECPOL)"); + case EIpsec_NoInnerSource: return _L("Cannot find inner-src for outbound packet when tunneling (for SECPOL)"); + // + // Special code for NAT Traversal + // + case EIpsec_NotANATTPacket: return _L("UDP packet is NOT a NAT Taversal packet"); + case EIpsec_FragmentMismatch: return _L("IPSEC on fragment is not same as before, packet dropped"); + + default: + return _L("Unknown reason"); + } + } + +#endif + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CSecpolReader* CSecpolReader::NewL( MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ) + { + CSecpolReader* self = new (ELeave) CSecpolReader( aEventLogger, + aDebug ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CSecpolReader::~CSecpolReader() + { + DEBUG_LOG(_L("CSecpolReader::~CSecpolReader")); + Cancel(); + iSocket.Close(); + iSocketServer.Close(); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CSecpolReader::CSecpolReader( MKmdEventLoggerIf& aEventLogger, + MIkeDebug& aDebug ) +: CActive( EPriorityStandard ), + iEventLogger( aEventLogger ), + iDebug( aDebug ) + { + CActiveScheduler::Add( this ); + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CSecpolReader::ConstructL() + { + TInetAddr addr; + User::LeaveIfError( iSocketServer.Connect() ); + User::LeaveIfError( iSocket.Open( iSocketServer, _L("secpol6") ) ); + addr.SetAddress( KInetAddrNone ); + addr.SetPort( 0 ); + User::LeaveIfError( iSocket.Bind( addr ) ); + iSocket.RecvFrom( iMsg, iAddr, 0, iStatus ); + SetActive(); + DEBUG_LOG(_L("CSecpolReader::ConstructL - constructed")); + } + +// --------------------------------------------------------------------------- +// Returns event logger. +// --------------------------------------------------------------------------- +// +MKmdEventLoggerIf& CSecpolReader::EventLogger() + { + return iEventLogger; + } + + +// --------------------------------------------------------------------------- +// From class CActive +// Handles completion of asynchronous reading. +// --------------------------------------------------------------------------- +// +void CSecpolReader::RunL() + { +#ifdef _DEBUG + TBuf<40> buf; + TBuf<1000> str; + TInt protocol = -1; +#endif // _DEBUG + TInt len = 0; + TBool processEvent; + TSecpolPayload packet( iMsg.Ptr() ); + + DEBUG_LOG1(_L("Secpol read, status=%d"), iStatus.Int()); + __ASSERT_DEBUG( iStatus.Int() == KErrNone, + User::Invariant() ); + if ( iStatus.Int() == KErrNone ) + { + switch ( packet.iIP4->Version() ) + { + case 4: + processEvent = ((THdrIP4 *)packet.iRaw)->IsUnicast(); + if ( processEvent ) + { +#ifdef _DEBUG + ((THdrIP4 *)packet.iRaw)->Dump( str, iMsg.Length() ); + protocol = packet.iIP4->Protocol(); +#endif // _DEBUG + len = packet.iIP4->HeaderLength(); + } + break; + case 6: + processEvent = ((THdrIP6 *)packet.iRaw)->IsUnicast(); + if ( processEvent ) + { +#ifdef _DEBUG + ((THdrIP6 *)packet.iRaw)->Dump( str, iMsg.Length() ); + protocol = packet.iIP6->NextHeader(); +#endif // _DEBUG + len = packet.iIP6->HeaderLength(); + } + break; + default: + processEvent = ETrue; +#ifdef _DEBUG + str.Format( _L("Unknown IP protocol version %d"), + (TInt)packet.iIP4->Version() ); +#endif // _DEBUG + break; + } + + if ( processEvent ) + { + if ( len ) + { + packet.iRaw += len; +#ifdef _DEBUG + packet.Dump( str, iMsg.Length()-len, protocol ); +#endif // _DEBUG + } +#ifdef _DEBUG + str.Append( _L(" from ") ); + (TInetAddr::Cast(iAddr)).OutputWithScope( buf ); + str.Append( buf ); + str.Append( _L(" because ") ); + str.Append( IpsecError( iAddr.Port() ) ); + str.AppendFormat( _L(" (%d)"), iAddr.Port() ); + DEBUG_LOG(str); +#endif // _DEBUG + + LOG_KMD_EVENT( MKmdEventLoggerIf::KLogWarning, + R_VPN_MSG_DATA_DROPPED_DUE_POLICY, + (TInt)iAddr.Port(), + 0, + &iAddr ); + } + } + + iSocket.RecvFrom( iMsg, iAddr, 0, iStatus ); // start a new read + SetActive(); + } + +// --------------------------------------------------------------------------- +// From class CActive +// Handles cancellation of asynchronous reading. +// --------------------------------------------------------------------------- +// +void CSecpolReader::DoCancel() + { + iSocket.CancelRecv(); + } diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/vpnconnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/kmdserver/src/vpnconnection.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,490 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: VPN connection specific structures +* +*/ + + +#include +#include + +#include "disconnectionobserver.h" +#include "ikeconnectioninterface.h" +#include "ikedebug.h" +#include "ikeplugindefs.h" +#include "ikepluginsessionhandler.h" +#include "ikepolparser.h" +#include "ikesocketdefs.h" +#include "kmdapi.h" // For error codes +#include "kmdserver.h" + +// CLASS HEADER +#include "vpnconnection.h" + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CVpnConnection* CVpnConnection::NewLC( TUint32 aVpnIapId, + CKmdServer& aServer, + MIkeDebug& aDebug ) + { + CVpnConnection* self = new ( ELeave ) CVpnConnection( aVpnIapId, + aServer, + aDebug ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CVpnConnection::~CVpnConnection() + { + DEBUG_LOG1( _L("CVpnConnection::~CVpnConnection, VPN IAP id=%d"), + iVpnIapId ); + + delete iDisconnectionObserver; + delete iIkeConnection; + + iEventMediator.Close(); + } + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CVpnConnection::CVpnConnection( TUint32 aVpnIapId, + CKmdServer& aServer, + MIkeDebug& aDebug ) + : iServer( aServer ), + iVpnIapId( aVpnIapId ), + iDisconnectEventReceived( EFalse ), + iIkePluginSessionHandler( NULL ), + iDebug( aDebug ) + { + DEBUG_LOG1( _L("CVpnConnection::CVpnConnection, VPN IAP id=%d"), + iVpnIapId ); + } + +// --------------------------------------------------------------------------- +// Second phase construction. +// --------------------------------------------------------------------------- +// +void CVpnConnection::ConstructL() + { + User::LeaveIfError( iEventMediator.Connect() ); + + using namespace CMManager; + + RCmManagerExt cmManagerExt; + cmManagerExt.OpenL(); + CleanupClosePushL( cmManagerExt ); + + RCmConnectionMethodExt vpnConnectionMethod = cmManagerExt.ConnectionMethodL( iVpnIapId ); + CleanupClosePushL( vpnConnectionMethod ); + + iVpnNetId = vpnConnectionMethod.GetIntAttributeL( ECmNetworkId ); + iRealIapId = vpnConnectionMethod.GetIntAttributeL( EVpnIapId ); + iRealSnapId = vpnConnectionMethod.GetIntAttributeL( ECmNextLayerSNAPId ); + + CleanupStack::PopAndDestroy( &vpnConnectionMethod ); + CleanupStack::PopAndDestroy( &cmManagerExt ); + + __ASSERT_DEBUG( iRealIapId != 0 || iRealSnapId != 0, User::Invariant() ); + + iIkeConnection = CIkeConnectionInterface::NewL( iDebug ); + iDisconnectionObserver = CDisconnectionObserver::NewL( *iIkeConnection, *this ); + iDisconnectionObserver->StartObserving(); + } + +// --------------------------------------------------------------------------- +// Starts real network connection. +// --------------------------------------------------------------------------- +// +void CVpnConnection::StartRealConnection( TRequestStatus& aStatus ) + { + __ASSERT_DEBUG( iRealIapId != 0 || iRealSnapId != 0, User::Invariant() ); + iIkeConnection->StartConnection( iRealIapId, iRealSnapId, aStatus ); + } + +// --------------------------------------------------------------------------- +// Cancels real connection starting. +// --------------------------------------------------------------------------- +// +void CVpnConnection::CancelStartRealConnection() + { + iIkeConnection->CancelStartConnection(); + } + +// --------------------------------------------------------------------------- +// Resolves an IP address from FQDN address. +// --------------------------------------------------------------------------- +// +void CVpnConnection::ResolveAddress( const TDesC& aFqdn, + TNameEntry& aNameEntry, + TRequestStatus& aStatus ) + { + iIkeConnection->ResolveFQDNAddress( aFqdn, aNameEntry, aStatus ); + } + +// --------------------------------------------------------------------------- +// Cancels resolving. +// --------------------------------------------------------------------------- +// +void CVpnConnection::CancelResolveAddress() + { + iIkeConnection->CancelResolveFQDNAddress(); + } + +// --------------------------------------------------------------------------- +// Starts negotiation with a remote host. +// --------------------------------------------------------------------------- +// +void CVpnConnection::NegotiateWithHost( CIkeData& aIkeData, + TUint32 aVpnInterfaceIndex, + IkeSocket::TIpVersion aIpVersion, + TVPNAddress& aInternalAddress, + TRequestStatus& aStatus ) + { + __ASSERT_DEBUG( iClientStatusNegotiate == NULL, + User::Invariant() ); + + // Store client's request status and internal address. + iClientStatusNegotiate = &aStatus; + *iClientStatusNegotiate = KRequestPending; + iClientInternalAddress = &aInternalAddress; + + TInt err( KErrNone ); + if ( aIkeData.iIkeVersion == KIkeV1 || aIkeData.iIkeVersion == KIkeV2 ) + { + // Create IKE plugin session. + iIkeVersion = aIkeData.iIkeVersion; + + if ( iIkePluginSessionHandler == NULL ) + { + TRAP( err, iIkePluginSessionHandler = &iServer.CreateIkePluginSessionL( iIkeVersion, + aIpVersion, + *iIkeConnection, + iVpnIapId, + iVpnNetId, + aVpnInterfaceIndex, + aIkeData.iDnsServer.Address(), + *this ) ); + } + } + else + { + err = KKmdIkePolicyFileErr; + } + + if ( err != KErrNone ) + { + User::RequestComplete( iClientStatusNegotiate, err ); + iClientStatusNegotiate = NULL; + return; + } + + if ( aIkeData.iAddr.Family() == KAfInet ) + { + aIkeData.iAddr.ConvertToV4Mapped(); + aIkeData.iMask.ConvertToV4Mapped(); + } + aIkeData.iAddr.SetScope( RealNetId() ); + + // Start negotiation. + iIkePluginSessionHandler->NegotiateWithHost( aIkeData ); + } + +// --------------------------------------------------------------------------- +// Cancels negotiation. +// --------------------------------------------------------------------------- +// +void CVpnConnection::CancelNegotiateWithHost() + { + DoCancelNegotiateWithHost(); + } + + +// --------------------------------------------------------------------------- +// Stops VPN connection. +// --------------------------------------------------------------------------- +// +void CVpnConnection::StopVpnConnection( TBool aSilentClose, + TRequestStatus& aStatus ) + { + __ASSERT_DEBUG( iClientStatusStopVpnConnection == NULL, + User::Invariant() ); + + // Store client's request status. + iClientStatusStopVpnConnection = &aStatus; + *iClientStatusStopVpnConnection = KRequestPending; + + DoStopVpnConnection( aSilentClose ); + } + +// --------------------------------------------------------------------------- +// Cancels VPN connection stoppping. VPN Connection is stopped silently. +// --------------------------------------------------------------------------- +// +void CVpnConnection::CancelStopVpnConnection() + { + DoCancelStopVpnConnection(); + } + +// --------------------------------------------------------------------------- +// Gets local address of real network interface. +// --------------------------------------------------------------------------- +// +TInt CVpnConnection::GetLocalAddress( const IkeSocket::TIpVersion aIpVersion, + TInetAddr& aLocalIp ) + { + return iIkeConnection->GetLocalAddress( aIpVersion, aLocalIp ); + } + +// --------------------------------------------------------------------------- +// Returns VPN IAP Id. +// --------------------------------------------------------------------------- +// +TInt CVpnConnection::VpnIapId() const + { + return iVpnIapId; + } + +// --------------------------------------------------------------------------- +// Returns real IAP Id. +// --------------------------------------------------------------------------- +// +TInt CVpnConnection::RealIapId() const + { + return iIkeConnection->IapId(); + } + +// --------------------------------------------------------------------------- +// Returns real NET Id. +// --------------------------------------------------------------------------- +// +TInt CVpnConnection::RealNetId() const + { + return iIkeConnection->NetId(); + } + +// --------------------------------------------------------------------------- +// From class MDisconnectionObserverCallback. +// Notification about link disconnection. VPN connection is stopped. +// --------------------------------------------------------------------------- +// +void CVpnConnection::DisconnectIndication( TInt aStatus ) + { + // Store disconnection status for reporting it to client. + iDisconnectEventReceived = ETrue; + iDisconnectionStatus = aStatus; + + DEBUG_LOG1( _L("Link disconnected, status=%d"), + iDisconnectionStatus ); + + if ( iDisconnectionStatus == KErrNone ) + { + iDisconnectionStatus = KErrDisconnected; + } + + // Stop VPN connection silently. + DoStopVpnConnection( ETrue ); + } + +// --------------------------------------------------------------------------- +// From class MIkePluginSessionHandlerCallback. +// Notification about completion of negotiate request. +// --------------------------------------------------------------------------- +// +void CVpnConnection::NegotiationStarted( TInt aStatus, + const TVPNAddress& aInternalAddress ) + { + __ASSERT_DEBUG( iIkePluginSessionHandler != NULL, + User::Invariant() ); + + DEBUG_LOG1( _L("NegotiateWithHost completed, status=%d"), + aStatus ); + + // Use disconnection status for reporting if set. + if ( iDisconnectEventReceived ) + { + aStatus = iDisconnectionStatus; + } + + if ( iClientStatusNegotiate != NULL ) + { + *iClientInternalAddress = aInternalAddress; + + // Complete client's request. + User::RequestComplete( iClientStatusNegotiate, aStatus ); + iClientInternalAddress = NULL; + iClientStatusNegotiate = NULL; + } + } + +// --------------------------------------------------------------------------- +// From class MIkePluginSessionHandlerCallback. +// Notification about completion of delete session request. IKE plugin +// session object is deleted and real connection stopped. +// --------------------------------------------------------------------------- +// +void CVpnConnection::IkePluginSessionClosed( TInt aStatus ) + { + __ASSERT_DEBUG( iIkePluginSessionHandler != NULL, + User::Invariant() ); + + DEBUG_LOG1( _L("IKE plugin session closed, status=%d"), + aStatus ); + + iServer.DeleteIkePluginSession( iIkeVersion, iVpnIapId ); + iIkePluginSessionHandler = NULL; + + DoStopRealConnection( aStatus ); + } + +// --------------------------------------------------------------------------- +// From class MIkePluginSessionHandlerCallback. +// Notification about IKE plugin session error. +// --------------------------------------------------------------------------- +// +void CVpnConnection::IkePluginSessionError( TInt aStatus ) + { + // Stop VPN connection silently. + DisconnectIndication( aStatus ); + } + +// --------------------------------------------------------------------------- +// Cancels negotiation. +// --------------------------------------------------------------------------- +// +void CVpnConnection::DoCancelNegotiateWithHost() + { + if ( iIkePluginSessionHandler ) + { + iIkePluginSessionHandler->CancelNegotiateWithHost(); + } + } + +// --------------------------------------------------------------------------- +// Stops VPN connection. +// --------------------------------------------------------------------------- +// +void CVpnConnection::DoStopVpnConnection( TBool aSilentClose ) + { + if ( iIkePluginSessionHandler == NULL ) + { + // Stop real connection immediately. + DoStopRealConnection( KErrNone ); + } + else + { + DoCancelNegotiateWithHost(); + + // Delete IKE plugin session first. + DoDeleteSession( aSilentClose ); + } + } + +// --------------------------------------------------------------------------- +// Cancels VPN connection stopping. VPN Connection is stopped silently. +// --------------------------------------------------------------------------- +// +void CVpnConnection::DoCancelStopVpnConnection() + { + DoCancelDeleteSession(); + + if ( iIkePluginSessionHandler != NULL ) + { + iServer.DeleteIkePluginSession( iIkeVersion, iVpnIapId ); + iIkePluginSessionHandler = NULL; + } + + DoStopRealConnection( KErrCancel ); + } + +// --------------------------------------------------------------------------- +// Starts deletion of IKE plugin session. +// --------------------------------------------------------------------------- +// +void CVpnConnection::DoDeleteSession( TBool aSilentClose ) + { + __ASSERT_DEBUG( iIkePluginSessionHandler != NULL, + User::Invariant() ); + + iIkePluginSessionHandler->DeleteSession( aSilentClose ); + } + +// --------------------------------------------------------------------------- +// Cancels deletion of IKE plugin session. IKE plugin session is deleted +// silently. +// --------------------------------------------------------------------------- +// +void CVpnConnection::DoCancelDeleteSession() + { + if ( iIkePluginSessionHandler != NULL ) + { + iIkePluginSessionHandler->CancelDeleteSession(); + } + } + +// --------------------------------------------------------------------------- +// Stops real network connection. +// --------------------------------------------------------------------------- +// +void CVpnConnection::DoStopRealConnection( TInt aStatus ) + { + iDisconnectionObserver->Cancel(); + iIkeConnection->StopConnection(); + + // Use disconnection status for reporting if set. + if ( iDisconnectEventReceived ) + { + aStatus = iDisconnectionStatus; + } + + if ( iClientStatusStopVpnConnection ) + { + // Complete client's request. + User::RequestComplete( iClientStatusStopVpnConnection, aStatus ); + iClientStatusStopVpnConnection = NULL; + } + DoReportDisconnectEvent( aStatus ); + + // Delete VPN connection object. + iServer.DeleteVpnConnection( iVpnIapId ); + } + +// --------------------------------------------------------------------------- +// Reports disconnect event via Event Mediator API. +// --------------------------------------------------------------------------- +// +void CVpnConnection::DoReportDisconnectEvent( TInt aStatus ) + { + TPckg connInfoDes( iVpnIapId ); + TEventData info; + info.iTaskStatus = aStatus; + TPckg infoDes( info ); + + DEBUG_LOG2( _L("Report disconnect event via event mediator, VPN IAP Id=%d, status=%d"), + iVpnIapId, aStatus ); + + iEventMediator.ReportEvent( EKmdRealIapConnDownEvent, + connInfoDes, + infoDes ); + } diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/bwins/pkiserviceu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/bwins/pkiserviceu.def Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,3 @@ +EXPORTS + ?WinsMain@@YAHXZ @ 1 NONAME ; int __cdecl WinsMain(void) + diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/group/PKIService.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/group/PKIService.mmp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Project definition file for project pkiservice +* +*/ + + + +#include + +TARGET pkiservice.exe +TARGETTYPE exe +UID 0x1000008d 0x101FAE07 + +CAPABILITY CAP_SERVER CommDD NetworkControl +VENDORID VID_DEFAULT + +SOURCEPATH ../src +SOURCE pkiservice.cpp +SOURCE pkisession.cpp +SOURCE pkimapper.cpp +SOURCE pkiwrapper.cpp +SOURCE pkisupport.cpp +SOURCE pkiservicestarter.cpp +SOURCE certificaterequeststore.cpp +SOURCE keyoperationprovider.cpp +SOURCE pkiservicesigner.cpp +SOURCE pkiservicedecryptor.cpp +SOURCE logonservices.cpp +SOURCE keymanager.cpp +SOURCE keyoperationqueue.cpp + +SOURCEPATH ../../vpncommon/src +SOURCE srvstatic.cpp + +USERINCLUDE ../inc +USERINCLUDE ../../pkiserviceapi/inc +USERINCLUDE ../../utlpkcs10/inc +USERINCLUDE ../../utlbase64/inc +USERINCLUDE ../../utlcrypto/inc +USERINCLUDE ../../eventmediatorapi/inc +USERINCLUDE ../../vpncommon/inc +USERINCLUDE ../../../vpnapiimpl/inc +USERINCLUDE ../../vpnmanager/inc + +MW_LAYER_SYSTEMINCLUDE + +LIBRARY CTFramework.lib +LIBRARY certstore.lib +LIBRARY euser.lib +LIBRARY efsrv.lib +LIBRARY utlpkcs10.lib +LIBRARY utlbase64.lib +LIBRARY utlcrypto.lib +LIBRARY bafl.lib +LIBRARY x500.lib +LIBRARY x509.lib +LIBRARY crypto.lib +LIBRARY cryptography.lib +LIBRARY random.lib +LIBRARY pbe.lib +LIBRARY eventmedapi.lib + +DEBUGLIBRARY flogger.lib diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/group/bld.inf Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2000 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file provides the information required for building the +* whole of a IPSeMan.dll. +* +*/ + + + +#include + +PRJ_PLATFORMS + +PRJ_EXPORTS + + +PRJ_MMPFILES + +PKIService.mmp + +PRJ_TESTMMPFILES diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/inc/PKIMapper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/inc/PKIMapper.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,232 @@ +/* +* Copyright (c) 2006-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: CPKIMapper class holds the information required to map API set +* to use the storage model which is not native for that API. +* +*/ + + + +#if !defined (__PKIMAPPER_H__) +#define __PKIMAPPER_H__ + +#include +#include + +#include "pkidefs.h" +#include "pkiserviceclientservercommon.h" + +class TSecurityObjectDescriptor; +class CX500DistinguishedName; +class CX520AttributeTypeAndValue; + +enum TValidity +{ + EValid, + EExpired, + ENotValidYet +}; + + +/** + * CMapDescriptor + * + * Maintains information of installed certificates and keys + * + * @lib internal (pkiservice.exe) + * @since S60 v3.0 + */ +class CMapDescriptor : public CBase +{ + public: + CMapDescriptor() + { + iOwnerType = EPKICACertificate; + iKeySize = 0; + iKeyAlgorithm = EPKIInvalidAlgorithm; + }; + + ~CMapDescriptor() + { + delete iTrustedAuthority; + iTrustedAuthority = NULL; + delete iIdentitySubjectName; + iIdentitySubjectName = NULL; + delete iIdentityRfc822Name; + iIdentityRfc822Name = NULL; + delete iSerialNumber; + iSerialNumber = NULL; + iApplUids.Close(); + }; + CMapDescriptor(TSecurityObjectDescriptor& aDesc); + CMapDescriptor& operator=(CMapDescriptor& aMapDesc); + void SetMapObjectName(const TDesC& aFilename) {iObjectName.Copy(aFilename);}; + TBool IsMatchingL(TSecurityObjectDescriptor &aDesc, + const TBool aInfoOnly, + TPkiServiceStoreType aCertStoreType) const; + + TBool IsEqual(CMapDescriptor &aDesc); + void SetMapSubjectKeyId(const TPKIKeyIdentifier &aKeyId) + { + iSubjectKeyId.Copy(aKeyId); + }; + void SetMapOwnerType(const TPKICertificateOwnerType aOwnerType) {iOwnerType = aOwnerType;}; + void SetMapKeyUsageDer(const TDesC8 &aKeyUsage) + { + iKeyUsageDer.Copy(aKeyUsage); + }; // Optional if only certificate is needed + // Key usage is not defined in the filter, this will be checked separately + void SetMapKeySize(const TUint aKeySize) {iKeySize = aKeySize;}; // Optional if only certificate is needed + // Issuer and serial are not defined in the filter, these will be checked separately + void SetMapTrustedAuthorityL(const TDesC8 &aTrustedAuthority) + { + delete iTrustedAuthority; + iTrustedAuthority = NULL; + iTrustedAuthority = aTrustedAuthority.AllocL(); + }; + void SetMapIdentitySubjectNameL(const TDesC8 &aIdentitySubjectName) + { + delete iIdentitySubjectName; + iIdentitySubjectName = NULL; + iIdentitySubjectName = aIdentitySubjectName.AllocL(); + }; + void SetMapIdentityRfc822NameL(const TDesC8 &aIdentityRfc822Name) + { + delete iIdentityRfc822Name; + iIdentityRfc822Name = NULL; + iIdentityRfc822Name = aIdentityRfc822Name.AllocL(); + }; + void SetMapSerialNumberL(const TDesC8 &aSerialNumber) + { + delete iSerialNumber; + iSerialNumber = NULL; + iSerialNumber = aSerialNumber.AllocL(); + }; + + void SetCertStoreType(TPkiServiceStoreType aCertStoreType); + + void SetMapKeyAlgorithm(const TPKIKeyAlgorithm &aKeyAlgorithm) {iKeyAlgorithm = aKeyAlgorithm;}; + void SetMapStartTime(const TTime &aTime) {iStartTime = aTime;}; + void SetMapEndTime(const TTime &aTime) {iEndTime = aTime;}; + void SetMapTrusted(const TBool &aTrusted) {iIsTrusted = aTrusted;}; + void SetMapIsDeletable(const TBool &aIsDeletable) {iIsDeletable = aIsDeletable;}; + void SetMapApplications(const RArray &aApplications) {for(TInt i=0; i iKeyUsageDer; // Der format flags + TBuf iObjectName; + TUint iKeySize; // Key size + TPKIKeyAlgorithm iKeyAlgorithm; // RSA, DSA + TTime iStartTime; + TTime iEndTime; + TBool iIsDeletable; + TBool iIsTrusted; + RArray iApplUids; + TPkiServiceStoreType iCertStoreType; +}; + +/** + * CPKIMapper + * + * Maintains array of CMapDescriptor objects + * + * @lib internal (pkiservice.exe) + * @since S60 v3.0 + */ +class CPKIMapper : public CBase +{ + public: + // Constructors, destructor + // When constructing an invocation, check if some key/certificate has been manually removed. + static CPKIMapper* NewL(); + static TValidity CertValidity(const TTime &aStartTime, const TTime &aEndTime); + ~CPKIMapper(); + + //////////////////////////////////////////////////////////////////////////////////////////// + // Mapping methods + //////////////////////////////////////////////////////////////////////////////////////////// + // These are new methods, which will be called from ipsecmanager when importing policy or deleting a certificate/key + // In acuagent, these will be called after user key has been generated and authorized by CA + TInt AddMapping(CMapDescriptor &aMap); + TInt DeleteMapping(CMapDescriptor &aDesc); + CMapDescriptor& GetMapDescriptorAtIndex(TInt aIndex); + // One-to-one mapping functions + void GetCertificateKeyIdL(TSecurityObjectDescriptor &aDescriptor, TPKIKeyIdentifier &aKeyId, + TPkiServiceStoreType aStoreType = EPkiStoreTypeUser) const; + + TInt ResolveCertMappingL(TSecurityObjectDescriptor &aDescriptor, TDes16 &aFilename, + TInt &aIndex, const TBool aInfoOnly, + TPkiServiceStoreType aStoreType = EPkiStoreTypeUser) const; + + TInt CertCount(void); + TInt ApplicableCertCount(const RArray& aUidArray); + TInt GetCertListL(const RMessage2& aMessage, TPkiServiceStoreType aStoreType, TBool aDescUsed = EFalse); + void GetApplicableCertListL(const RMessage2& aMessage, const RArray& aUidArray); + + // Function to check whether the given certificate is unique (doesn't exist in cert store) + TBool CertificateIsUniqueL(const TDesC8& aCertData); + + // Function that returns a guaranteedly unique certificate label. + void GenerateUniqueNameL(const TDesC8& aCertData, TDes& aName, + TCertificateOwnerType aOwnerType = ECACertificate); + void SetCacheCreated(); + TBool CacheCreated(); + + private: // implementation + + void DeleteMapping(TInt aIndex); + TBool LabelIsUnique(const TDesC& aLabel) const; + void LogMap(CMapDescriptor& aDescriptor) const; + void LogSearchArguments(TSecurityObjectDescriptor& aDescriptor) const; + + private: // C'tor + + CPKIMapper(); + void ConstructL(); + + private: // data + TBool iCacheCreated; + TInt iCount; + /// Used when generating uniqname + + RPointerArray* iMapping; + TPckgBuf iCurrentDescriptor; + TBuf iObjectName; +}; + +class PkiUtil +{ + public: + static TBool MatchL(const CX500DistinguishedName& aDn1, + const CX500DistinguishedName& aDn2); + + private: + static TBool HasElementL(const CX500DistinguishedName& aDn, + const CX520AttributeTypeAndValue& aElement); +}; + + +#endif \ No newline at end of file diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/inc/certificaterequeststore.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/inc/certificaterequeststore.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2007 - 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class, which handles storing and accessing certificate requests. +* +*/ + + + + +#ifndef C_CERTIFICATEREQUESTSTORE_H +#define C_CERTIFICATEREQUESTSTORE_H + +#include +#include + +#include "pkidefs.h" + +/** + * Class, which handles storing and accessing certificate requests. + * + * @since S60 v3.2 + */ +class CCertificateRequestStore : public CBase + { + +public: + + static CCertificateRequestStore* NewL(); + ~CCertificateRequestStore(); + + TInt CertReqCountL(); + CArrayFixFlat* GetCertReqListLC(); + + HBufC* SaveCertRequestLC(const TDesC8& aCertReqData); + HBufC8* ReadCertRequestLC(const TDesC& aCertReqObjectName); + void DeleteCertRequestL(const TDesC& aCertReqObjectName); + +private: + + void ConstructL(); + + TFileName* GetNewCertReqFileNameLC(); + + RFs iFileSession; + TFileName iPrivatePath; + }; + + +#endif // C_CERTIFICATEREQUESTSTORE_H diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/inc/keymanager.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/inc/keymanager.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: PKI server main module +* +*/ + + + + +#ifndef C_KEYMANAGER_H +#define C_KEYMANAGER_H + +#include +#include +#include "pkidefs.h" + +class CUnifiedKeyStore; +class CCTKeyInfo; +class CLogonServices; + +/** + * A class that handles simple access to the keypairs. + * + * This class provieds following simple key access functionality: + * key pair removal, key pair generation, key pair import and public key + * export. + */ +class CKeyManager : public CActive + { +public: + static CKeyManager* NewL(CLogonServices& aLogonServices); + ~CKeyManager(); + + void RemoveKeyPair(const TPKIKeyIdentifier& aKeyId, + CUnifiedKeyStore& aUnifiedKeyStore, + TInt aUsedKeyStore, + TRequestStatus& aClientStatus); + + void GenerateKeyPair(CUnifiedKeyStore& aUnifiedKeyStore, + TInt aUsedKeyStore, + const TUint aKeySize, + TPKIKeyAlgorithm aKeyAlgorithm, + TPKIKeyIdentifier& aKeyId, + TRequestStatus& aClientStatus); + + void ImportKeyPair(CUnifiedKeyStore& aUnifiedKeyStore, + TInt aUsedKeyStore, + const TDesC8& aKeyData, + TPKIKeyIdentifier& aKeyId, + TRequestStatus& aClientStatus); + + void ExportPublicKey(CUnifiedKeyStore& aUnifiedKeyStore, + TInt aUsedKeyStore, + const TPKIKeyIdentifier& aKeyId, + HBufC8*& aPublicKeyData, + TRequestStatus& aClientStatus); + + +protected: + + void RunL(); + void DoCancel(); + void RunError(); + +private: + enum TKeyManagerState + { + EKeyManagerIdle = 0, + ERetrievingKeyPairForRemove, + ERemovingKeyPair, + EGeneratingKeyPair, + EImportingKeyPair, + ESettingManagementPolicy, + ESettingUsePolicy, + ERetrievingKeyListForExport, + EExportingPublicKey + }; + + CKeyManager(CLogonServices& aLogonServices); + void ConstructL(); + void Cleanup(); + + TInt GetKeyIndex(TInt aUsedKeyStore, const RMPointerArray& aKeysList) const; + + HBufC* GetUniqueNameL() const; + CCTKeyInfo::EKeyAlgorithm ConvertPKIAlgorithm(TPKIKeyAlgorithm aAlg) const; + + CLogonServices& iLogonServices; + TKeyManagerState iState; + + TRequestStatus* iClientStatus; + CUnifiedKeyStore* iUnifiedKeyStore; //Not owned by this class + RMPointerArray iKeysList; + + TInt iUsedKeyStore; + + HBufC* iObjectName; + HBufC8** iPublicKeyData; //Now owned by this class + TPKIKeyIdentifier* iKeyId; //Not owned by this class + CCTKeyInfo* iKeyInfo; //Not owned by this class + }; + +#endif //C_KEYMANAGER_H \ No newline at end of file diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/inc/keyoperationprovider.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/inc/keyoperationprovider.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,151 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: PKI server main module +* +*/ + + + + +#ifndef C_KEYOPERATIONPROVIDER_H +#define C_KEYOPERATIONPROVIDER_H + +#include +#include +#include +#include "pkidefs.h" + +class CUnifiedKeyStore; +class CPKISession; +class CPkiServiceSigner; +class CPkiServiceDecryptor; +class CLogonServices; +class CKeyManager; +class CKeyOperationQueue; + +/** +* A class that collects all the keyoperation functionality. +* +* The instance of this class is owned by CKeyOperationQueue, which +* calls the methods according to the client request. When an operation +* is completed the CKeyPairOperationProvider calls the associated callback +* from CKeyOperationQueue. +* +* The Initialize operation must be completed succesfully, before any other +* requests can be made to this class. +* +* Any current time, there can be only one request under process. +*/ +class CKeyPairOperationProvider : public CActive + { +public: + static CKeyPairOperationProvider* NewL(CKeyOperationQueue& aKeyOperationQueue); + ~CKeyPairOperationProvider(); + + /** + * Initializes the keystore. + * This is an asynchronous method. + * CPKISession::KeyStoreInitComplete is called when this + * request is completed. + */ + void Initialize(); + void GetKeyPairList(const TPKIKeyIdentifier& aKeyId, TInt aUsedKeyStore); + + /** + * Decrypts the data using key specified in aKeyId. + * The key has to be stored in the store defined by + * method SetKeyStore. + */ + void Decrypt(const TPKIKeyIdentifier& aKeyId, + TInt aUsedKeyStore, + HBufC8* aEncryptedData, + TInt aOutputLength); + + void Sign(const TPKIKeyIdentifier& aKeyId, + TInt aUsedKeyStore, + HBufC8* aDataToBeSigned); + + void GetPublicKey(const TPKIKeyIdentifier& aKeyId, TInt aUsedKeyStore); + + void Logon(); + void Logoff(); + void ChangePassword(); + + void RemoveKeyPair(const TPKIKeyIdentifier& aKeyId, TInt aUsedKeyStore); + void GenerateKeyPair(const TUint aKeySize, TPKIKeyAlgorithm aKeyAlgorithm, TInt aUsedKeyStore); + + void ImportKeyPair(HBufC8* aKeyData, TInt aUsedKeyStore); //Takes the ownership of the data + +protected: + void RunL(); + void DoCancel(); + TInt RunError(TInt aError); + +private: + enum TKeyOperation + { + EKeyOperationIdle = 0, + EKeyOperationInitialize, + EKeyOperationSetPassPhraseTimeout, + EKeyOperationGetKeyList, + EKeyOperationGetKeyDetails, + EKeyOperationDecrypting, + EKeyOperationSigning, + EKeyOperationPublicKeyExport, + EKeyOperationLogon, + EKeyOperationLogoff, + EKeyOperationLogonForChangePassword, + EKeyOperationChangingPassword, + EKeyOperationRemoveKeyPair, + EKeyOperationGeneratingKeyPair, + EKeyOperationImportingKeyPair + }; + + CKeyPairOperationProvider(CKeyOperationQueue& aKeyOperationQueue); + void ConstructL(); + + + void DecryptL(const TPKIKeyIdentifier& aKeyId, + TInt aUsedKeyStore, + HBufC8* aEncryptedData, + TInt aOutputLength); + + void CleanupCryptoOperation(); + + CArrayFixFlat* MakeKeyEntryListL(RMPointerArray aKeysList, + TInt aUsedKeyStore) const; + + TBool iIsInitialized; + TKeyOperation iKeyOperation; + + CKeyOperationQueue& iKeyOperationQueue; + RFs iFileServer; + CUnifiedKeyStore* iUnifiedKeyStore; + TInt iUsedKeyStore; //Not owned by this instance. + + RMPointerArray iKeysList; + + HBufC8* iInputData; //Used by Decrypt and Sign operations. + HBufC8* iOutputData; //Used by Decrypt and Sign operations. + TPtr8 iOutputDataPtr; + + TPKIKeyIdentifier iKeyId; //Used by store and generate keypair + + CPkiServiceDecryptor* iPkiDecryptor; + CPkiServiceSigner* iPkiSigner; + CLogonServices* iLogonService; + CKeyManager* iKeyManager; + }; + +#endif // C_KEYOPERATIONPROVIDER_H diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/inc/keyoperationqueue.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/inc/keyoperationqueue.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,124 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: A task que to serialize the key operations among session. +* +*/ + + + +#ifndef C_KEYOPERATIONQUEUE_H +#define C_KEYOPERATIONQUEUE_H + +#include + +#include "pkidefs.h" + +class CPKISession; +class CKeyPairOperationProvider; +class CPKIMapper; + + +/** + * A queueing class for keypair operations. + * + * This class queues the keypairoperations issued by client sessions. + * The keyoperations are queued, because only one session handle to + * CUnifiedKeystore can be open in this process and the CUnifiedKeystore + * can't handle concurrent asynchronous operations simultaniously. Only one + * session handle can be open to CUnifiedKeystore, because of the required + * Login/Logoff functionality. + * + * Server side session add the operations to que by calling AddOperationL. + * The operations are handled one at the time. When the operation is completed, the + * key operation queue signals the associated RMessage. + * + * Rest of the operations are call backs, which are used to signal, that the current + * operation is completed. + * + */ +class CKeyOperationQueue : public CBase + { +public: + static CKeyOperationQueue* NewL(CPKIMapper& aMapper); + ~CKeyOperationQueue(); + + void AddOperationL(CPKISession& aOwner, + const RMessage2& aMessage, + TInt aUsedKeyStore, + TPkiServiceStoreType aUsedCertStore); + + + void KeyStoreInitComplete(TInt aStatus); + + /** + * Transfers the ownership of aKeyList. + */ + void KeyPairListComplete(TInt aStatus, CArrayFixFlat* aKeyList); + + /** + * Transfers the ownership of aDecryptedData. + */ + void DecryptComplete(TInt aStatus, HBufC8* aDecryptedData); + + /** + * Transfers the ownership of aSignedData. + */ + void SignComplete(TInt aStatus, HBufC8* aSignedData); + + /** + * Transfers the ownership of aPublicKeyData. + */ + void GetPublicKeyCompleted(TInt aStatus, HBufC8* aPublicKeyData); + + void LogonCompleted(TInt aStatus); + void LogoffCompleted(TInt aStatus); + void PasswordChangeCompleted(TInt aStatus); + void KeyPairRemoveCompleted(TInt aStatus); + void KeyGenerationCompleted(TInt aStatus, TPKIKeyIdentifier& aKeyId); + void StoreKeyPairCompleted(TInt aStatus, TPKIKeyIdentifier& aKeyId); + + +private: + + class TKeyOperation + { + public: + TKeyOperation(CPKISession& aOwner, + const RMessage2& aMessage, + TInt aUsedKeyStore, + TPkiServiceStoreType aUsedCertStore); + + CPKISession& iOwner; + const RMessage2 iMessage; + TInt iUsedKeyStore; + TPkiServiceStoreType iUsedCertStore; + }; + + + CKeyOperationQueue(CPKIMapper& aMapper); + void ConstructL(); + + void StartNextOperation(); + void ServiceL(TKeyOperation& aOperation); + + void CompleteCurrentOperation(TInt aStatus); + + CPKIMapper& iMapper; + RPointerArray iOperationQue; + TKeyOperation* iCurrentOperation; + + CKeyPairOperationProvider* iKeyOperationProvider; + }; + +#endif //C_KEYOPERATIONQUEUE_H diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/inc/log_r6.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/inc/log_r6.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Logging utility. +* +*/ + + + +#if !defined(__LOG_R6_H__) +#define __LOG_R6_H__ + +_LIT(KLogFile,"pkiservice.txt"); + +#include "logcommon.h" + +#endif // __LOG_R6_H__ diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/inc/logonservices.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/inc/logonservices.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,72 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: A class that provides logon and logoff functionality. +* +*/ + + + +#ifndef C_LOGONSERVICES_H +#define C_LOGONSERVICES_H + +#include + +class CUnifiedKeyStore; + +class CLogonServices : public CActive + { +public: + static CLogonServices* NewL(CUnifiedKeyStore& aUnifiedKeyStore); + ~CLogonServices(); + + + void Logon(TRequestStatus& aClientStatus); + void Logoff(TRequestStatus& aClientStatus); + void ChangePassword(TRequestStatus& aClientStatus); + + //Used by explicit login + void SetAuthenticationObject(MCTAuthenticationObject* aAuthenticationObject); + + TBool LogonCompleted() const; + + void RunL(); + void DoCancel(); + +private: + enum TLogonServiceState + { + ELogonServiceIdle = 0, + ELogonServiceAlreadyLoggedIn, + ELogonServiceListingKeys, + ELogonServiceOpeningAuthentication, + ELogonServiceClosingAuthentication, + ELogonServiceChangingPassword + }; + + CLogonServices(CUnifiedKeyStore& aUnifiedKeyStore); + void ConstructL(); + + void Cleanup(); + + CUnifiedKeyStore& iUnifiedKeyStore; + TRequestStatus* iClientStatus; + TLogonServiceState iState; + + MCTKeyStoreManager* iUserKeyStore; //Not owned by this class + RMPointerArray iKeysList; + MCTAuthenticationObject* iAuthenticationObject; + }; + +#endif //C_LOGONSERVICES_H + diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/inc/pkiservice.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/inc/pkiservice.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2006-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: PKI server main module +* +*/ + + + +#ifndef __PKISERVICE_H__ +#define __PKISERVICE_H__ + +#include + +class CPKIMapper; +class CSuspendedShutdown; +class CCertificateRequestStore; +class CKeyOperationQueue; + +class CPKIService:public CPolicyServer +{ + public: + static CPKIService* NewL(void); + virtual ~CPKIService(void); + + CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const; + void SessionDeleted(); + + CCertificateRequestStore& CertificateRequestStore(); + + private: + CPKIService(); + void ConstructL(); + + static const TUint iRangeCount; + static const TInt iRanges[]; + static const TUint8 iElementIndex[]; + + static const CPolicyServer::TPolicyElement iElements[]; + static const CPolicyServer::TPolicy iPolicy; + + mutable TInt iSessionCount; + + CCertificateRequestStore *iCertificateRequestStore; + CSuspendedShutdown *iShutdown; + TBool iStopImmediately; + CPKIMapper *iMapper; + CKeyOperationQueue *iKeyOperationQueue; +}; + +class CSuspendedShutdown : public CActive +{ + public: + CSuspendedShutdown(); + void Construct(); + ~CSuspendedShutdown(); + void ArmShutdown(); + private: + void DoCancel(); + void RunL(); + private: + RTimer iTimer; +}; + + +#endif diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/inc/pkiserviceassert.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/inc/pkiserviceassert.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: a special assert macros used in pkiservice. +* +*/ + + + +#ifndef PKISERVICEASSERT_H +#define PKISERVICEASSERT_H + +#include "log_r6.h" + +#if defined(_DEBUG) + +#define PKISERVICE_ASSERT(cond) if(!(cond)){ LOG_("ASSERTION FAILED"); LOG8_1("%s, ", __FILE__); LOG8_1("%d", __LINE__); User::Invariant();} +#define PKISERVICE_INVARIANT() LOG_("ASSERTION FAILED"); LOG8_1("%s, ", __FILE__); LOG8_1("%d", __LINE__); User::Invariant() + +#else + +#define PKISERVICE_ASSERT(cond) +#define PKISERVICE_INVARIANT() + +#endif + + +#endif //PKISERVICEASSERT_H \ No newline at end of file diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/inc/pkiserviceclientservercommon.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/inc/pkiserviceclientservercommon.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,311 @@ +/* +* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Collects data type used by both client and server. +* +*/ + + + + +#ifndef PKI_SERVICE_CLIENT_SERVER_COMMON_H +#define PKI_SERVICE_CLIENT_SERVER_COMMON_H + +#include "pkidefs.h" + +static const TUid KPkiServiceUid3 = {0x101FAE07}; +_LIT(KPkiServerName,"!PKIserver"); +_LIT(KPkiServerImg,"pkiservice"); + + +const TInt KPkiMajorVersion = 1; +const TInt KPkiMinorVersion = 0; +const TInt KPkiBuildVersion = 0; + + +const TInt KMyServerInitHeapSize=0x1000; // 4KB +const TInt KMyServerMaxHeapSize=0x1000000; // 16MB +const TInt KMyServerStackSize=0x2000; // 8KB + +namespace PkiService + { + enum TPkiServiceCommands + { + ELogon, // 0 + EChangePassword, // 1 + ESignWithKeyId, // 2 + ESignWithCert, // 3 + EDecrypt, // 4 + EStoreKeypair, // 5 + EGenerateKeypair, // 6 + ECancelPendingOperation, // 7 + EGetRequiredBufferSize, // 8 + EReadPublicKey, // 9 + EReadCertificate, // 10 + EStoreCertificate, // 11 + EAttachCertificate, // 12 + ERemoveKeypair, // 13 + ERemoveCertificate, // 14 + ECertCount, // 15 + EInitialize, // 16 + ESaveCertificateRequest, // 17 + EReadCertificateRequest, // 18 + EDeleteCertificateRequest, // 19 + ESetTrust, // 20 + ETrusted, // 21 + EKeyCount, // 22 + EGetKeyList, // 23 + EGetCertList, // 24 + ESetApplicability, // 25 + EApplications, // 26 + EGetCertDetails, // 27 + ELogoff, // 28 + ECertReqCount, // 29 + EGetCertReqList, // 30 + EGetKeyDetails, // 31 + EApplicableCertCount, // 32 + EGetApplicableCertList, // 33 + ESetCertStoreType, // 34 + ESetKeyStoreType, // 35 + ESetStoreType, // 36 + EGetCertStoreType, // 37 + EGetKeyStoreType, // 38 + ESetInformational // 39 + }; + } + + + +const TInt KKeyUsageNotUsed = 0x5A5A5A5A; + +/** +* Internal class. Not used by the API +*/ + +class TSecurityObjectDescriptor +{ + public: + TSecurityObjectDescriptor() + :iTrustedAuthority(), + iTrustedAuthorityUsed(EFalse), + iIdentitySubjectName(), + iIdentitySubjectNameUsed(EFalse), + iIdentityRfc822Name(), + iIdentityRfc822NameUsed(EFalse), + iSerialNumber(), + iSerialNumberUsed(EFalse), + iSubjectKeyId(), + iSubjectKeyIdUsed(EFalse), + iOwnerType(EPKICACertificate), + iOwnerTypeUsed(EFalse), + iKeyUsage( (TPKIKeyUsage) 0), + iKeyUsageDer(), + iKeyUsageUsed(EFalse), + iKeySize(0), + iKeySizeUsed(EFalse), + iKeyAlgorithm(EPKIInvalidAlgorithm), + iKeyAlgorithmUsed(EFalse), + iObjectSize(EFalse), + iEncrypted(EFalse), + iObjectName(), + iObjectNameUsed(EFalse), + iIsDeletable(EFalse), + iIsDeletableUsed(EFalse) + {}; + + void SetSubjectKeyId(const TPKIKeyIdentifier &aKeyId) + { + if(aKeyId.Length() > 0) + { + iSubjectKeyId.Copy(aKeyId); + iSubjectKeyIdUsed = ETrue; + } + else + { + iSubjectKeyIdUsed = EFalse; + } + }; + void SetOwnerType(const TPKICertificateOwnerType aOwnerType) + { + iOwnerType = aOwnerType; + iOwnerTypeUsed = ETrue; + }; + void SetKeyUsage(const TPKIKeyUsage aKeyUsage) // Optional if only certificate is needed + { + if((TInt)aKeyUsage != KKeyUsageNotUsed) + { + iKeyUsage = aKeyUsage; + iKeyUsageUsed = ETrue; + } + else + { + iKeyUsage = (TPKIKeyUsage)0; + iKeyUsageUsed = EFalse; + } + }; + // Key usage is not defined in the filter, this will be checked separately + void SetKeySize(const TUint aKeySize) + { + if(aKeySize != 0) + { + iKeySize = aKeySize; + iKeySizeUsed = ETrue; + } + else + { + iKeySizeUsed = EFalse; + } + }; // Optional if only certificate is needed + void SetObjectName(const TDesC &aObjectName) + { + if(aObjectName.Length() > 0) + { + iObjectName.Copy(aObjectName); + iObjectNameUsed = ETrue; + } + else + { + iObjectNameUsed = EFalse; + } + }; + // Issuer and serial are not defined in the filter, these will be checked separately + void SetTrustedAuthority(const TDesC8 &aTrustedAuthority) + { + if(aTrustedAuthority.Length() > 0) + { + iTrustedAuthority.Copy(aTrustedAuthority); + iTrustedAuthorityUsed = ETrue; + } + else + { + iTrustedAuthorityUsed = EFalse; + } + }; + void SetIdentitySubjectName(const TDesC8 &aIdentitySubjectName) + { + if(aIdentitySubjectName.Length() > 0) + { + iIdentitySubjectName.Copy(aIdentitySubjectName); + iIdentitySubjectNameUsed = ETrue; + } + else + { + iIdentitySubjectNameUsed = EFalse; + } + }; + void SetIdentityRfc822Name(const TDesC8 &aIdentityRfc822Name) + { + if(aIdentityRfc822Name.Length() > 0) + { + iIdentityRfc822Name.Copy(aIdentityRfc822Name); + iIdentityRfc822NameUsed = ETrue; + } + else + { + iIdentityRfc822NameUsed = EFalse; + } + }; + void SetSerialNumber(const TDesC8 &aSerialNumber) + { + if(aSerialNumber.Length() > 0) + { + iSerialNumber.Copy(aSerialNumber); + iSerialNumberUsed = ETrue; + } + else + { + iSerialNumberUsed = EFalse; + } + }; + void SetKeyAlgorithm(const TPKIKeyAlgorithm &aKeyAlgorithm) + { + iKeyAlgorithm = aKeyAlgorithm; + iKeyAlgorithmUsed = ETrue; + }; + void SetIsDeletable(const TUint &aIsDeletable) + { + iIsDeletable = aIsDeletable; + iIsDeletableUsed = ETrue; + }; + void Reset() + { + iObjectNameUsed = EFalse; + iTrustedAuthorityUsed = EFalse; + iIdentitySubjectNameUsed = EFalse; + iIdentityRfc822NameUsed = EFalse; + iSubjectKeyIdUsed = EFalse; + iOwnerTypeUsed = EFalse; + iKeyUsageUsed = EFalse; + iKeySizeUsed = EFalse; + iKeyAlgorithmUsed = EFalse; + }; + TSecurityObjectDescriptor& operator=(const TSecurityObjectDescriptor& aDesc) + { + if (this != &aDesc) + { + this->iObjectName = aDesc.iObjectName; + this->iObjectNameUsed = aDesc.iObjectNameUsed; + this->iTrustedAuthority = aDesc.iTrustedAuthority; + this->iTrustedAuthorityUsed = aDesc.iTrustedAuthorityUsed; + this->iIdentitySubjectName = aDesc.iIdentitySubjectName; + this->iIdentitySubjectNameUsed = aDesc.iIdentitySubjectNameUsed; + this->iIdentityRfc822Name = aDesc.iIdentityRfc822Name; + this->iIdentityRfc822NameUsed = aDesc.iIdentityRfc822NameUsed; + this->iSerialNumber = aDesc.iSerialNumber; + this->iSerialNumberUsed = aDesc.iSerialNumberUsed; + this->iSubjectKeyId = aDesc.iSubjectKeyId; + this->iSubjectKeyIdUsed = aDesc.iSubjectKeyIdUsed; + this->iOwnerType = aDesc.iOwnerType; + this->iOwnerTypeUsed = aDesc.iOwnerTypeUsed; + this->iKeyUsage = aDesc.iKeyUsage; + this->iKeyUsageDer = aDesc.iKeyUsageDer; + this->iKeyUsageUsed = aDesc.iKeyUsageUsed; + this->iKeySize = aDesc.iKeySize; + this->iKeySizeUsed = aDesc.iKeySizeUsed; + this->iKeyAlgorithm = aDesc.iKeyAlgorithm; + this->iKeyAlgorithmUsed = aDesc.iKeyAlgorithmUsed; + this->iIsDeletable = aDesc.iIsDeletable; + this->iIsDeletableUsed = aDesc.iIsDeletableUsed; + } + return *this; + }; + + // No get methods introduced, values are used directly! + TBuf8 iTrustedAuthority; // Cert TrustedAuthority + TBool iTrustedAuthorityUsed; + TBuf8 iIdentitySubjectName; // Identity subject name + TBool iIdentitySubjectNameUsed; + TBuf8 iIdentityRfc822Name; // Identity subjectAltName rfc822 name + TBool iIdentityRfc822NameUsed; + TBuf8 iSerialNumber; // Serialnumber + TBool iSerialNumberUsed; + TPKIKeyIdentifier iSubjectKeyId; // SHA1 hash of the corresponding private key + TBool iSubjectKeyIdUsed; + TPKICertificateOwnerType iOwnerType; // User, CA or peer. If user certificate, at least key usage must be set + TBool iOwnerTypeUsed; + TPKIKeyUsage iKeyUsage; // Key usage flags + TBuf8 iKeyUsageDer; // Der format flags + TBool iKeyUsageUsed; + TUint iKeySize; // Key size + TBool iKeySizeUsed; + TPKIKeyAlgorithm iKeyAlgorithm; // RSA, DSA + TBool iKeyAlgorithmUsed; + TBool iObjectSize; // Byte size of the referenced security object + TBool iEncrypted; // Only used for passing aEncrypted parameter from client to server + TBuf iObjectName; + TBool iObjectNameUsed; + TBool iIsDeletable; // + TBool iIsDeletableUsed; +}; + +#endif // PKI_SERVICE_CLIENT_SERVER_COMMON_H diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/inc/pkiserviceconstants.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/inc/pkiserviceconstants.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Constants used in PKIService module +* +*/ + + + +#ifndef PKISERVICECONSTANTS_H +#define PKISERVICECONSTANTS_H + +const TInt STORETYPE_DEVICE_CERT_ID = 0x101FB668; +const TInt STORETYPE_DEVICE_KEY_ID = 0x101FB66A; +const TInt STORETYPE_USER_CERT_ID = 0x101F501A; +const TInt STORETYPE_USER_KEY_ID = 0x101F7333; + +const TInt STORETYPE_ANY_KEY_ID = 0x0; //Not a real uid. Just used internally + +// Constants for cert store types +_LIT(KUserCertStore, "Software certificate store"); +_LIT(KDeviceCertStore, "device certstore"); + + + +#endif //PKISERVICECONSTANTS_H + diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/inc/pkiservicedecryptor.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/inc/pkiservicedecryptor.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: A class that provides a decrypt operation. +* +*/ + + + +#ifndef C_PKISERVICEDECRYPTOR_H +#define C_PKISERVICEDECRYPTOR_H + +#include +#include + +#include "pkidefs.h" + +class MCTKeyStoreManager; +class CLogonServices; + + +/** + * A class that decrypts data using a private key. + * + * This class handles the decryption of a data, which is + * encrypted by using a public key from a stored keypair. + */ +class CPkiServiceDecryptor : public CActive + { +public: + static CPkiServiceDecryptor* NewL(CLogonServices& aLogonServices); + ~CPkiServiceDecryptor(); + + void Decrypt(const TPKIKeyIdentifier& aKeyId, + const TDesC8& aEncryptedData, + TPtr8& aPlainTextData, + CUnifiedKeyStore& aUnifiedKeyStore, + TInt aUsedKeyStore, + TRequestStatus& aClientstatus); + + + void RunL(); + void DoCancel(); + +private: + enum TDecryptorState + { + EDecryptorIdle = 0, + EDecryptorGettingKey, + EDecryptorOpeningDecryptor, + EDecryptorDecrypting + }; + + CPkiServiceDecryptor(CLogonServices& aLogonServices); + void Cleanup(); + + CLogonServices& iLogonServices; + TDecryptorState iState; + CUnifiedKeyStore* iKeyStore; //Not owned by this class + TInt iUsedKeyStore; + const TDesC8* iInput; //Not owned by this class + TPtr8* iPlainText;//Not owned by this class + TRequestStatus* iClientStatus; + + MCTDecryptor* iDecryptor; + RMPointerArray iKeysList; + + CCTKeyInfo* iKeyInfo; + }; + +#endif //C_PKISERVICEDECRYPTOR_H diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/inc/pkiservicesigner.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/inc/pkiservicesigner.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: A class that provides a signing operation. +* +*/ + + + +#ifndef C_PKISERVICESIGNER_H +#define C_PKISERVICESIGNER_H + +#include + +#include "pkidefs.h" + +class MCTKeyStoreManager; +class CLogonServices; + +/** + * This class signs a given data by using a stored private key. + */ +class CPkiServiceSigner : public CActive + { +public: + static CPkiServiceSigner* NewL(CLogonServices& aLogonServices); + ~CPkiServiceSigner(); + + void Sign(const TPKIKeyIdentifier& aKeyId, + const TDesC8& aDataToBeSigned, + HBufC8*& aSignature, + CUnifiedKeyStore& aUnifiedKeyStore, + TInt aUsedKeyStore, + TRequestStatus& aStatus); + + + void DoCancel(); + void RunL(); + +private: + enum TSignerState + { + ESignerIdle = 0, + ESignerGettingKey, + ESignerOpeningSigner, + ESignerSigning + }; + + CPkiServiceSigner(CLogonServices& aLogonServices); + void Cleanup(); + + CLogonServices& iLogonServices; + + TSignerState iState; + TRequestStatus* iClientStatus; + CUnifiedKeyStore* iKeyStore; //Not owned by this class + TInt iUsedKeyStore; + TPtrC8 iInput; //Not owned by this class + HBufC8** iOutputBuffer;//Not owned by this class + + const CCTKeyInfo* iUsedKeyInfo; + + MRSASigner* iRsaSigner; + MDSASigner* iDsaSigner; + + CRSASignature* iRsaSignature; + CDSASignature* iDsaSignature; + + RMPointerArray iKeysList; + }; + +#endif //C_PKISERVICESIGNER_H + + diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/inc/pkisession.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/inc/pkisession.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2003-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* A server side session object. Owns instances of the CPKIService and +* CPKIWrapper classes. All requests to the service objects go through +* this object. +* +*/ + + + +#ifndef __PKISESSION__ +#define __PKISESSION__ + +#include +#include +#include "pkidefs.h" +#include "keyoperationprovider.h" + +class CPKIWrapper; +class CPKIService; +class CPKIMapper; +class CKeyOperationQueue; + +class CPKISession: public CSession2//, public MKeyOperationObserver + +{ + public: + static CPKISession* NewL(CPKIService& aServer, + CPKIMapper& aMapper, + CKeyOperationQueue& aKeyOperationQueue); + virtual ~CPKISession(void); + + void ServiceL(const RMessage2& aMessage); + + void SetRequiredBufferSize(TInt aSize); + void SetKeyList(CArrayFixFlat *aKeyList); + void InitializeWrapperL(const RMessage2& aMessage); + + +private: + CPKISession(CPKIService& aServer, CPKIMapper& aMapper, CKeyOperationQueue& aKeyOperationQueue); + void ConstructL(); + //void InitializeL(const RMessage2& aMessage); + + /** + * Set the used key store. + */ + void SetKeyStoreL(TPkiServiceStoreType aStoreType); + TPkiServiceStoreType KeyStore() const; + + CPKIService &iServer; + CPKIMapper &iMapper; + CKeyOperationQueue &iKeyOperationQueue; + + CPKIWrapper *iWrapper; + RArray iUidArray; + TInt iApplCount; + + TInt iUsedKeyStore; + CArrayFixFlat *iKeyList; + TInt iRequiredBufferSize; +}; + +#endif \ No newline at end of file diff -r 000000000000 -r 33413c0669b9 vpnengine/pkiservice/inc/pkisupport.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/inc/pkisupport.h Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,226 @@ +/* +* Copyright (c) 2003-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: CPKISupport class implements the PKI interface for Symbian +* PKI storage. +* +*/ + + + +#ifndef __PKISUPPORT_H__ +#define __PKISUPPORT_H__ + +#include +#include "pkidefs.h" +#include "eventmediatorapi.h" // for logging + +class CPKIWrapper; +class CMapDescriptor; +class TSecurityObjectDescriptor; +class CUnifiedCertStore; +class MCTWritableCertStore; +class CCTCertInfo; +class CCertAttributeFilter; + +enum TSubState +{ + ESSComplete, + ESSContinue, + ESSCompleteRequest, +}; + +enum TInitPhaseState +{ + EInitDone = 0, + EInitContinueInitialize, + EInitInitializeCertStore, + EInitRetrieveCertList, + EInitCompleteImportCerts, +}; + +enum TPending +{ + ENoPendingOperation, + EInitializeCertStore, + EListCerts, + EListDevCerts, + ECertAdd, + ECertRetrieve, + ECertRemove, + ESetTrust, + ETrusted, + ESetApplicability, + EApplications, + EIsApplicable, +}; + + +/** + * Implements PKI support. + * + * @lib (internal) pkiservice.exe + * @since S60 v3.0 + */ +class CPKISupport : public CActive +{ + public: + + // Constructors, destructor + static CPKISupport* NewL( + CPKIMapper& aMapper, CPKIWrapper& aWrapper); + static CPKISupport* NewLC( + CPKIMapper& aMapper, CPKIWrapper& aWrapper); + + + ~CPKISupport(); + + void StartInitializeL(const RMessage2& aMessage); + void SetCurrentFunction(TInt aFunc); + + // Certificate Data manipulation + void StoreCertificateL(const TDesC &aLabel, + TCertificateOwnerType aOwnerType, const TDesC8 &aBufferPtr, + const TBool& aIsDeletable, TRequestStatus& aStatus); + + void AttachCertificateL(const TDesC &aLabel, + const TPKIKeyIdentifier &aKeyId, + const TDesC8 &aBufferPtr, TRequestStatus& aStatus); + + void RetrieveCertificateL(const TDesC &aLabel, + TPtr8 &aBufferPtr, const TPKICertificateOwnerType& aType, + TRequestStatus& aStatus); + + void RemoveCertificateL(const TDesC &aLabel, + TRequestStatus& aStatus); + + void SelectCertificateL(const TDesC &aLabel, + const TPKICertificateOwnerType& aType = EPKICACertificate); + + // Asynchronous sertificate store request + void GetCertificateStoreListAsync(); + + // Helper methods + TInt GetRequiredBufferSize(); + void SetCallerStatusPending(TRequestStatus& aStatus); + void CompleteCallerStatus(TInt aError); + void SetTrustL( + const TDesC &aLabel, TBool aTrusted, TRequestStatus& aStatus); + void TrustedL(const TDesC &aLabel, TRequestStatus& aStatus); + void SetApplicabilityL( + const TDesC &aLabel, const RArray& aApplUids, + TRequestStatus& Status); + void ApplicationsL(const TDesC &aLabel, TRequestStatus& Status); + + inline void SetCertStoreType(TPkiServiceStoreType aStoreType) + { + iCertStoreType = aStoreType; + }; + + inline const TPkiServiceStoreType CertStoreType() const + { + return iCertStoreType; + }; + + private: // implementation + CPKISupport(CPKIMapper& aMapper, CPKIWrapper& aWrapper); + void ConstructL(); + + void CancelCurrentOperation(); + CCTKeyInfo::EKeyAlgorithm ConvertPKIAlgorithm(TPKIKeyAlgorithm aAlg); + TPKIKeyAlgorithm ConvertSymbianAlgorithm(CCTKeyInfo::EKeyAlgorithm aAlg); + void FindInterfacesL(); + void ListAllCertificatesL(); + void ReadNextCertForImportL(); + void SaveCertInfoToCacheL(); + TBool GetApplicationsOfCTFCertL(); + + void ContinueStoreCertificateL(); + void ContinueRetrieveCertificate(); + void ContinueStoreCertifiedKeypairL(); + void ContinueRemoveCertificate(); + void ContinueSetTrust(); + void ContinueSetApplicability(); + void ContinueApplications(); + void ContinueTrusted(); + void DoRunOperationL(); + void DoRunLoggedInOperationL(); + + // Function to remove all MIDP2 certificates from the + // local listing (MIDP2 certs shouldn't be supported by VPN) + void CleanupCertListL(); + + // CActive methods + void RunL(); + void DoCancel(); + TInt RunError(TInt aError); + + /** + * Used for logging. + * Exctracts certificate info from the parameters + * and inserts result into iCertInfoForLogging. + * Result string looks like this: + * \nLabel: