bluetooth/btstack/common/btsap.cpp
changeset 0 29b1cd4cb562
child 48 22de2e391156
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // The base class for Bluetooth Saps
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <es_prot.h>
       
    19 #include "BtSap.h"
       
    20 #include "secman.h"
       
    21 #include "codman.h"
       
    22 
       
    23 #include "BTSec.h"
       
    24 
       
    25 //Diagnostic string for security check failures, in builds without platsec
       
    26 //diagnostics this will be NULL.
       
    27 const char* const KBT_SAP_NAME_DIAG = __PLATSEC_DIAGNOSTIC_STRING("Bluetooth SAP");
       
    28 
       
    29 CBluetoothSAP::CBluetoothSAP(CBTSecMan& aSecMan, CBTCodServiceMan& aCodMan)
       
    30 : iSecMan(aSecMan), iCodMan(aCodMan)
       
    31 	{
       
    32 	}
       
    33 
       
    34 void CBluetoothSAP::ConstructL()
       
    35 	{
       
    36 	TCallBack accessDenied(AccessDeniedCallBack, this);
       
    37 	iAccessDeniedCallBack = new(ELeave) CAsyncCallBack(accessDenied, CActive::EPriorityStandard);
       
    38 	}
       
    39 
       
    40 TInt CBluetoothSAP::SetDeviceOverride(const TDesC8& aOption)
       
    41 /**
       
    42 	Provides for overriding of the general *service* security
       
    43 	for given devices.
       
    44 
       
    45 **/
       
    46 	{
       
    47 	if (aOption.Length() != sizeof(TBTServiceSecurityPerDevice))
       
    48 		{
       
    49 		return KErrArgument;
       
    50 		}
       
    51 
       
    52 	TBTServiceSecurityPerDevice override =
       
    53 		*reinterpret_cast<const TBTServiceSecurityPerDevice*>(aOption.Ptr());
       
    54 
       
    55 	// add this device into the array of overrides for this SAP
       
    56 	// if device is in the list, replace the entry
       
    57 	for (TInt i=0; i<=iDeviceOverrides.Count()-1; i++)
       
    58 		{
       
    59 		if (iDeviceOverrides[i].DeviceAddress() == override.DeviceAddress())
       
    60 			{
       
    61 			// update!
       
    62 			iDeviceOverrides[i].SetDeviceSecurity(override.DeviceSecurity());
       
    63 			return KErrNone;
       
    64 			}
       
    65 		}
       
    66 	// if here, this is a new entry
       
    67 	return iDeviceOverrides.Append(override);
       
    68 	}
       
    69 	
       
    70 TInt CBluetoothSAP::GetDeviceOverride(TDes8& aOption) const
       
    71 /**
       
    72 	Allows forgetful apps to give us an address, and we'll tell
       
    73 	them the overrides for this service for that device.
       
    74 */
       
    75 	{
       
    76 	if (aOption.Length() != sizeof(TBTServiceSecurityPerDevice))
       
    77 		{
       
    78 		return KErrArgument;
       
    79 		}
       
    80 
       
    81 	TBTServiceSecurityPerDevice overrideBuf =
       
    82 		*reinterpret_cast<const TBTServiceSecurityPerDevice*>(aOption.Ptr());
       
    83 
       
    84 	const TBTServiceSecurityPerDevice* override = Override(overrideBuf.DeviceAddress());	
       
    85 	if (override)
       
    86 		{
       
    87 		overrideBuf.SetDeviceSecurity(override->DeviceSecurity());
       
    88 		aOption = TPtrC8(reinterpret_cast<TUint8*>(&overrideBuf), sizeof(TBTServiceSecurityPerDevice));
       
    89 		return KErrNone;
       
    90 		}
       
    91 	else
       
    92 		{
       
    93 		return KErrNotFound;
       
    94 		}
       
    95 	}
       
    96 	
       
    97 
       
    98 CBluetoothSAP::~CBluetoothSAP()
       
    99 	{
       
   100 	__ASSERT_DEBUG(!(iCodServiceBits & KBTCodBitsRegdFlag), User::Panic(KBTCodPanic, EBTCodBadDeregister));
       
   101 	iDeviceOverrides.Close();
       
   102 	delete iAccessDeniedCallBack;
       
   103 	}
       
   104 
       
   105 
       
   106 const TBTServiceSecurity& CBluetoothSAP::Security() const
       
   107 	{
       
   108 	return iSecurity;
       
   109 	}
       
   110 
       
   111 const TBTServiceSecurityPerDevice* CBluetoothSAP::Override(const TBTDevAddr& aAddress) const
       
   112 	{
       
   113 	//look through overrides for a device override
       
   114 	for (TInt i=0; i<iDeviceOverrides.Count(); i++)
       
   115 		{
       
   116 		if (iDeviceOverrides[i].DeviceAddress() == aAddress)
       
   117 			{
       
   118 			return &iDeviceOverrides[i];
       
   119 			}
       
   120 		}
       
   121 	return NULL;
       
   122 	}
       
   123 
       
   124 void CBluetoothSAP::IoctlComplete(TInt /*aErr*/, TUint /*aLevel*/, TUint /*aName*/, TDesC8* aBuf)
       
   125 	{
       
   126 	iSocket->IoctlComplete(aBuf);
       
   127 	}
       
   128 
       
   129 
       
   130 TInt CBluetoothSAP::SecurityCheck(MProvdSecurityChecker *aSecurityChecker)
       
   131 	{
       
   132 	__ASSERT_ALWAYS(aSecurityChecker, User::Panic(KSECURITY_PANIC, EBTPanicNullSecurityChecker));
       
   133 	
       
   134 	iSecurityChecker = aSecurityChecker;
       
   135 	return iSecurityChecker->CheckPolicy(KLOCAL_SERVICES, KBT_SAP_NAME_DIAG);
       
   136 	}
       
   137 
       
   138 void CBluetoothSAP::StartAccessRequest(const CBluetoothSAP& aSAPWithSecuritySettings, TBool aSecurityModeFourOutgoing)
       
   139 /**
       
   140 	Ask secman to do security
       
   141 	@param aSAPWithSecuritySettings contains the security details
       
   142 	@param aSecurityModeFourOutgoing indicates whether this is a security mode 4 request that comes before
       
   143 	a security mode 2 request.  This is to be used for establishing a suitable 
       
   144 
       
   145 	this SAP has the remote address connecting
       
   146 **/
       
   147 	{
       
   148 	const MAccessRequestResponseHandler& handler = *this;
       
   149 	
       
   150 	TBTServiceSecurity secReqs(aSAPWithSecuritySettings.Security());
       
   151 	if(aSecurityModeFourOutgoing)
       
   152 		{
       
   153 		// For security mode 4 requests we don't consider the authorisation and any pre-v2.1
       
   154 		// security settings.  Note this is only applicable for outgoing access requirements.
       
   155 		//So we set a concrete MITM protection value...
       
   156 		secReqs.SetAuthentication(secReqs.MitmProtection());
       
   157 		// ...then we remove any authorisation, authentication or encryption.
       
   158 		secReqs.SetAuthorisation(EFalse);
       
   159 		secReqs.SetAuthentication(EFalse);
       
   160 		secReqs.SetEncryption(EFalse);
       
   161 		}
       
   162 	// As a note, using the override as-is is infact safe as none of the override values 
       
   163 	// can really affect the security mode 4 aspects.
       
   164 
       
   165 	TRAPD(err, SecMan().AccessRequestL(secReqs,
       
   166 						aSAPWithSecuritySettings.Override(RemoteAddress()),
       
   167 						RemoteAddress(),
       
   168 						aSecurityModeFourOutgoing ? EGeneralBondingSecurityMode4Outgoing : EGeneralBonding, // We are doing general bonding
       
   169 						const_cast<MAccessRequestResponseHandler&>(handler)));
       
   170 
       
   171 	if (err != KErrNone)
       
   172 		{
       
   173 		// complete request now...
       
   174 		iAccessDeniedCallBack->CallBack();
       
   175 		}
       
   176 	}
       
   177 
       
   178 void CBluetoothSAP::CancelAccessRequest()
       
   179 	{
       
   180 	SecMan().CancelRequest(*this);
       
   181 	}
       
   182 
       
   183 void CBluetoothSAP::AccessRequestComplete(TInt /*aResult*/)
       
   184 /**
       
   185 	The SAP wasnt expecting security responses
       
   186 	Derivers normally would override (and forward to state)
       
   187 **/
       
   188 	{
       
   189 	_LIT(KBTSAPPanic, "BTSAP");
       
   190 	User::Panic(KBTSAPPanic, EBTSecUnexpectedSecurityResponse);
       
   191 	}
       
   192 
       
   193 /*static*/ TInt CBluetoothSAP::AccessDeniedCallBack(TAny* aBtSap)
       
   194 	{
       
   195 	CBluetoothSAP* btSap = static_cast<CBluetoothSAP*>(aBtSap);
       
   196 	btSap->AccessRequestComplete(EBTSecManAccessDenied);
       
   197 	return KErrNone;
       
   198 	}
       
   199 
       
   200 
       
   201 TInt CBluetoothSAP::SetCodServiceBits(TUint16 aNewCodServiceBits)
       
   202 /**
       
   203 	Allow SetOpts to set Service bits. These are written to the CoD
       
   204 	when the SAP becomes active.
       
   205 **/
       
   206 	{
       
   207 	TInt err = KErrNone;
       
   208 	if (aNewCodServiceBits & (~KBTCodValidServiceBits))
       
   209 		{
       
   210 		err = KErrArgument;		// SetOpt is attempting to set illegal bits
       
   211 		}
       
   212 	else
       
   213 		{
       
   214 		if (iCodServiceBits & KBTCodBitsRegdFlag)
       
   215 			{
       
   216 			err = KErrAlreadyExists; // This SAP has Service bits already registered
       
   217 			}
       
   218 		else
       
   219 			{
       
   220 			iCodServiceBits = aNewCodServiceBits; // These can be overwritten at this stage
       
   221 			}
       
   222 		}
       
   223 	return err;
       
   224 	}
       
   225 
       
   226 	
       
   227 void CBluetoothSAP::RegisterCodService()
       
   228 /**
       
   229 	Allows SAPs to register their Service(s)
       
   230 **/
       
   231 	{
       
   232 	if (iCodServiceBits && !(iCodServiceBits & KBTCodBitsRegdFlag))
       
   233 		{
       
   234 		// Only send to CodMan once
       
   235 		CodMan().RegisterCodService(iCodServiceBits);
       
   236 		}
       
   237 // Set the regd flag, even if no service bits, this will ensure that late SetOpts are errored
       
   238 	iCodServiceBits |= KBTCodBitsRegdFlag;
       
   239 	}
       
   240 
       
   241 
       
   242 void CBluetoothSAP::DeregisterCodService()
       
   243 /**
       
   244 	Allows SAPs to clear their Service bits
       
   245 **/
       
   246 	{
       
   247 	if (iCodServiceBits && (iCodServiceBits & KBTCodBitsRegdFlag))
       
   248 		{
       
   249 		iCodServiceBits &= (~KBTCodBitsRegdFlag);	// reset the registered flag, don't want to confuse CodMan
       
   250 		CodMan().RemoveCodService(iCodServiceBits);
       
   251 		}
       
   252 	iCodServiceBits = 0;	// tidy up these service bits + regd flag
       
   253 	}
       
   254 
       
   255 
       
   256 TInt CBluetoothSAP::SetOption(TUint aLevel,TUint aName,const TDesC8 &aOption)
       
   257 /**
       
   258 	This is now the default SetOpt handler for SAP protocols.
       
   259 	Common attributes are processed here and the protocol dependent SetOpts are passed on.
       
   260 **/
       
   261 	{
       
   262 	TInt rerr = KErrNone;
       
   263 	if(aLevel == KSolBtSAPBase)
       
   264 		{
       
   265 		switch (aName)
       
   266 			{
       
   267 			case KBTRegisterCodService:
       
   268 				{
       
   269 				if (aOption.Length() != sizeof(TDesC8))
       
   270 					return KErrArgument;
       
   271 				
       
   272 		        TUint16 newServiceBits = *reinterpret_cast<const TUint16*>(aOption.Ptr());
       
   273 				rerr = SetCodServiceBits(newServiceBits);	// The service bits are saved and then registered when SAP becomes live
       
   274 				}
       
   275 				break;	
       
   276 
       
   277 			default:
       
   278 				// Unhandled SetOpt name
       
   279 				rerr = KErrNotSupported;
       
   280 				break;
       
   281 			}
       
   282 		}
       
   283 	else
       
   284 		{
       
   285 		// Process SAP SetOpts
       
   286 		rerr = SAPSetOption(aLevel, aName, aOption);
       
   287 		}
       
   288 		
       
   289 	return rerr;
       
   290 	}