diff -r 000000000000 -r 29b1cd4cb562 bluetooth/btstack/common/btsap.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetooth/btstack/common/btsap.cpp Fri Jan 15 08:13:17 2010 +0200 @@ -0,0 +1,290 @@ +// 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: +// The base class for Bluetooth Saps +// +// + +#include +#include "BtSap.h" +#include "secman.h" +#include "codman.h" + +#include "BTSec.h" + +//Diagnostic string for security check failures, in builds without platsec +//diagnostics this will be NULL. +const char* const KBT_SAP_NAME_DIAG = __PLATSEC_DIAGNOSTIC_STRING("Bluetooth SAP"); + +CBluetoothSAP::CBluetoothSAP(CBTSecMan& aSecMan, CBTCodServiceMan& aCodMan) +: iSecMan(aSecMan), iCodMan(aCodMan) + { + } + +void CBluetoothSAP::ConstructL() + { + TCallBack accessDenied(AccessDeniedCallBack, this); + iAccessDeniedCallBack = new(ELeave) CAsyncCallBack(accessDenied, CActive::EPriorityStandard); + } + +TInt CBluetoothSAP::SetDeviceOverride(const TDesC8& aOption) +/** + Provides for overriding of the general *service* security + for given devices. + +**/ + { + if (aOption.Length() != sizeof(TBTServiceSecurityPerDevice)) + { + return KErrArgument; + } + + TBTServiceSecurityPerDevice override = + *reinterpret_cast(aOption.Ptr()); + + // add this device into the array of overrides for this SAP + // if device is in the list, replace the entry + for (TInt i=0; i<=iDeviceOverrides.Count()-1; i++) + { + if (iDeviceOverrides[i].DeviceAddress() == override.DeviceAddress()) + { + // update! + iDeviceOverrides[i].SetDeviceSecurity(override.DeviceSecurity()); + return KErrNone; + } + } + // if here, this is a new entry + return iDeviceOverrides.Append(override); + } + +TInt CBluetoothSAP::GetDeviceOverride(TDes8& aOption) const +/** + Allows forgetful apps to give us an address, and we'll tell + them the overrides for this service for that device. +*/ + { + if (aOption.Length() != sizeof(TBTServiceSecurityPerDevice)) + { + return KErrArgument; + } + + TBTServiceSecurityPerDevice overrideBuf = + *reinterpret_cast(aOption.Ptr()); + + const TBTServiceSecurityPerDevice* override = Override(overrideBuf.DeviceAddress()); + if (override) + { + overrideBuf.SetDeviceSecurity(override->DeviceSecurity()); + aOption = TPtrC8(reinterpret_cast(&overrideBuf), sizeof(TBTServiceSecurityPerDevice)); + return KErrNone; + } + else + { + return KErrNotFound; + } + } + + +CBluetoothSAP::~CBluetoothSAP() + { + __ASSERT_DEBUG(!(iCodServiceBits & KBTCodBitsRegdFlag), User::Panic(KBTCodPanic, EBTCodBadDeregister)); + iDeviceOverrides.Close(); + delete iAccessDeniedCallBack; + } + + +const TBTServiceSecurity& CBluetoothSAP::Security() const + { + return iSecurity; + } + +const TBTServiceSecurityPerDevice* CBluetoothSAP::Override(const TBTDevAddr& aAddress) const + { + //look through overrides for a device override + for (TInt i=0; iIoctlComplete(aBuf); + } + + +TInt CBluetoothSAP::SecurityCheck(MProvdSecurityChecker *aSecurityChecker) + { + __ASSERT_ALWAYS(aSecurityChecker, User::Panic(KSECURITY_PANIC, EBTPanicNullSecurityChecker)); + + iSecurityChecker = aSecurityChecker; + return iSecurityChecker->CheckPolicy(KLOCAL_SERVICES, KBT_SAP_NAME_DIAG); + } + +void CBluetoothSAP::StartAccessRequest(const CBluetoothSAP& aSAPWithSecuritySettings, TBool aSecurityModeFourOutgoing) +/** + Ask secman to do security + @param aSAPWithSecuritySettings contains the security details + @param aSecurityModeFourOutgoing indicates whether this is a security mode 4 request that comes before + a security mode 2 request. This is to be used for establishing a suitable + + this SAP has the remote address connecting +**/ + { + const MAccessRequestResponseHandler& handler = *this; + + TBTServiceSecurity secReqs(aSAPWithSecuritySettings.Security()); + if(aSecurityModeFourOutgoing) + { + // For security mode 4 requests we don't consider the authorisation and any pre-v2.1 + // security settings. Note this is only applicable for outgoing access requirements. + //So we set a concrete MITM protection value... + secReqs.SetAuthentication(secReqs.MitmProtection()); + // ...then we remove any authorisation, authentication or encryption. + secReqs.SetAuthorisation(EFalse); + secReqs.SetAuthentication(EFalse); + secReqs.SetEncryption(EFalse); + } + // As a note, using the override as-is is infact safe as none of the override values + // can really affect the security mode 4 aspects. + + TRAPD(err, SecMan().AccessRequestL(secReqs, + aSAPWithSecuritySettings.Override(RemoteAddress()), + RemoteAddress(), + aSecurityModeFourOutgoing ? EGeneralBondingSecurityMode4Outgoing : EGeneralBonding, // We are doing general bonding + const_cast(handler))); + + if (err != KErrNone) + { + // complete request now... + iAccessDeniedCallBack->CallBack(); + } + } + +void CBluetoothSAP::CancelAccessRequest() + { + SecMan().CancelRequest(*this); + } + +void CBluetoothSAP::AccessRequestComplete(TInt /*aResult*/) +/** + The SAP wasnt expecting security responses + Derivers normally would override (and forward to state) +**/ + { + _LIT(KBTSAPPanic, "BTSAP"); + User::Panic(KBTSAPPanic, EBTSecUnexpectedSecurityResponse); + } + +/*static*/ TInt CBluetoothSAP::AccessDeniedCallBack(TAny* aBtSap) + { + CBluetoothSAP* btSap = static_cast(aBtSap); + btSap->AccessRequestComplete(EBTSecManAccessDenied); + return KErrNone; + } + + +TInt CBluetoothSAP::SetCodServiceBits(TUint16 aNewCodServiceBits) +/** + Allow SetOpts to set Service bits. These are written to the CoD + when the SAP becomes active. +**/ + { + TInt err = KErrNone; + if (aNewCodServiceBits & (~KBTCodValidServiceBits)) + { + err = KErrArgument; // SetOpt is attempting to set illegal bits + } + else + { + if (iCodServiceBits & KBTCodBitsRegdFlag) + { + err = KErrAlreadyExists; // This SAP has Service bits already registered + } + else + { + iCodServiceBits = aNewCodServiceBits; // These can be overwritten at this stage + } + } + return err; + } + + +void CBluetoothSAP::RegisterCodService() +/** + Allows SAPs to register their Service(s) +**/ + { + if (iCodServiceBits && !(iCodServiceBits & KBTCodBitsRegdFlag)) + { + // Only send to CodMan once + CodMan().RegisterCodService(iCodServiceBits); + } +// Set the regd flag, even if no service bits, this will ensure that late SetOpts are errored + iCodServiceBits |= KBTCodBitsRegdFlag; + } + + +void CBluetoothSAP::DeregisterCodService() +/** + Allows SAPs to clear their Service bits +**/ + { + if (iCodServiceBits && (iCodServiceBits & KBTCodBitsRegdFlag)) + { + iCodServiceBits &= (~KBTCodBitsRegdFlag); // reset the registered flag, don't want to confuse CodMan + CodMan().RemoveCodService(iCodServiceBits); + } + iCodServiceBits = 0; // tidy up these service bits + regd flag + } + + +TInt CBluetoothSAP::SetOption(TUint aLevel,TUint aName,const TDesC8 &aOption) +/** + This is now the default SetOpt handler for SAP protocols. + Common attributes are processed here and the protocol dependent SetOpts are passed on. +**/ + { + TInt rerr = KErrNone; + if(aLevel == KSolBtSAPBase) + { + switch (aName) + { + case KBTRegisterCodService: + { + if (aOption.Length() != sizeof(TDesC8)) + return KErrArgument; + + TUint16 newServiceBits = *reinterpret_cast(aOption.Ptr()); + rerr = SetCodServiceBits(newServiceBits); // The service bits are saved and then registered when SAP becomes live + } + break; + + default: + // Unhandled SetOpt name + rerr = KErrNotSupported; + break; + } + } + else + { + // Process SAP SetOpts + rerr = SAPSetOption(aLevel, aName, aOption); + } + + return rerr; + }