1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/dbms/sdbms/Sd_DbProps2.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,315 @@
1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// RDbPropsFactory class - "DBMS Security" related - full security support
1.18 +//
1.19 +//
1.20 +
1.21 +#include <f32file.h>
1.22 +#include "D32DRVR.H"
1.23 +#include "U32STD.H"
1.24 +#include "D32Strings.h"
1.25 +#include "Sd_DbProps.h"
1.26 +#include "Sd_DbList.h"
1.27 +
1.28 +using namespace DBSC;
1.29 +
1.30 +/**
1.31 +Utility method, which can be used separately to remove the common part of a secure
1.32 +shared database name. The input string format is:
1.33 +"DBS_UID_<DbName>".
1.34 +The output string format is:
1.35 +"<DbName>".
1.36 +@param aDbName An output/input parameter. Th input format is: "DBS_UID_<DbName>".
1.37 + The output format is: "<DbName>".
1.38 +@panic The method will panic in debug builds in case of a bad input string.
1.39 +*/
1.40 +void RDbPropsFactory::StripCommonPart(TDes& aDbName)
1.41 + {
1.42 + TInt pos = aDbName.FindF(KDbsPrefix);
1.43 + __ASSERT_DEBUG(pos != KErrNotFound, User::Invariant());
1.44 + aDbName.Delete(pos, KDbsPrefix().Length());
1.45 + //Remove the UID from the string
1.46 + TInt pos_b = aDbName.Locate('_');
1.47 +
1.48 + TPtrC right = aDbName.Mid(pos_b+1);
1.49 + TInt pos_e = right.Locate('_') + pos_b + 1;
1.50 +
1.51 + __ASSERT_DEBUG(pos_b != KErrNotFound && pos_e != KErrNotFound, User::Invariant());
1.52 + aDbName.Delete(pos_b, pos_e - pos_b + 1);
1.53 + }
1.54 +
1.55 +/**
1.56 +Utility method, which can be used separately to construct the common part of the secure
1.57 +shared database name. The result string format is:
1.58 +"DBS_UID_"
1.59 +@param aPolicyUid Security policy UID.
1.60 +@param aRes An output parameter, referencing the location, where the constructed string will be stored.
1.61 +*/
1.62 +void RDbPropsFactory::ConstructCommonPart(TUid aPolicyUid, TDes& aRes)
1.63 + {
1.64 + aRes.Zero();
1.65 + aRes.Append(KDbsPrefix);
1.66 + aRes.Append('_');
1.67 + aRes.AppendNumFixedWidthUC(aPolicyUid.iUid, EHex, 8);
1.68 + aRes.Append('_');
1.69 + }
1.70 +
1.71 +/**
1.72 +Standard factory method for TDbProps instances.
1.73 +The created TDbProps instance will be pushed in the cleanup stack.
1.74 +@return A pointer to the created TDbProps instance.
1.75 +@leave KErrNoMemory
1.76 +@internalComponent
1.77 +*/
1.78 +static TDbProps* NewDbPropsLC()
1.79 + {
1.80 + TDbProps* dbProps = new (ELeave) TDbProps;
1.81 + CleanupStack::PushL(dbProps);
1.82 + return dbProps;
1.83 + }
1.84 +
1.85 +/**
1.86 +Extracts the drive number from the supplied TParse instance.
1.87 +@param aFileNameParser A reference to TParse instance, which will be used to extract the
1.88 +drive number.
1.89 +@return Extracted TDriveNumber value.
1.90 +@leave KErrArgument aFileNameParser parameter does not contain a drive number or it cannot
1.91 + be constructed from the string.
1.92 +@internalComponent
1.93 +*/
1.94 +static TDriveNumber ExtractDriveNumberL(TParse& aFileNameParser)
1.95 + {
1.96 + TPtrC drvPtr = aFileNameParser.Drive();
1.97 + if(drvPtr.Length() == 0)
1.98 + {
1.99 + __LEAVE(KErrArgument);
1.100 + }
1.101 + TInt drvId = 0;
1.102 + __LEAVE_IF_ERROR(RFs::CharToDrive(drvPtr[0], drvId));
1.103 + return static_cast <TDriveNumber> (drvId);
1.104 + }
1.105 +
1.106 +/**
1.107 +Creates private directory of the DBMS server if it does not exist (on a specific drive).
1.108 +If the supplied aDriveNumber parameter refers to a rom drive, the method does nothing.
1.109 +@param aDriveNumber The drive number, where the private DBMS data directory has to be created.
1.110 +@param aFs A file session instance.
1.111 +@leave RFs::CreatePrivatePath() leave error codes.
1.112 +@internalComponent
1.113 +*/
1.114 +static void CreatePrivateDataPathL(TDriveNumber aDriveNumber, RFs& aFs)
1.115 + {
1.116 + TDriveInfo driveInfo;
1.117 + __LEAVE_IF_ERROR(aFs.Drive(driveInfo, aDriveNumber));
1.118 + if(driveInfo.iDriveAtt & KDriveAttRom)
1.119 + {//ROM drive - do nothing.
1.120 + return;
1.121 + }
1.122 + TInt err = aFs.CreatePrivatePath(aDriveNumber);
1.123 + if(err != KErrNone && err != KErrAlreadyExists)
1.124 + {
1.125 + __LEAVE(err);
1.126 + }
1.127 + }
1.128 +
1.129 +/**
1.130 +*/
1.131 +RDbPropsFactory::RDbPropsFactory(RFs& aFs) :
1.132 + iFs(aFs),
1.133 + iFileNameParser(NULL),
1.134 + iPrivateDataPath(NULL)
1.135 + {
1.136 + }
1.137 +
1.138 +/**
1.139 +Initializes RDbPropsFactory instance
1.140 +@leave One of the system wide error codes, including KErrNoMemory.
1.141 +*/
1.142 +void RDbPropsFactory::OpenL()
1.143 + {
1.144 + iFileNameParser = new (ELeave) TParse;
1.145 + iPrivateDataPath = HBufC::NewL(KMaxFileName);
1.146 + TPtr ptr(iPrivateDataPath->Des());
1.147 + __LEAVE_IF_ERROR(iFs.PrivatePath(ptr));
1.148 + }
1.149 +
1.150 +/**
1.151 +*/
1.152 +void RDbPropsFactory::Close()
1.153 + {
1.154 + delete iPrivateDataPath;
1.155 + delete iFileNameParser;
1.156 + }
1.157 +
1.158 +/**
1.159 +Extracts database properties from the database path and format string.
1.160 +The created and returned TDbProps instance will be pushed in the cleanup stack.
1.161 +@param aPath Database path.
1.162 +@param aFormatStr database format string.
1.163 +@return A pointer to the created TDbProps instance.
1.164 +@leave One of the system-wide error codes, including KErrNoMemory.
1.165 +*/
1.166 +TDbProps* RDbPropsFactory::ExtractLC(const TDesC& aPath, const TDesC& aFormatStr)
1.167 + {
1.168 + __ASSERT(iFileNameParser);
1.169 + __ASSERT(iPrivateDataPath);
1.170 +
1.171 + __LEAVE_IF_ERROR(iFileNameParser->Set(aPath, NULL, NULL));
1.172 + TDbProps* dbProps = ::NewDbPropsLC();
1.173 +
1.174 + //TDbProps::iDbsUid.iUid, TDbProps::iDbsUid.iRqAccess
1.175 + TPtrC fmtIdent;//fmtIdent may contain KSecure keyword.
1.176 + ::ExtractUidAndName(aFormatStr, dbProps->iDbPolicyRequest.iUid, fmtIdent);
1.177 + dbProps->iDbPolicyRequest.iAccessType = (fmtIdent.CompareF(KSecure) == 0 ? EATSecure : EATNonSecure);
1.178 +
1.179 + //TDbProps::iDriveNumber
1.180 + dbProps->iDriveNumber = ::ExtractDriveNumberL(*iFileNameParser);
1.181 + ::CheckDriveL(iFs, dbProps->iDriveNumber);
1.182 +
1.183 + if(dbProps->iDbPolicyRequest.iAccessType == EATSecure)
1.184 + {//requested access to a secure shared database
1.185 + ExtractSecureL(aFormatStr, *dbProps);
1.186 + }
1.187 + else
1.188 + {//requested access to a non-secure database
1.189 + ExtractNonSecureL(aPath, aFormatStr, *dbProps);
1.190 + }
1.191 +
1.192 + return dbProps;
1.193 + }
1.194 +
1.195 +/**
1.196 +Extracts database properties from the database path, assuming that this is a secure shared
1.197 +database.
1.198 +The created and returned TDbProps instance will be pushed in the cleanup stack.
1.199 +@param aPath Database path.
1.200 +@param aPolicyUid Security policy UID.
1.201 +@return A pointer to the created TDbProps instance.
1.202 +@leave One of the system-wide error codes, including KErrNoMemory.
1.203 +*/
1.204 +TDbProps* RDbPropsFactory::ExtractLC(const TDesC& aPath, TUid aPolicyUid)
1.205 + {
1.206 + TBuf<32> dbFormat;
1.207 + dbFormat.Copy(KSecure);
1.208 + dbFormat.Append(aPolicyUid.Name());
1.209 + return ExtractLC(aPath, dbFormat);
1.210 + }
1.211 +
1.212 +/**
1.213 +Utility method, which can be used separately to get the common part of the secure
1.214 +shared database full path. The result string format is:
1.215 +"<Drive>:\<PrivatePath>\"
1.216 +@param aDriveNumber A drive number, for which the private data path string has to be constructed.
1.217 +@param aRes An output parameter, referencing the location, where the created private path has to be copied.
1.218 +@leave RFs::DriveToChar() leave error codes
1.219 +*/
1.220 +void RDbPropsFactory::GetPrivatePathL(TDriveNumber aDriveNumber, TDes& aRes) const
1.221 + {
1.222 + aRes.Zero();
1.223 + TChar driveChar;
1.224 + __LEAVE_IF_ERROR(RFs::DriveToChar(aDriveNumber, driveChar));
1.225 + aRes.Append(driveChar);
1.226 + aRes.Append(':');
1.227 + aRes.Append(*iPrivateDataPath);
1.228 + }
1.229 +
1.230 +/**
1.231 +Extracts secure shared database properties.
1.232 +@param aFormatStr Secure shared database format string.
1.233 +@param aDbProps An output parameter, referencing the location, where the datapase properties will be stored.
1.234 +@leave KErrArgument Bad format string. Some of the other system-wide error codes.
1.235 +*/
1.236 +void RDbPropsFactory::ExtractSecureL(const TDesC& aFormatStr, TDbProps& aDbProps)
1.237 + {
1.238 + if(aDbProps.iDbPolicyRequest.iUid == KNullUid)
1.239 + {//Secure shared database cannot have null uid.
1.240 + __LEAVE(KErrArgument);
1.241 + }
1.242 + if(iFileNameParser->PathPresent())
1.243 + {//The path can contain only the database name.
1.244 + __LEAVE(KErrArgument);
1.245 + }
1.246 + TPtrC dbName = iFileNameParser->NameAndExt();
1.247 + if(dbName.Length() > KDbMaxName)
1.248 + {//There is a limit for the secure shared database names
1.249 + __LEAVE(KErrArgument);
1.250 + }
1.251 + ::CreatePrivateDataPathL(aDbProps.iDriveNumber, iFs);
1.252 + ConstructFullDbPathL(aDbProps);
1.253 + ConstructFormatString(aDbProps, aFormatStr);
1.254 + }
1.255 +
1.256 +/**
1.257 +Extracts non-secure database properties.
1.258 +@param aPath Database path.
1.259 +@param aFormatStr Database format string.
1.260 +@param aDbProps An output parameter, referencing the location, where the datapase properties will be stored.
1.261 +@leave KErrPermissionDenied The database path contains the DBMS server private data path.
1.262 +*/
1.263 +void RDbPropsFactory::ExtractNonSecureL(const TDesC& aPath, const TDesC& aFormatStr,
1.264 + TDbProps& aDbProps)
1.265 + {
1.266 + //DBMS private data path cannot be the first in the database path. This is non-secure database.
1.267 + TInt pos = aPath.FindF(iPrivateDataPath->Des());
1.268 + if(pos != KErrNotFound)
1.269 + {//If pos is 2 (pos 0 - drive letter, pos 1 - ':'), then
1.270 + //the caller wants to create/open non-secure database in the DBMS private directory,
1.271 + //which is not allowed.
1.272 + if(pos == 2)
1.273 + {
1.274 + __LEAVE(KErrPermissionDenied);
1.275 + }
1.276 + }
1.277 + //The database path and format string stay the same
1.278 + aDbProps.iPath.Copy(aPath);
1.279 + aDbProps.iFormatStr.Copy(aFormatStr);
1.280 + }
1.281 +
1.282 +/**
1.283 +Constructs the full physical path of the secure shared database
1.284 +@param aDbProps An output parameter, where the database path will be stored.
1.285 +@leave RDbPropsFactory::GetPrivatePathL() leaving error codes
1.286 +@see RDbPropsFactory::GetPrivatePathL()
1.287 +*/
1.288 +void RDbPropsFactory::ConstructFullDbPathL(TDbProps& aDbProps)
1.289 + {
1.290 + GetPrivatePathL(aDbProps.iDriveNumber, aDbProps.iPath);
1.291 + TBuf<32> dbNameCmnPart;
1.292 + RDbPropsFactory::ConstructCommonPart(aDbProps.iDbPolicyRequest.iUid, dbNameCmnPart);
1.293 + aDbProps.iPath.Append(dbNameCmnPart);
1.294 + aDbProps.iPath.Append(iFileNameParser->Name());
1.295 + aDbProps.iPath.Append(iFileNameParser->Ext());
1.296 + }
1.297 +
1.298 +/**
1.299 +Processes the format string of secure shared database. "SECURE" keyword and security policy UID
1.300 +will be removed.
1.301 +@param aDbProps An input/output parameter, referencing TDbProps instance, where the processed
1.302 + database format string will be stored.
1.303 +@param aFormatStr The database format string.
1.304 +*/
1.305 +void RDbPropsFactory::ConstructFormatString(TDbProps& aDbProps, const TDesC& aFormatStr)
1.306 + {
1.307 + TDes& fmtStr = aDbProps.iFormatStr;
1.308 + fmtStr.Copy(aFormatStr);
1.309 + //Remove KSecure keyword from the format string
1.310 + TInt pos = fmtStr.FindF(KSecure);
1.311 + __ASSERT_DEBUG(pos != KErrNotFound, User::Invariant());
1.312 + fmtStr.Delete(pos, KSecure().Length());
1.313 + //Remove the UID from the format string
1.314 + TInt pos_b = fmtStr.Locate('[');
1.315 + TInt pos_e = fmtStr.Locate(']');
1.316 + __ASSERT_DEBUG(pos_b != KErrNotFound && pos_e != KErrNotFound, User::Invariant());
1.317 + fmtStr.Delete(pos_b, pos_e - pos_b + 1);
1.318 + }