--- /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 <es_prot.h>
+#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<const TBTServiceSecurityPerDevice*>(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<const TBTServiceSecurityPerDevice*>(aOption.Ptr());
+
+ const TBTServiceSecurityPerDevice* override = Override(overrideBuf.DeviceAddress());
+ if (override)
+ {
+ overrideBuf.SetDeviceSecurity(override->DeviceSecurity());
+ aOption = TPtrC8(reinterpret_cast<TUint8*>(&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; i<iDeviceOverrides.Count(); i++)
+ {
+ if (iDeviceOverrides[i].DeviceAddress() == aAddress)
+ {
+ return &iDeviceOverrides[i];
+ }
+ }
+ return NULL;
+ }
+
+void CBluetoothSAP::IoctlComplete(TInt /*aErr*/, TUint /*aLevel*/, TUint /*aName*/, TDesC8* aBuf)
+ {
+ iSocket->IoctlComplete(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<MAccessRequestResponseHandler&>(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<CBluetoothSAP*>(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<const TUint16*>(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;
+ }