1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/centralrepository/common/src/inifile.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,2310 @@
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 +//
1.18 +
1.19 +#define __INCLUDE_CAPABILITY_NAMES__
1.20 +#include <utf.h>
1.21 +#include "inifile.h"
1.22 +#include "datatype.h"
1.23 +#include "log.h"
1.24 +
1.25 +#define MAX(a,b) ((a)<(b)?(b):(a))
1.26 +#define MAX3(a,b,c) MAX(MAX(a,b),c)
1.27 +#define MAX4(a,b,c,d) MAX(MAX(a,b),MAX(c,d))
1.28 +
1.29 +//Unicode text file prefix - FE,FF bytes.
1.30 +static const TUint16 KUcs2Bom = 0xfeff;
1.31 +
1.32 +//Repository (ini) file - signature
1.33 +_LIT(KSignature, "cenrep");
1.34 +static const TInt KSignatureLen = 6;
1.35 +
1.36 +//Repository (ini) file - version string and version number
1.37 +_LIT(KVersion, "version");
1.38 +static const TInt KVersionLen = 7;
1.39 +static const TUint KCurrentVersion = 1;
1.40 +
1.41 +//Repository (ini) file - supported types names
1.42 +_LIT(KTypeInt, "int");
1.43 +_LIT(KTypeReal, "real");
1.44 +_LIT(KTypeString, "string");
1.45 +_LIT(KTypeString8, "string8");
1.46 +_LIT(KTypeBinary, "binary");
1.47 +
1.48 +//Max type name length
1.49 +static const TInt KMaxTypeLen = 9;
1.50 +
1.51 +//The symbol used in repository (ini) files to note null data
1.52 +static const TChar KNullDataIndicator = '-';
1.53 +
1.54 +// Section identifiers in the repository (ini) file
1.55 +_LIT(KPlatSecSection, "[platsec]");
1.56 +static const TInt KPlatSecSectionLen = 9;
1.57 +
1.58 +_LIT(KOwnerSection, "[owner]");
1.59 +static const TInt KOwnerSectionLen = 7;
1.60 +
1.61 +_LIT(KTimeStampSection, "[timestamp]");
1.62 +static const TInt KTimeStampSectionLen = 11;
1.63 +
1.64 +_LIT(KMainSection, "[main]");
1.65 +static const TInt KMainSectionLen = 6;
1.66 +
1.67 +_LIT(KDefaultMetaSection, "[defaultmeta]");
1.68 +static const TInt KDefaultMetaSectionLen = 13 ;
1.69 +
1.70 +static const TInt KIniFileSectionLen = MAX4(KPlatSecSectionLen,KMainSectionLen,KTimeStampSectionLen, KDefaultMetaSectionLen);
1.71 +
1.72 +// Other useful string constants
1.73 +_LIT(KMaskString, "mask");
1.74 +static const TInt KMaskLen = 4;
1.75 +
1.76 +_LIT(KReadAccessSidString, "sid_rd");
1.77 +_LIT(KReadAccessCapString, "cap_rd");
1.78 +_LIT(KWriteAccessSidString, "sid_wr");
1.79 +_LIT(KWriteAccessCapString, "cap_wr");
1.80 +_LIT(KAccessAlwaysPass, "alwayspass");
1.81 +_LIT(KAccessAlwaysFail, "alwaysfail");
1.82 +// could do max of _LITs above
1.83 +static const TInt KMaxAccessTypeLen = 6;
1.84 +
1.85 +// longest capability string from CapabilityNames is 15
1.86 +static const TInt KMaxCapabilityStringLen = 20;
1.87 +
1.88 +static const TInt KBufLen = MAX3(KVersionLen, KSignatureLen, KIniFileSectionLen);
1.89 +
1.90 +
1.91 +
1.92 +const TUint KCr = '\r';
1.93 +const TUint KTab = '\t';
1.94 +const TUint KSpace = ' ';
1.95 +
1.96 +#ifdef CENTREP_CONV_TOOL
1.97 +_LIT(KTransactFileName, "transact");
1.98 +_LIT(KCrNl, "\r\n");
1.99 +_LIT(KHexIntFormat, "0x%X");
1.100 +_LIT(KUidFormat, "0x%08X");
1.101 +_LIT(KRangeMetaFmt, "0x%X 0x%X 0x%08X");
1.102 +_LIT(KMaskMetaFmt, "0x%X mask = 0x%X 0x%08X");
1.103 +
1.104 +_LIT(KRangePrefix, "0x%X 0x%X");
1.105 +_LIT(KMaskPrefix, "0x%08X mask = 0x%08X");
1.106 +#endif
1.107 +
1.108 +/////////////////////////////////////////////////////////////////////////////////////////////////
1.109 +// Local functions
1.110 +
1.111 +/**
1.112 +The function checks if the file with aFile name exists.
1.113 +@param aFile File name, including the full path.
1.114 +@return 0, if the file does not exist, non-zero value otherwise.
1.115 +@internalComponent
1.116 +*/
1.117 +/**
1.118 +#ifdef CENTREP_CONV_TOOL
1.119 +static TBool FileExists(const TDesC& aFile)
1.120 + {
1.121 + TEntry entry;
1.122 + return TServerResources::iFs.Entry(aFile, entry) == KErrNone;
1.123 + }
1.124 +#endif
1.125 +*/
1.126 +
1.127 +/**
1.128 +@internalComponent
1.129 +*/
1.130 +static TInt ReadFileL(RFile aFile, HBufC16*& aBuf)
1.131 + {
1.132 + TInt size;
1.133 + TInt r = aFile.Size(size);
1.134 + if(r!=KErrNone)
1.135 + return r;
1.136 + if(size<2)
1.137 + return KErrCorrupt;
1.138 +
1.139 + TInt len = size/2-1;
1.140 + aBuf = HBufC16::NewL(len);
1.141 + TPtr16 ptr16 = aBuf->Des();
1.142 + TPtr8 ptr8((TUint8*)ptr16.Ptr(), 0, 2);
1.143 + r = aFile.Read(ptr8, 2);
1.144 + if(r!=KErrNone)
1.145 + return r;
1.146 +
1.147 + if(*ptr16.Ptr()!=KUcs2Bom)
1.148 + {
1.149 + __CENTREP_TRACE("File not Ucs2. No BOM");
1.150 + return KErrCorrupt;
1.151 + }
1.152 + ptr8.Set((TUint8*)ptr16.Ptr(), 0, size-2);
1.153 + r = aFile.Read(ptr8);
1.154 + if(r!=KErrNone)
1.155 + return r;
1.156 + ptr16.SetLength(len);
1.157 +
1.158 + return KErrNone;
1.159 + }
1.160 +
1.161 +static TBool IsNegativeNumber(TLex& aLex)
1.162 + {
1.163 + if (aLex.Peek()=='-')
1.164 + return ETrue;
1.165 + else
1.166 + return EFalse;
1.167 + }
1.168 +
1.169 +/**
1.170 +@internalComponent
1.171 +*/
1.172 +static TInt ReadNumberL(TLex& aLex, TUint32& aVal)
1.173 + {
1.174 + TRadix radix = EDecimal;
1.175 + if(aLex.Peek()=='0')
1.176 + {
1.177 + aLex.Inc();
1.178 + if(aLex.Peek().GetLowerCase()=='x')
1.179 + {
1.180 + aLex.Inc();
1.181 + radix = EHex;
1.182 + }
1.183 + else
1.184 + aLex.UnGet();
1.185 + }
1.186 +
1.187 + if(aLex.Val(aVal, radix)!=KErrNone)
1.188 + return KErrCorrupt;
1.189 +
1.190 + return KErrNone;
1.191 + }
1.192 +
1.193 +#ifdef CENTREP_CONV_TOOL
1.194 +/**
1.195 +@internalComponent
1.196 +*/
1.197 +static void WriteBinary(TDes& aBuf, const HBufC8* aString)
1.198 + {
1.199 + if(aString)
1.200 + {
1.201 + TInt len = aString->Length();
1.202 + if(len==0)
1.203 + aBuf.Append(KNullDataIndicator);
1.204 + else
1.205 + {
1.206 + TPtr8 ptr8 = const_cast<HBufC8*>(aString)->Des();
1.207 + for(TInt i=0;i<len;i++)
1.208 + aBuf.AppendNumFixedWidth(ptr8[i], EHex, 2);
1.209 + }
1.210 + }
1.211 + else
1.212 + {
1.213 + aBuf.Append(KNullDataIndicator);
1.214 + }
1.215 + }
1.216 +
1.217 +/**
1.218 +The function writes setting value into the supplied buffer (aBuf).
1.219 +@param aBuf The buffer where the setting value will be appended.
1.220 +@param aSetting Reference to the setting object
1.221 +@leave KErrGeneral If the supplied setting object has unknown type.
1.222 +@internalComponent
1.223 +*/
1.224 +static void AddSettingValueL(TDes& aBuf, const TServerSetting& aSetting)
1.225 + {
1.226 + switch(aSetting.Type())
1.227 + {
1.228 + case TServerSetting::EInt:
1.229 + aBuf.Append(KTypeInt);
1.230 + aBuf.Append(KSpace);
1.231 + aBuf.AppendNum(aSetting.GetIntValue());
1.232 + break;
1.233 + case TServerSetting::EReal:
1.234 + aBuf.Append(KTypeReal);
1.235 + aBuf.Append(KSpace);
1.236 + aBuf.AppendNum(aSetting.GetRealValue(), TRealFormat());
1.237 + break;
1.238 + case TServerSetting::EString:
1.239 + aBuf.Append(KTypeBinary);
1.240 + aBuf.Append(KSpace);
1.241 + WriteBinary(aBuf, aSetting.GetStrValue());
1.242 + break;
1.243 + default:
1.244 + User::Leave(KErrGeneral); //unknown setting type
1.245 + break;
1.246 + }
1.247 + }
1.248 +#endif
1.249 +
1.250 +/////////////////////////////////////////////////////////////////////////////////////////////////
1.251 +// CIniFileIn class
1.252 +
1.253 +TInt CIniFileIn::NewLC(RFs& aFs,CIniFileIn*& aIniFile,const TDesC& aFullFileName)
1.254 + {
1.255 + aIniFile = new(ELeave) CIniFileIn(aFs);
1.256 + CleanupStack::PushL(aIniFile);
1.257 + RFile file;
1.258 + CleanupClosePushL(file);
1.259 + TInt r = file.Open(aFs, aFullFileName, EFileRead|EFileStreamText);
1.260 + if(r==KErrNone)
1.261 + {
1.262 +
1.263 +#ifdef CENTREP_TRACE
1.264 + aIniFile->iFullName = HBufC::NewL(aFullFileName.Length());
1.265 + TPtr filename = aIniFile->iFullName->Des();
1.266 + filename.Copy(aFullFileName);
1.267 +#endif
1.268 + TInt rReadFile = ReadFileL(file,aIniFile->iBuf);
1.269 + CleanupStack::PopAndDestroy(); //file
1.270 + TInt rReadHeader=KErrNone;
1.271 + if(rReadFile==KErrNone)
1.272 + {
1.273 + aIniFile->iLex.Assign(aIniFile->iBuf->Des());
1.274 + rReadHeader=aIniFile->ReadHeaderL();
1.275 + }
1.276 +
1.277 + if((rReadFile==KErrCorrupt) || ( rReadHeader==KErrCorrupt))
1.278 + {
1.279 + return KErrCorrupt;
1.280 + }
1.281 + }
1.282 + else
1.283 + {
1.284 + CleanupStack::Pop();//file
1.285 + }
1.286 + return r;
1.287 +
1.288 +
1.289 + }
1.290 +
1.291 +CIniFileIn::~CIniFileIn()
1.292 + {
1.293 + delete iBuf;
1.294 +#ifdef CENTREP_TRACE
1.295 + delete iFullName;
1.296 +#endif
1.297 + }
1.298 +
1.299 +
1.300 +TInt CIniFileIn::ReadHeaderL()
1.301 + {
1.302 + TBuf<KBufLen> buf;
1.303 +
1.304 + //
1.305 + // Check file signature
1.306 + //
1.307 +
1.308 + SkipComments();
1.309 +
1.310 + iLex.Mark();
1.311 + iLex.SkipCharacters();
1.312 +
1.313 + if(iLex.TokenLength()>KSignatureLen)
1.314 + {
1.315 + __CENTREP_TRACE1("[%S] Invalid header signature",iFullName);
1.316 + return(KErrCorrupt);
1.317 + }
1.318 + buf.CopyLC(iLex.MarkedToken());
1.319 + if(buf.Compare(KSignature)!=0)
1.320 + {
1.321 + __CENTREP_TRACE1("[%S] Invalid header signature",iFullName);
1.322 + return(KErrCorrupt);
1.323 + }
1.324 + //
1.325 + // Check file version
1.326 + //
1.327 +
1.328 + SkipComments();
1.329 +
1.330 + iLex.Mark();
1.331 + iLex.SkipCharacters();
1.332 +
1.333 + if(iLex.TokenLength()>KVersionLen)
1.334 + {
1.335 + __CENTREP_TRACE1("[%S] Missing version keyword",iFullName);
1.336 + return(KErrCorrupt);
1.337 + }
1.338 + buf.CopyLC(iLex.MarkedToken());
1.339 + if(buf.Compare(KVersion)!=0)
1.340 + {
1.341 + __CENTREP_TRACE1("[%S] Missing version keyword",iFullName);
1.342 + return(KErrCorrupt);
1.343 + }
1.344 + iLex.SkipSpace();
1.345 +
1.346 + TUint version;
1.347 + iLex.Val(version);
1.348 + if(version>KCurrentVersion)
1.349 + {
1.350 + __CENTREP_TRACE1("[%S] Invalid version number",iFullName);
1.351 + return(KErrNotSupported);
1.352 + }
1.353 + return( KErrNone);
1.354 + }
1.355 +
1.356 +void CIniFileIn::SkipComments()
1.357 + {
1.358 + for(;;)
1.359 + {
1.360 + iLex.SkipSpace();
1.361 +
1.362 + if(iLex.Peek()!='#')
1.363 + break;
1.364 +
1.365 + while(iLex.Get()!='\n' && !iLex.Eos()) {}
1.366 + }
1.367 + }
1.368 +
1.369 +void CIniFileIn::SkipEqualSign()
1.370 + {
1.371 + iLex.SkipSpace();
1.372 + if(iLex.Peek()=='=')
1.373 + iLex.Get();
1.374 +
1.375 + iLex.SkipSpace();
1.376 + }
1.377 +
1.378 +TInt CIniFileIn::ReadSettingOnlyL(TServerSetting& aSetting,TBool& aSingleMetaFound)
1.379 + {
1.380 + TInt ret = KErrNone;
1.381 +
1.382 + aSingleMetaFound=EFalse;
1.383 +
1.384 + SkipComments();
1.385 + iLex.SkipSpace();
1.386 +
1.387 + if(iLex.Eos())
1.388 + return KErrNotFound;
1.389 +
1.390 + TUint32 key;
1.391 + TInt r=ReadNumberL(iLex, key);
1.392 + if(r!=KErrNone)
1.393 + {
1.394 + // returns either KErrCorrupt or KErrNone
1.395 + __CENTREP_TRACE1("[%S] Invalid single setting id",iFullName);
1.396 + return r;
1.397 + }
1.398 + aSetting.SetKey(key);
1.399 +
1.400 + iLex.SkipSpaceAndMark();
1.401 + iLex.SkipCharacters();
1.402 +
1.403 + if(iLex.TokenLength()>KMaxTypeLen)
1.404 + {
1.405 + __CENTREP_TRACE1("[%S] Invalid key type, must be one of: [int,real,string,string8,binary]",iFullName);
1.406 + return KErrCorrupt;
1.407 + }
1.408 + TBuf<KMaxTypeLen> type;
1.409 + type.CopyLC(iLex.MarkedToken());
1.410 +
1.411 + iLex.SkipSpace();
1.412 +
1.413 + if(type.Compare(KTypeInt)==0)
1.414 + {
1.415 + if (IsNegativeNumber(iLex))
1.416 + {
1.417 + TInt i;
1.418 + if(iLex.Val(i)!=KErrNone)
1.419 + {
1.420 + __CENTREP_TRACE1("[%S] Invalid negative integer value",iFullName);
1.421 + return(KErrCorrupt);
1.422 + }
1.423 + aSetting.SetIntValue(i);
1.424 + }
1.425 + else
1.426 + {
1.427 + TUint32 i;
1.428 + TInt r=ReadNumberL(iLex, i);
1.429 + if(r!=KErrNone)
1.430 + {
1.431 + __CENTREP_TRACE1("[%S] Invalid integer value",iFullName);
1.432 + return r;
1.433 + }
1.434 + aSetting.SetIntValue(i);
1.435 + }
1.436 + }
1.437 + else if(type.Compare(KTypeReal)==0)
1.438 + {
1.439 + TReal r;
1.440 + ret=iLex.Val(r,'.');
1.441 + //iLex.Val with TReal can return KErrNoMemory
1.442 + if (ret!=KErrNone)
1.443 + {
1.444 + if (ret==KErrNoMemory)
1.445 + User::LeaveNoMemory();
1.446 + else
1.447 + {
1.448 + __CENTREP_TRACE1("[%S] Invalid real value",iFullName);
1.449 + return KErrCorrupt;
1.450 + }
1.451 + }
1.452 + TReal* temp = new(ELeave)TReal(r);
1.453 + aSetting.SetRealValue(temp);
1.454 + temp = NULL;
1.455 + }
1.456 + else if(type.Compare(KTypeString)==0)
1.457 + {
1.458 + HBufC8* s;
1.459 + ret = ReadStringL(s);
1.460 + if(ret != KErrNone)
1.461 + {
1.462 + __CENTREP_TRACE1("[%S] Invalid string value",iFullName);
1.463 + return KErrCorrupt;
1.464 + }
1.465 + aSetting.SetStrValue(s);
1.466 + }
1.467 +
1.468 + else if(type.Compare(KTypeString8)==0)
1.469 + {
1.470 + HBufC8* s;
1.471 + ret = ReadString16To8L(s);
1.472 + if(ret != KErrNone)
1.473 + {
1.474 + __CENTREP_TRACE1("[%S] Invalid string8 value",iFullName);
1.475 + return KErrCorrupt;
1.476 + }
1.477 + aSetting.SetStrValue(s);
1.478 + }
1.479 +
1.480 + else if(type.Compare(KTypeBinary)==0)
1.481 + {
1.482 + HBufC8* s = NULL;
1.483 + ret = ReadBinaryL(s);
1.484 + if(ret != KErrNone)
1.485 + {
1.486 + __CENTREP_TRACE1("[%S] Invalid binary value",iFullName);
1.487 + return KErrCorrupt;
1.488 + }
1.489 + aSetting.SetStrValue(s);
1.490 + }
1.491 + else
1.492 + {
1.493 + __CENTREP_TRACE1("[%S] Invalid key type, must be one of: [int,real,string,string8,binary]",iFullName);
1.494 + return KErrCorrupt;
1.495 + }
1.496 + //skip any spaces or tabs
1.497 + while(iLex.Peek()==KSpace || iLex.Peek()==KTab)
1.498 + {
1.499 + iLex.Inc();
1.500 + }
1.501 +
1.502 + TUint32 meta;
1.503 +
1.504 + /**
1.505 + carriage return reached which means that there is no meta AND capabilities
1.506 + defined for this key. Thus setting meta to NULL to be able to set a value
1.507 + from default section later.
1.508 + */
1.509 + if (iLex.Peek()==KCr)
1.510 + {
1.511 + meta = 0;
1.512 + }
1.513 + else
1.514 + {
1.515 + r=ReadNumberL(iLex, meta);
1.516 + /**
1.517 + If meta can not be read, it is not neccessary an error.
1.518 + It might be not present for an individual key and it will be taken
1.519 + from a default section.
1.520 + If single meta is present, we need to remember so we can recognise a single
1.521 + meta of 0 as distinct from no meta ( also sets meta to 0 ).
1.522 + */
1.523 + if(r!=KErrNone)
1.524 + meta = 0;
1.525 + else
1.526 + aSingleMetaFound=ETrue;
1.527 + }
1.528 +
1.529 + aSetting.SetMeta(meta);
1.530 +
1.531 + return KErrNone;
1.532 + }
1.533 +
1.534 +/**
1.535 +Read an entire DefaultMeta section from ini file
1.536 +and create FDefault metadata entries
1.537 +
1.538 +@internalTechnology
1.539 +@return KErrNone, KErrCorrupt or KErrNotFound
1.540 +*/
1.541 +TInt CIniFileIn::ReadDefaultMetaSecSectionL(TUint32& aDefaultMeta, RDefaultMetaArray& aDefaultMetaRanges)
1.542 + {
1.543 + TBuf<KBufLen> buf;
1.544 +
1.545 + //
1.546 + // Check if a DefaultMeta section is present
1.547 + //
1.548 +
1.549 + SkipComments();
1.550 +
1.551 + // we will need this section later to write the out file...
1.552 + iLex.Mark(iMainSectionMark);
1.553 +
1.554 + iLex.Mark();
1.555 + iLex.SkipCharacters();
1.556 +
1.557 + if( iLex.TokenLength()!=KDefaultMetaSectionLen ||
1.558 + (buf.CopyLC( iLex.MarkedToken() ), buf.Compare( KDefaultMetaSection )!=0) )
1.559 + {
1.560 + // Meta not available
1.561 + iLex.UnGetToMark();
1.562 + return KErrNotFound;
1.563 + }
1.564 +
1.565 + //
1.566 + // Lets read Meta settings
1.567 + //
1.568 +
1.569 + SkipComments();
1.570 +
1.571 + // we might have a default Meta section first
1.572 + if(KErrNone != ReadNumber(aDefaultMeta))
1.573 + {
1.574 + // should we log that no default read policy?
1.575 + }
1.576 +
1.577 +
1.578 + // now lets try range policies
1.579 + TInt r=ReadRangeMetaDefaultsL(aDefaultMetaRanges);
1.580 + if(r!=KErrNone)
1.581 + {
1.582 + __CENTREP_TRACE1("[%S] Error parsing [defaultMeta]",iFullName);
1.583 + return r;
1.584 + }
1.585 + iLex.Mark(iMainSectionMark);
1.586 + return KErrNone;
1.587 + }
1.588 +
1.589 +
1.590 +/**
1.591 +Reads Meta defaults as defined for range of indexes
1.592 +
1.593 +@internalTechnology
1.594 +@return KErrNone, KErrCorrupt
1.595 +*/
1.596 +TInt CIniFileIn::ReadRangeMetaDefaultsL(RDefaultMetaArray& aDefaultMetaRanges)
1.597 +{
1.598 + TUint32 lowKey = 0;
1.599 + TBuf<KBufLen> buf;
1.600 +
1.601 + SkipComments();
1.602 + while(KErrNone == ReadNumber(lowKey))
1.603 + {
1.604 + // highKey and mask needs to be zero'd every cycle...
1.605 + TUint32 highKey = 0;
1.606 + TUint32 mask = 0;
1.607 + TUint32 defaultMeta = 0 ;
1.608 +
1.609 + iLex.SkipSpace();
1.610 + // may be not range but key & mask so lets check 'mask' keyword
1.611 + if(!iLex.Peek().IsDigit())
1.612 + {
1.613 + //so should be mask then...
1.614 + iLex.Mark();
1.615 + while((iLex.Peek()!='=')&&(!iLex.Eos()))
1.616 + {
1.617 + iLex.Inc();
1.618 +
1.619 + if(iLex.TokenLength() >= KMaskLen)
1.620 + {
1.621 + // so no '=' there
1.622 + // not necessarily bad thing... could be space there first
1.623 + break;
1.624 + }
1.625 +
1.626 + }
1.627 +
1.628 + // check if KMaskLen is < buf length?
1.629 + buf.CopyLC(iLex.MarkedToken());
1.630 + if(buf.Compare(KMaskString)!=0)
1.631 + {
1.632 + __CENTREP_TRACE1("[%S] Missing 'mask' keyword [defaultMeta]",iFullName);
1.633 + return KErrCorrupt;
1.634 + }
1.635 +
1.636 + iLex.SkipSpace();
1.637 + if('=' != iLex.Get())
1.638 + {
1.639 + __CENTREP_TRACE1("[%S] Missing '=' for 'mask' keyword [defaultMeta]",iFullName);
1.640 + return KErrCorrupt;
1.641 + }
1.642 + iLex.SkipSpace();
1.643 + TInt r=ReadNumberL(iLex,mask);
1.644 + if(r!=KErrNone)
1.645 + {
1.646 + __CENTREP_TRACE1("[%S] Invalid 'mask' for keyspace range [defaultMeta]",iFullName);
1.647 + return KErrCorrupt;
1.648 + }
1.649 + }
1.650 + else
1.651 + {
1.652 + TInt r = ReadNumberL(iLex,highKey);
1.653 + if(r!=KErrNone)
1.654 + {
1.655 + __CENTREP_TRACE1("[%S] Invalid end of range [defaultMeta]",iFullName);
1.656 + return KErrCorrupt;
1.657 + }
1.658 + }
1.659 +
1.660 +
1.661 + if(KErrNone == ReadNumber(defaultMeta))
1.662 + {
1.663 + TSettingsDefaultMeta metaDefault(defaultMeta,lowKey, highKey, mask);
1.664 + aDefaultMetaRanges.AppendL(metaDefault);
1.665 + }
1.666 + else
1.667 + {
1.668 + // unfortunately, we can't tell if we got here because the default
1.669 + // meta was bad or because there was an invalid start value for the range.
1.670 + __CENTREP_TRACE1("[%S] Range defined without default or bad start of range [defaultMeta]",iFullName);
1.671 + // range specified with no default Meta!
1.672 + return KErrCorrupt;
1.673 + }
1.674 + SkipComments();
1.675 + }
1.676 + return KErrNone;
1.677 +}
1.678 +
1.679 +/**
1.680 +Read Owner section from ini file and extract owner UID
1.681 +
1.682 +@internalTechnology
1.683 +@return KErrNone, KErrCorrupt or KErrNotFound
1.684 +*/
1.685 +TInt CIniFileIn::ReadOwnerSectionL(TUint32 &aOwnerUID)
1.686 + {
1.687 + TBuf<KBufLen> buf;
1.688 +
1.689 +
1.690 +
1.691 + SkipComments();
1.692 +
1.693 + // we will need this section later to write the out file...
1.694 + iLex.Mark(iMainSectionMark);
1.695 +
1.696 + iLex.Mark();
1.697 + iLex.SkipCharacters();
1.698 +
1.699 + if( iLex.TokenLength()!=KOwnerSectionLen ||
1.700 + (buf.CopyLC( iLex.MarkedToken() ), buf.Compare( KOwnerSection )!=0) )
1.701 + {
1.702 + // Owner section not available
1.703 + iLex.UnGetToMark();
1.704 + return KErrNotFound;
1.705 + }
1.706 + else
1.707 + {
1.708 + // Found an "owner" section - must be followed by a UID (hex number
1.709 + // in format 0xnnnnn) to be valid!
1.710 + iLex.SkipSpace() ;
1.711 + if(iLex.Peek()=='0')
1.712 + {
1.713 + iLex.Inc();
1.714 + if(iLex.Peek().GetLowerCase()=='x')
1.715 + {
1.716 + iLex.Inc();
1.717 + if(iLex.Val(aOwnerUID, EHex)!=KErrNone)
1.718 + {
1.719 + __CENTREP_TRACE1("[%S] Invalid owner UID not valid hex digit [owner]",iFullName);
1.720 + return KErrCorrupt;
1.721 + }
1.722 + }
1.723 + else
1.724 + {
1.725 + __CENTREP_TRACE1("[%S] Invalid owner UID not valid hex digit [owner]",iFullName);
1.726 + return KErrCorrupt;
1.727 + }
1.728 + }
1.729 + else
1.730 + {
1.731 + __CENTREP_TRACE1("[%S] Invalid owner UID not valid hex digit [owner]",iFullName);
1.732 + return KErrCorrupt;
1.733 + }
1.734 + }
1.735 +
1.736 + iLex.Mark(iMainSectionMark);
1.737 +
1.738 + return KErrNone;
1.739 + }
1.740 +
1.741 +/**
1.742 +Read Timestamp section from ini file and extract value as a TTime
1.743 +
1.744 +@internalTechnology
1.745 +@return KErrNone, KErrCorrupt or KErrNotFound
1.746 +*/
1.747 +TInt CIniFileIn::ReadTimeStampSectionL(TTime &aTimeStamp)
1.748 + {
1.749 + TBuf<25> buf;
1.750 + SkipComments();
1.751 +
1.752 + // we will need this section later to write the out file...
1.753 + iLex.Mark(iMainSectionMark);
1.754 +
1.755 + iLex.Mark();
1.756 + iLex.SkipCharacters();
1.757 +
1.758 + buf.CopyLC( iLex.MarkedToken());
1.759 +
1.760 + if( iLex.TokenLength()!=KTimeStampSectionLen ||
1.761 + (buf.Compare( KTimeStampSection )!=0) )
1.762 + {
1.763 + // Timestamp section not available
1.764 + iLex.UnGetToMark();
1.765 + return KErrNotFound;
1.766 + }
1.767 + else
1.768 + {
1.769 + // Found a "timestamp" section - must be followed by a a timestamp
1.770 + // either in format...
1.771 + //
1.772 + // YYYYMMDD:HHMMSS.MMMMMM where:
1.773 + // YYYY = 4 digit year
1.774 + // MM = 2 digit numeric month
1.775 + // DD = 2 digit numeric date
1.776 + // HH = 2 digit hour
1.777 + // MM = 2 digit minute
1.778 + // SS = 2 digit second
1.779 + // MMMMMM = 6 digit microseconds
1.780 + // Note that this is the format used for constructing/initialising
1.781 + // a TTime from a string.
1.782 + //
1.783 + // ...or a 64-bit integer which can be converted to
1.784 + // to a TTime to be considered valid!
1.785 + //
1.786 + iLex.SkipSpace();
1.787 + iLex.Mark();
1.788 + iLex.SkipCharacters() ;
1.789 +
1.790 + buf.CopyLC(iLex.MarkedToken()) ;
1.791 + if (aTimeStamp.Set(buf) !=KErrNone)
1.792 + {
1.793 + TInt64 intTimeStamp ;
1.794 + iLex.UnGetToMark();
1.795 + if (iLex.Val(intTimeStamp) != KErrNone)
1.796 + {
1.797 + __CENTREP_TRACE1("[%S] Invalid time stamp [timestamp]",iFullName);
1.798 + return KErrCorrupt;
1.799 + }
1.800 + else
1.801 + {
1.802 + aTimeStamp = intTimeStamp;
1.803 + }
1.804 + }
1.805 + }
1.806 + iLex.Mark(iMainSectionMark);
1.807 + return KErrNone;
1.808 + }
1.809 +
1.810 +/**
1.811 +Read a setting and it's single policy ( if it exists )
1.812 +
1.813 +@internalTechnology
1.814 +@return KErrNone, KErrCorrupt
1.815 + aSetting setting read from ini file
1.816 + aSingleReadPolicy single read policy if any
1.817 + aSingleWritePolicy single write policy if any
1.818 + aSingleReadPolicyFound ETrue if single read policy found with this key, EFalse if not
1.819 + aSingleWritePolicyFound ETrue if single write policy found with this key, EFalse if not
1.820 + aSingleMetaFound ETrue if single metadata found with this key, EFalse if not
1.821 +*/
1.822 +TInt CIniFileIn::ReadSettingL(TServerSetting& aSetting,TSecurityPolicy& aSingleReadPolicy,TSecurityPolicy& aSingleWritePolicy, TBool& aSingleReadPolicyFound, TBool& aSingleWritePolicyFound, TBool& aSingleMetaFound)
1.823 + {
1.824 + aSingleReadPolicyFound = EFalse;
1.825 + aSingleWritePolicyFound = EFalse;
1.826 +
1.827 + TInt error = ReadSettingOnlyL(aSetting, aSingleMetaFound);
1.828 + if(KErrNone == error)
1.829 + {
1.830 + //Need to push into cleanupstack for string setting
1.831 + aSetting.PushL();
1.832 + // when multiple policies enabled then read in a loop
1.833 +
1.834 + if (iLex.Peek() !=KCr)
1.835 + {
1.836 + // if neither read/write policy found we do not create TSettingsAccessPolicy at all...
1.837 + TInt err=ReadRdPolicyL(aSingleReadPolicy);
1.838 + if (err==KErrNone)
1.839 + aSingleReadPolicyFound=ETrue;
1.840 + else
1.841 + {
1.842 + //we need to return error code rather than assuming no single policy is found
1.843 + if (err==KErrCorrupt || err==KErrNoMemory)
1.844 + {
1.845 +#ifdef CENTREP_TRACE
1.846 + if (err == KErrCorrupt)
1.847 + {
1.848 + __CENTREP_TRACE1("[%S] Invalid read setting",iFullName);
1.849 + }
1.850 +#endif
1.851 + aSetting.PopAndDestroy();
1.852 + return err;
1.853 + }
1.854 + //else if ret!=KErrNone very likely it is KErrNotFound so leave
1.855 + //the state of the writePolicyFound to EFalse
1.856 + }
1.857 +
1.858 + err=ReadWrPolicyL(aSingleWritePolicy);
1.859 + if (err==KErrNone)
1.860 + aSingleWritePolicyFound=ETrue;
1.861 + else
1.862 + {
1.863 + //we need to return error code rather than assuming no single policy is found
1.864 + if (err==KErrCorrupt || err==KErrNoMemory)
1.865 + {
1.866 +#ifdef CENTREP_TRACE
1.867 + if (err == KErrCorrupt)
1.868 + {
1.869 + __CENTREP_TRACE1("[%S] Invalid write setting",iFullName);
1.870 + }
1.871 +#endif
1.872 + aSetting.PopAndDestroy();
1.873 + return err;
1.874 + }
1.875 + //else if ret!=KErrNone very likely it is KErrNotFound so leave
1.876 + //the state of the writePolicyFound to EFalse
1.877 + }
1.878 + }
1.879 +
1.880 + //Need to pop back the setting
1.881 + aSetting.Pop();
1.882 + }
1.883 + return error;
1.884 + }
1.885 +
1.886 +TInt CIniFileIn::SkipPlatSecSectionL()
1.887 + {
1.888 + HBufC* platSecSection;
1.889 + TInt r=GetPlatSecSectionLC(platSecSection);
1.890 + if(platSecSection)
1.891 + CleanupStack::PopAndDestroy(platSecSection);
1.892 + return r;
1.893 + }
1.894 +
1.895 +TInt CIniFileIn::SkipOwnerSectionL()
1.896 + {
1.897 + HBufC* ownerSection;
1.898 + TInt r=GetOwnerSectionLC(ownerSection);
1.899 + if(ownerSection)
1.900 + CleanupStack::PopAndDestroy(ownerSection);
1.901 + return r;
1.902 + }
1.903 +
1.904 +TInt CIniFileIn::SkipDefaultMetaSectionL()
1.905 + {
1.906 + HBufC* section;
1.907 + TInt r=GetDefaultMetaSectionLC(section);
1.908 + if(section)
1.909 + CleanupStack::PopAndDestroy(section);
1.910 + return r;
1.911 + }
1.912 +
1.913 +TInt CIniFileIn::SkipTimeStampSectionL()
1.914 + {
1.915 + HBufC* timeStampSection;
1.916 + TInt r=GetTimeStampSectionLC(timeStampSection);
1.917 + if(timeStampSection)
1.918 + CleanupStack::PopAndDestroy(timeStampSection);
1.919 + return r;
1.920 + }
1.921 +
1.922 +/**
1.923 +Read an entire PlatSec section from ini file
1.924 +and create TSecurityPolicy for default access and for range of indexes
1.925 +
1.926 +@internalTechnology
1.927 +@return KErrNone, KErrCorrupt or KErrNotFound
1.928 +*/
1.929 +TInt CIniFileIn::ReadPlatSecSectionL(TSecurityPolicy& aDefaultReadPolicy, TBool& aGotDefaultReadPolicy,
1.930 + TSecurityPolicy& aDefaultWritePolicy, TBool& aGotDefaultWritePolicy,
1.931 + RRangePolicyArray& aRangePolicies)
1.932 +
1.933 + {
1.934 + TBuf<KBufLen> buf;
1.935 +
1.936 + aGotDefaultReadPolicy = EFalse ;
1.937 + aGotDefaultWritePolicy = EFalse ;
1.938 +
1.939 + //
1.940 + // Check if the PlatSec section is present
1.941 + //
1.942 + SkipComments();
1.943 +
1.944 + // we will need this section later to write the out file...
1.945 + iLex.Mark(iMainSectionMark);
1.946 +
1.947 + iLex.Mark();
1.948 + iLex.SkipCharacters();
1.949 +
1.950 + if( iLex.TokenLength()!=KPlatSecSectionLen ||
1.951 + (buf.CopyLC( iLex.MarkedToken() ), buf.Compare( KPlatSecSection )!=0) )
1.952 + {
1.953 + // PlatSec section not available
1.954 + iLex.UnGetToMark();
1.955 + return KErrNotFound;
1.956 + }
1.957 +
1.958 + //
1.959 + // Lets read the policies
1.960 + //
1.961 +
1.962 + SkipComments();
1.963 + TInt r=KErrNone;
1.964 + // we might have a default policies first
1.965 + // check for default read policy
1.966 + r=ReadRdPolicyL(aDefaultReadPolicy);
1.967 + if (r==KErrNone)
1.968 + aGotDefaultReadPolicy=ETrue;
1.969 + else
1.970 + {
1.971 + //we need to return error code rather than assuming no default policy is found
1.972 + if (r==KErrCorrupt || r==KErrNoMemory)
1.973 + {
1.974 +#ifdef CENTREP_TRACE
1.975 + if (r == KErrCorrupt)
1.976 + {
1.977 + __CENTREP_TRACE1("[%S] Invalid read policy [platsec]",iFullName);
1.978 + }
1.979 +#endif
1.980 + return r;
1.981 + }
1.982 + //else if ret!=KErrNone very likely it is KErrNotFound so leave
1.983 + //the state of the writePolicyFound to EFalse
1.984 + }
1.985 + // check for default write policy
1.986 + r=ReadWrPolicyL(aDefaultWritePolicy);
1.987 + if (r==KErrNone)
1.988 + aGotDefaultWritePolicy=ETrue;
1.989 + else
1.990 + {
1.991 + //we need to return error code rather than assuming no default policy is found
1.992 + if (r==KErrCorrupt || r==KErrNoMemory)
1.993 + {
1.994 +#ifdef CENTREP_TRACE
1.995 + if (r == KErrCorrupt)
1.996 + {
1.997 + __CENTREP_TRACE1("[%S] Invalid write policy [platsec]",iFullName);
1.998 + }
1.999 +#endif
1.1000 + return r;
1.1001 + }
1.1002 + //else if ret!=KErrNone very likely it is KErrNotFound so leave
1.1003 + //the state of the writePolicyFound to EFalse
1.1004 + }
1.1005 + // now lets try range policies
1.1006 + r = ReadRangePoliciesL(aDefaultReadPolicy,aDefaultWritePolicy,aRangePolicies);
1.1007 + if(r!=KErrNone)
1.1008 + {
1.1009 + __CENTREP_TRACE1("[%S] Invalid range policy [platsec]",iFullName);
1.1010 + return KErrCorrupt;
1.1011 + }
1.1012 + // it must be the main section now so lets check
1.1013 + SkipComments();
1.1014 + iLex.Mark();
1.1015 + iLex.SkipCharacters();
1.1016 +
1.1017 + if(iLex.TokenLength()>KBufLen)
1.1018 + return KErrCorrupt;
1.1019 +
1.1020 + buf.CopyLC(iLex.MarkedToken());
1.1021 + if(buf.Compare(KMainSection)!=0)
1.1022 + {
1.1023 + return KErrCorrupt;
1.1024 + }
1.1025 +
1.1026 + iLex.Mark(iMainSectionMark);
1.1027 +
1.1028 + return KErrNone;
1.1029 + }
1.1030 +
1.1031 +/**
1.1032 +Reads TSecurityPolicy as defined for range of indexes
1.1033 +
1.1034 +@internalTechnology
1.1035 +@return KErrNone, KErrCorrupt
1.1036 +@leave KErrNotFound
1.1037 +*/
1.1038 +TInt CIniFileIn::ReadRangePoliciesL(const TSecurityPolicy& aDefaultReadPolicy,
1.1039 + const TSecurityPolicy& aDefaultWritePolicy,
1.1040 + RRangePolicyArray& aRangePolicies)
1.1041 +{
1.1042 + TUint32 lowKey = 0;
1.1043 + TBuf<KBufLen> buf;
1.1044 +
1.1045 + SkipComments();
1.1046 + while(KErrNone == ReadNumber(lowKey))
1.1047 + {
1.1048 + // highKey and mask needs to be zero'd every cycle...
1.1049 + TUint32 highKey = 0;
1.1050 + TUint32 mask = 0;
1.1051 + iLex.SkipSpace();
1.1052 + // may be not range but key & mask so lets check 'mask' keyword
1.1053 + if(!iLex.Peek().IsDigit())
1.1054 + {
1.1055 + //so should be mask then...
1.1056 + iLex.Mark();
1.1057 + while((iLex.Peek()!='=')&&(!iLex.Eos()))
1.1058 + {
1.1059 + iLex.Inc();
1.1060 +
1.1061 + if(iLex.TokenLength() >= KMaskLen)
1.1062 + {
1.1063 + // so no '=' there
1.1064 + // not necessarily bad thing... could be space there first
1.1065 + break;
1.1066 + }
1.1067 +
1.1068 + }
1.1069 +
1.1070 + // check if KMaskLen is < buf length?
1.1071 + buf.CopyLC(iLex.MarkedToken());
1.1072 + if(buf.Compare(KMaskString)!=0)
1.1073 + {
1.1074 + __CENTREP_TRACE1("[%S] Missing 'mask' keyword for range [platsec]",iFullName);
1.1075 + return KErrCorrupt;
1.1076 + }
1.1077 +
1.1078 + iLex.SkipSpace();
1.1079 + if('=' != iLex.Get())
1.1080 + {
1.1081 + __CENTREP_TRACE1("[%S] Missing '=' for 'mask' keyword for range [platsec]",iFullName);
1.1082 + return KErrCorrupt;
1.1083 + }
1.1084 + iLex.SkipSpace();
1.1085 + TInt r = ReadNumberL(iLex,mask);
1.1086 + if(r!=KErrNone)
1.1087 + {
1.1088 + __CENTREP_TRACE1("[%S] Invalid value for 'mask' keyword [platsec]",iFullName);
1.1089 + return KErrCorrupt;
1.1090 + }
1.1091 + }
1.1092 + else
1.1093 + {
1.1094 + TInt r = ReadNumberL(iLex,highKey);
1.1095 + if(r!=KErrNone)
1.1096 + {
1.1097 + __CENTREP_TRACE1("[%S] Invalid end of range [platsec]",iFullName);
1.1098 + return KErrCorrupt;
1.1099 + }
1.1100 + }
1.1101 + TBool writePolicyFound = EFalse;
1.1102 + TBool readPolicyFound= EFalse;
1.1103 + TSecurityPolicy readPolicy;
1.1104 + TSecurityPolicy writePolicy;
1.1105 +
1.1106 + TInt ret=KErrNone;
1.1107 + ret=ReadRdPolicyL(readPolicy);
1.1108 + if (ret==KErrNone)
1.1109 + readPolicyFound=ETrue;
1.1110 + else
1.1111 + {
1.1112 + if (ret==KErrCorrupt || ret==KErrNoMemory)
1.1113 + {
1.1114 +#ifdef CENTREP_TRACE
1.1115 + if (ret == KErrCorrupt)
1.1116 + {
1.1117 + __CENTREP_TRACE1("[%S] Invalid read policy for range [platsec]",iFullName);
1.1118 + }
1.1119 +#endif
1.1120 + return ret;
1.1121 + }
1.1122 + //else if ret!=KErrNone very likely it is KErrNotFound so leave
1.1123 + //the state of the writePolicyFound to EFalse
1.1124 + }
1.1125 + ret=ReadWrPolicyL(writePolicy);
1.1126 + if (ret==KErrNone)
1.1127 + writePolicyFound=ETrue;
1.1128 + else
1.1129 + {
1.1130 + if (ret==KErrCorrupt || ret==KErrNoMemory)
1.1131 + {
1.1132 +#ifdef CENTREP_TRACE
1.1133 + if (ret == KErrCorrupt)
1.1134 + {
1.1135 + __CENTREP_TRACE1("[%S] Invalid write policy for range [platsec]",iFullName);
1.1136 + }
1.1137 +#endif
1.1138 + return ret;
1.1139 + }
1.1140 + //else if ret!=KErrNone very likely it is KErrNotFound so leave
1.1141 + //the state of the writePolicyFound to EFalse
1.1142 + }
1.1143 + //If only one of the policy is specified,need to set the other one to default value
1.1144 + //to prevent it from being uninitialized
1.1145 + if(readPolicyFound || writePolicyFound)
1.1146 + {
1.1147 + if (!readPolicyFound)
1.1148 + readPolicy=aDefaultReadPolicy;
1.1149 + if (!writePolicyFound)
1.1150 + writePolicy=aDefaultWritePolicy;
1.1151 + TSettingsAccessPolicy settingsPolicy(readPolicy,writePolicy,
1.1152 + lowKey, highKey, mask);
1.1153 + aRangePolicies.AppendL(settingsPolicy);
1.1154 + }
1.1155 + else
1.1156 + {
1.1157 + // range specified with no policies!
1.1158 + __CENTREP_TRACE1("[%S] Range specified with no policies [platsec]",iFullName);
1.1159 + return KErrCorrupt;
1.1160 + }
1.1161 + SkipComments();
1.1162 + }
1.1163 + return KErrNone;
1.1164 +}
1.1165 +
1.1166 +/**
1.1167 +@internalTechnology
1.1168 +@return TCapability as converted from string description
1.1169 +@leave KErrNotFound
1.1170 +*/
1.1171 +TInt CIniFileIn::ReadCapabilityL(TCapability& aCapability)
1.1172 + {
1.1173 + iLex.SkipSpace();
1.1174 +
1.1175 + if(iLex.Eos())
1.1176 + User::Leave(KErrNotFound);
1.1177 +
1.1178 + // check if '=' still there and skip
1.1179 + SkipEqualSign();
1.1180 +
1.1181 + iLex.Mark();
1.1182 +
1.1183 + // potentially comma separated list of capabilities
1.1184 + // we read just one at the time
1.1185 + while(!iLex.Peek().IsSpace() && (iLex.Peek() != ',') && !iLex.Eos())
1.1186 + {
1.1187 + iLex.Inc();
1.1188 + if(iLex.TokenLength()>KMaxCapabilityStringLen)
1.1189 + {
1.1190 + __CENTREP_TRACE1("[%S] Invalid capability [platsec]",iFullName);
1.1191 + return KErrCorrupt;
1.1192 + }
1.1193 + }
1.1194 +
1.1195 + TBuf<KMaxCapabilityStringLen> string;
1.1196 + string.CopyLC(iLex.MarkedToken());
1.1197 +
1.1198 + // lets check against list of capabilities
1.1199 + TInt capability;
1.1200 +
1.1201 + // descriptors...desriptors - we need it for conversion from const char[] to TPtr
1.1202 + HBufC *cap = HBufC::NewLC(KMaxCapabilityStringLen);
1.1203 + TPtr capPtr = cap->Des() ;
1.1204 + HBufC8 *capNarrow = HBufC8::NewLC(KMaxCapabilityStringLen) ;
1.1205 + for(capability=0; capability<ECapability_Limit; capability++)
1.1206 + {
1.1207 + // CapabilityNames is const char[]
1.1208 + *capNarrow = (const TUint8 *)CapabilityNames[capability];
1.1209 +
1.1210 + capPtr.Copy(*capNarrow);
1.1211 + capPtr.LowerCase();
1.1212 + if(0 == string.Compare(capPtr))
1.1213 + {
1.1214 + aCapability=static_cast<TCapability>(capability);
1.1215 + CleanupStack::PopAndDestroy(capNarrow);
1.1216 + CleanupStack::PopAndDestroy(cap);
1.1217 + return KErrNone;
1.1218 + }
1.1219 + }
1.1220 + CleanupStack::PopAndDestroy(capNarrow);
1.1221 + CleanupStack::PopAndDestroy(cap);
1.1222 +
1.1223 + // to satisfy compiler
1.1224 + aCapability=ECapability_Limit;
1.1225 +
1.1226 + __CENTREP_TRACE1("[%S] Invalid capability [platsec]",iFullName);
1.1227 + // we didn't find anything
1.1228 + return KErrCorrupt;
1.1229 +
1.1230 + }
1.1231 +
1.1232 +/**
1.1233 +@internalTechnology
1.1234 +@param aAlwaysPass will be true if the first capability is AlwaysPass
1.1235 + aAlwaysFail will be true if the first capability is AlwaysFail
1.1236 +*/
1.1237 +void CIniFileIn::CheckForAlwaysPassOrFailL(TBool& aAlwaysPass,TBool& aAlwaysFail)
1.1238 + {
1.1239 + iLex.SkipSpace();
1.1240 +
1.1241 + if(iLex.Eos())
1.1242 + User::Leave(KErrNotFound);
1.1243 +
1.1244 + // check if '=' still there and skip
1.1245 + SkipEqualSign();
1.1246 +
1.1247 + iLex.Mark();
1.1248 + // we are just checking if AlwaysPass has been set
1.1249 + while(!iLex.Peek().IsSpace() && !iLex.Eos())
1.1250 + {
1.1251 + iLex.Inc();
1.1252 + if(iLex.TokenLength()>KMaxCapabilityStringLen)
1.1253 + {
1.1254 + iLex.UnGetToMark();
1.1255 + return;
1.1256 + }
1.1257 +
1.1258 + }
1.1259 +
1.1260 + TBuf<KMaxCapabilityStringLen> string;
1.1261 + string.CopyLC(iLex.MarkedToken());
1.1262 +
1.1263 + aAlwaysPass=(string.Compare(KAccessAlwaysPass)==0);
1.1264 + aAlwaysFail=(string.Compare(KAccessAlwaysFail)==0);
1.1265 + //if not either AlwaysPass or AlwaysFail reset the Lex position to Mark
1.1266 + if(!(aAlwaysPass || aAlwaysFail))
1.1267 + iLex.UnGetToMark();
1.1268 + }
1.1269 +
1.1270 +TInt CIniFileIn::ReadCapabilitiesL(TSecurityPolicy& aPolicy)
1.1271 + {
1.1272 + // we can have 0-7 capabilities
1.1273 + const TInt maxCapWithoutSid = 7;
1.1274 + TCapability capabilities[maxCapWithoutSid];
1.1275 + TInt index = 0;
1.1276 + // initialise
1.1277 + for(index=0;index<maxCapWithoutSid;index++)
1.1278 + capabilities[index] = ECapability_None;
1.1279 +
1.1280 + index = 0;
1.1281 +
1.1282 + // lets read the first capability... there must be at least one!
1.1283 + TBool isAlwaysPass=EFalse;
1.1284 + TBool isAlwaysFail=EFalse;
1.1285 + CheckForAlwaysPassOrFailL(isAlwaysPass,isAlwaysFail);
1.1286 + if(isAlwaysPass || isAlwaysFail)
1.1287 + {
1.1288 + //default is set to EAlwaysFail
1.1289 + TSecurityPolicy policy;
1.1290 + if (isAlwaysPass)
1.1291 + policy=TSecurityPolicy(TSecurityPolicy::EAlwaysPass);
1.1292 + aPolicy.Set(policy.Package());
1.1293 + }
1.1294 + else
1.1295 + {
1.1296 + TInt r=ReadCapabilityL(capabilities[index]);
1.1297 + if(r!=KErrNone)
1.1298 + return r;
1.1299 +
1.1300 + // do we have more?
1.1301 + iLex.SkipSpace();
1.1302 + index++;
1.1303 + while((iLex.Peek() == ','))
1.1304 + {
1.1305 + //if capabilities supplied is more than allowed return KErrCorrupt
1.1306 + if (index>=maxCapWithoutSid)
1.1307 + {
1.1308 + __CENTREP_TRACE1("[%S] Too many read capabilities [platsec]",iFullName);
1.1309 + return KErrCorrupt;
1.1310 + }
1.1311 + // skip comma
1.1312 + iLex.SkipAndMark(1);
1.1313 + r=ReadCapabilityL(capabilities[index]);
1.1314 + if(r!=KErrNone)
1.1315 + return r;
1.1316 + // do we have yet more?
1.1317 + iLex.SkipSpace();
1.1318 + index++;
1.1319 + }
1.1320 + TSecurityPolicy policy(static_cast<TCapability>(capabilities[0]),
1.1321 + static_cast<TCapability>(capabilities[1]),
1.1322 + static_cast<TCapability>(capabilities[2]),
1.1323 + static_cast<TCapability>(capabilities[3]),
1.1324 + static_cast<TCapability>(capabilities[4]),
1.1325 + static_cast<TCapability>(capabilities[5]),
1.1326 + static_cast<TCapability>(capabilities[6]));
1.1327 + aPolicy.Set(policy.Package());
1.1328 + }
1.1329 + return KErrNone;
1.1330 + }
1.1331 +
1.1332 +TInt CIniFileIn::ReadSidAndCapabilitiesL(TSecurityPolicy& aPolicy,const TDesC& aPolicyType,
1.1333 + TSecureId& aSid)
1.1334 + {
1.1335 + //SID was specified we can have 0-3 capabilities
1.1336 + const TInt maxCapWithSid = 3;
1.1337 +
1.1338 + TCapability capabilities[maxCapWithSid];
1.1339 + TInt index = 0;
1.1340 + for(index=0;index<maxCapWithSid;index++)
1.1341 + capabilities[index] = ECapability_None;
1.1342 +
1.1343 + // lets see what we have here...
1.1344 + iLex.SkipSpaceAndMark();
1.1345 +
1.1346 + // we are looking for a string terminated by '='
1.1347 + // up to a certain length....
1.1348 + while((iLex.Peek()!='=')&&(!iLex.Eos()))
1.1349 + {
1.1350 + iLex.Inc();
1.1351 +
1.1352 + if(iLex.TokenLength() >= KMaxAccessTypeLen)
1.1353 + {
1.1354 + // so no '=' there
1.1355 + // not necessarily bad thing... could be space there first
1.1356 + break;
1.1357 + }
1.1358 +
1.1359 + }
1.1360 +
1.1361 + TBuf<KMaxAccessTypeLen> string;
1.1362 + string.CopyLC(iLex.MarkedToken());
1.1363 +
1.1364 + index = 0;
1.1365 + // lets check if there are any capabilities specified and if of correct type
1.1366 + if(0 == string.Compare(aPolicyType))
1.1367 + {
1.1368 + //Need to check for AlwaysPass or AlwaysFail
1.1369 + TBool isAlwaysPass=EFalse;
1.1370 + TBool isAlwaysFail=EFalse;
1.1371 + CheckForAlwaysPassOrFailL(isAlwaysPass,isAlwaysFail);
1.1372 + if(isAlwaysPass || isAlwaysFail)
1.1373 + {
1.1374 + //default is set to EAlwaysFail
1.1375 + TSecurityPolicy policy;
1.1376 + if (isAlwaysPass)
1.1377 + policy=TSecurityPolicy(TSecurityPolicy::EAlwaysPass);
1.1378 + aPolicy.Set(policy.Package());
1.1379 + }
1.1380 + else
1.1381 + {
1.1382 + // so we have some capabilities to read
1.1383 + TInt r = ReadCapabilityL(capabilities[index]);
1.1384 + if(r!=KErrNone)
1.1385 + return r;
1.1386 + // do we have more?
1.1387 + iLex.SkipSpace();
1.1388 + index++;
1.1389 + while((iLex.Peek() == ','))
1.1390 + {
1.1391 + //cannot permit more than 3 capabilities when followed by a SID
1.1392 + if (index>=maxCapWithSid)
1.1393 + {
1.1394 + __CENTREP_TRACE1("[%S] Too many read capabilities [platsec]",iFullName);
1.1395 + return KErrCorrupt;
1.1396 + }
1.1397 + // skip comma
1.1398 + iLex.SkipAndMark(1);
1.1399 + TInt r= ReadCapabilityL(capabilities[index]);
1.1400 + if(r!=KErrNone)
1.1401 + return r;
1.1402 + // do we have yet more?
1.1403 + iLex.SkipSpace();
1.1404 + index++;
1.1405 + }
1.1406 + TSecurityPolicy policy(aSid,static_cast<TCapability>(capabilities[0]),
1.1407 + static_cast<TCapability>(capabilities[1]),
1.1408 + static_cast<TCapability>(capabilities[2]));
1.1409 + aPolicy.Set(policy.Package());
1.1410 + }
1.1411 + }
1.1412 + else
1.1413 + {
1.1414 + // so no capabilities just SID
1.1415 + // and the token wasn't for us either
1.1416 + iLex.UnGetToMark();
1.1417 + TSecurityPolicy policy(aSid);
1.1418 + aPolicy.Set(policy.Package());
1.1419 + }
1.1420 + return KErrNone;
1.1421 + }
1.1422 +
1.1423 +
1.1424 +TInt CIniFileIn::ReadPolicyL(TSecurityPolicy& aPolicy,TInt aPolicyType)
1.1425 + {
1.1426 +
1.1427 + // lets check if there a SID is specified
1.1428 + iLex.SkipSpaceAndMark();
1.1429 +
1.1430 + if(iLex.Eos())
1.1431 + return KErrNotFound;
1.1432 +
1.1433 + while((iLex.Peek()!='=')&&(!iLex.Eos()))
1.1434 + {
1.1435 + iLex.Inc();
1.1436 +
1.1437 + if(iLex.TokenLength() >= KMaxAccessTypeLen)
1.1438 + {
1.1439 + // so no '=' there
1.1440 + // not necessarily bad thing... could be space there first
1.1441 + break;
1.1442 + }
1.1443 +
1.1444 + }
1.1445 +
1.1446 + // we are looking for either KReadAccessSid, KReadAccessCap, KWriteAccessSid,KWriteAccessCap
1.1447 + TBuf<KMaxAccessTypeLen> accessString;
1.1448 + accessString.CopyLC(iLex.MarkedToken());
1.1449 + iLex.SkipSpace();
1.1450 + TInt returnCode = KErrNotFound;
1.1451 + // we expect a combination of sid_rd1 cap_rd1 sid_wr1 cap_wr1
1.1452 + if(accessString.Compare(KReadAccessSidString)==0)
1.1453 + {
1.1454 + // we've got read - either SID or SID+CAP! Are we expecting read?
1.1455 + if(KReadPolicy == aPolicyType)
1.1456 + {
1.1457 + TUint32 sid;
1.1458 + SkipEqualSign();
1.1459 + if (ReadNumber(sid) != KErrNone)
1.1460 + {
1.1461 + __CENTREP_TRACE1("[%S] Invalid SID (read)[platsec]",iFullName);
1.1462 + return KErrCorrupt;
1.1463 + }
1.1464 + TSecureId sidId(sid);
1.1465 + // so we read sid and now we expect cap_rd1=cap1,cap2,..
1.1466 + // lets assume it's a SID+CAP for now
1.1467 + returnCode= ReadSidAndCapabilitiesL(aPolicy,KReadAccessCapString,sidId);
1.1468 + }
1.1469 + }
1.1470 + else if(accessString.Compare(KReadAccessCapString)==0)
1.1471 + {
1.1472 + // we've got read CAP only! Are we expecting read?
1.1473 + if(KReadPolicy == aPolicyType)
1.1474 + {
1.1475 + returnCode=ReadCapabilitiesL(aPolicy);
1.1476 + }
1.1477 + }
1.1478 + else if(accessString.Compare(KWriteAccessSidString)==0)
1.1479 + {
1.1480 + // we've got write - either SID or SID+CAP! Are we expecting read?
1.1481 + if(KWritePolicy == aPolicyType)
1.1482 + {
1.1483 + TUint32 sid;
1.1484 + SkipEqualSign();
1.1485 + if(ReadNumber(sid)!=KErrNone)
1.1486 + {
1.1487 + __CENTREP_TRACE1("[%S] Invalid SID (write)[platsec]",iFullName);
1.1488 + return KErrCorrupt;
1.1489 + }
1.1490 + TSecureId sidId(sid);
1.1491 + // lets assume SID+CAP for now
1.1492 + returnCode= ReadSidAndCapabilitiesL(aPolicy,KWriteAccessCapString,sidId);
1.1493 + }
1.1494 + }
1.1495 + else if(accessString.Compare(KWriteAccessCapString)==0)
1.1496 + {
1.1497 + // we've got write CAP only! Are we expecting write?
1.1498 + if(KWritePolicy == aPolicyType)
1.1499 + {
1.1500 + returnCode=ReadCapabilitiesL(aPolicy);
1.1501 + }
1.1502 + }
1.1503 + if(KErrNone != returnCode)
1.1504 + iLex.UnGetToMark();
1.1505 +
1.1506 + return returnCode;
1.1507 + }
1.1508 +
1.1509 +TInt CIniFileIn::ReadRdPolicyL(TSecurityPolicy& aReadPolicy)
1.1510 + {
1.1511 + return ReadPolicyL(aReadPolicy,KReadPolicy);
1.1512 + }
1.1513 +
1.1514 +TInt CIniFileIn::ReadWrPolicyL(TSecurityPolicy& aReadPolicy)
1.1515 + {
1.1516 + return ReadPolicyL(aReadPolicy,KWritePolicy);
1.1517 + }
1.1518 +
1.1519 +TInt CIniFileIn::ReadStringL(HBufC8*& aString)
1.1520 + {
1.1521 + iLex.Mark();
1.1522 +
1.1523 + TChar c = iLex.Peek();
1.1524 + TChar quote = 0;
1.1525 + if(c=='\'' || c=='\"')
1.1526 + {
1.1527 + iLex.SkipAndMark(1);
1.1528 + quote = c;
1.1529 + }
1.1530 +
1.1531 + TBool complete = EFalse;
1.1532 +
1.1533 + TInt len;
1.1534 + for(len=0;!iLex.Eos();len++)
1.1535 + {
1.1536 + c = iLex.Get();
1.1537 +
1.1538 + if(quote ? c==quote : c.IsSpace())
1.1539 + {
1.1540 + complete = ETrue;
1.1541 + break;
1.1542 + }
1.1543 +
1.1544 + if(c=='\\')
1.1545 + iLex.Get();
1.1546 + }
1.1547 +
1.1548 + if(!complete || len>KMaxUnicodeStringLength)
1.1549 + return KErrCorrupt;
1.1550 +
1.1551 + aString = HBufC8::NewL(len*2);
1.1552 + TPtr8 ptr8 = aString->Des();
1.1553 + ptr8.SetLength(len*2);
1.1554 + TPtr16 ptr16((TUint16*)ptr8.Ptr(), len, len);
1.1555 +
1.1556 +
1.1557 + iLex.UnGetToMark();
1.1558 +
1.1559 + _LIT(KSpecialChars, "abfnrvt0");
1.1560 + static TUint8 specialChars[] = { '\a', '\b', '\f', '\n', '\r', '\v', '\t', '\0' };
1.1561 + for(TInt i=0;i<len;i++)
1.1562 + {
1.1563 + c = iLex.Get();
1.1564 +
1.1565 + if(c=='\\')
1.1566 + {
1.1567 + c = iLex.Get();
1.1568 + TInt i = KSpecialChars().Locate(c);
1.1569 + if(i>=0)
1.1570 + c = specialChars[i];
1.1571 + }
1.1572 +
1.1573 + ptr16[i] = (TUint16)c;
1.1574 +
1.1575 + }
1.1576 +
1.1577 + if(quote)
1.1578 + iLex.Inc(); // trailing quote
1.1579 +
1.1580 + return KErrNone;
1.1581 + }
1.1582 +
1.1583 +
1.1584 +
1.1585 +TInt CIniFileIn::ReadString16To8L(HBufC8*& aString)
1.1586 + {
1.1587 + iLex.Mark();
1.1588 +
1.1589 + TChar c = iLex.Peek();
1.1590 + TChar quote = 0;
1.1591 + if(c=='\'' || c=='\"')
1.1592 + {
1.1593 + iLex.SkipAndMark(1);
1.1594 + quote = c;
1.1595 + }
1.1596 +
1.1597 + TBool complete = EFalse;
1.1598 +
1.1599 + TInt len;
1.1600 + for(len=0;!iLex.Eos();len++)
1.1601 + {
1.1602 + c = iLex.Get();
1.1603 +
1.1604 + if(quote ? c==quote : c.IsSpace())
1.1605 + {
1.1606 + complete = ETrue;
1.1607 + break;
1.1608 + }
1.1609 +
1.1610 + if(c=='\\')
1.1611 + iLex.Get();
1.1612 + }
1.1613 +
1.1614 + if(!complete || len>KMaxUnicodeStringLength)
1.1615 + return KErrCorrupt;
1.1616 +
1.1617 + aString = HBufC8::NewLC(len*2);
1.1618 +
1.1619 + HBufC16* tempBuffer = HBufC16::NewLC(len);
1.1620 +
1.1621 + TPtr16 ptr16 = tempBuffer->Des();
1.1622 + TPtr8 ptr8 = aString->Des();
1.1623 + ptr8.SetLength(len*2);
1.1624 +
1.1625 +
1.1626 +
1.1627 + iLex.UnGetToMark();
1.1628 +
1.1629 + _LIT(KSpecialChars, "abfnrvt0");
1.1630 + static TUint8 specialChars[] = { '\a', '\b', '\f', '\n', '\r', '\v', '\t', '\0' };
1.1631 + for(TInt i=0;i<len;i++)
1.1632 + {
1.1633 + c = iLex.Get();
1.1634 +
1.1635 + if(c=='\\')
1.1636 + {
1.1637 + c = iLex.Get();
1.1638 + TInt i = KSpecialChars().Locate(c);
1.1639 + if(i>=0)
1.1640 + c = specialChars[i];
1.1641 + }
1.1642 +
1.1643 + ptr16.Append(c);
1.1644 +
1.1645 + }
1.1646 +
1.1647 + const TInt returnValue = CnvUtfConverter::ConvertFromUnicodeToUtf8(ptr8, ptr16);
1.1648 + if (returnValue==CnvUtfConverter::EErrorIllFormedInput)
1.1649 + {
1.1650 + CleanupStack::PopAndDestroy(tempBuffer);
1.1651 + CleanupStack::PopAndDestroy(aString);
1.1652 + return KErrCorrupt;
1.1653 + }
1.1654 + else if(returnValue<0)
1.1655 + User::Leave(KErrGeneral);
1.1656 +
1.1657 + CleanupStack::PopAndDestroy(tempBuffer);
1.1658 + CleanupStack::Pop(aString);
1.1659 +
1.1660 + if(quote)
1.1661 + iLex.Inc(); // trailing quote
1.1662 +
1.1663 + return KErrNone;
1.1664 + }
1.1665 +
1.1666 +TInt CIniFileIn::ReadBinaryL(HBufC8*& aString)
1.1667 + {
1.1668 + iLex.Mark();
1.1669 + iLex.SkipCharacters();
1.1670 + TInt len = iLex.TokenLength();
1.1671 + iLex.UnGetToMark();
1.1672 +
1.1673 + if(len==1 && iLex.Peek()==KNullDataIndicator)
1.1674 + {
1.1675 + iLex.Get();
1.1676 + aString = HBufC8::NewL(0);
1.1677 + TPtr8 ptr8 = aString->Des();
1.1678 + ptr8.SetLength(0);
1.1679 + return KErrNone;
1.1680 + }
1.1681 +
1.1682 + if(len>KMaxBinaryLength*2 || len%2)
1.1683 + {
1.1684 + delete aString;
1.1685 + return KErrCorrupt;
1.1686 + }
1.1687 +
1.1688 + len /= 2;
1.1689 + aString = HBufC8::NewL(len);
1.1690 + TPtr8 ptr8 = aString->Des();
1.1691 + ptr8.SetLength(len);
1.1692 +
1.1693 + TBuf<2> buf(2);
1.1694 + for(TInt i=0;i<len;i++)
1.1695 + {
1.1696 + buf[0] = (TUint8)iLex.Get();
1.1697 + buf[1] = (TUint8)iLex.Get();
1.1698 + TLex lex(buf);
1.1699 + if(lex.Val(ptr8[i], EHex)!=KErrNone)
1.1700 + {
1.1701 + delete aString;
1.1702 + return KErrCorrupt;
1.1703 + }
1.1704 + }
1.1705 + return KErrNone;
1.1706 + }
1.1707 +
1.1708 +TInt CIniFileIn::ReadNumber(TUint32& aVal)
1.1709 + {
1.1710 + iLex.SkipSpace();
1.1711 +
1.1712 + if(iLex.Eos())
1.1713 + return KErrNotFound;
1.1714 +
1.1715 + TRadix radix = EDecimal;
1.1716 + if(iLex.Peek()=='0')
1.1717 + {
1.1718 + iLex.Inc();
1.1719 + if(iLex.Peek().GetLowerCase()=='x')
1.1720 + {
1.1721 + iLex.Inc();
1.1722 + radix = EHex;
1.1723 + }
1.1724 + else
1.1725 + iLex.UnGet();
1.1726 + }
1.1727 +
1.1728 + return iLex.Val(aVal, radix);
1.1729 + }
1.1730 +
1.1731 +
1.1732 +TInt CIniFileIn::GetOwnerSectionLC(HBufC*& aSection)
1.1733 + {
1.1734 + return( GetSectionLC(KOwnerSection(), aSection));
1.1735 + }
1.1736 +
1.1737 +TInt CIniFileIn::GetDefaultMetaSectionLC(HBufC*& aSection)
1.1738 + {
1.1739 + return( GetSectionLC(KDefaultMetaSection(), aSection));
1.1740 + }
1.1741 +
1.1742 +TInt CIniFileIn::GetTimeStampSectionLC(HBufC*& aSection)
1.1743 + {
1.1744 + return( GetSectionLC(KTimeStampSection(), aSection));
1.1745 + }
1.1746 +
1.1747 +TInt CIniFileIn::GetPlatSecSectionLC(HBufC*& aSection)
1.1748 + {
1.1749 + return( GetSectionLC(KPlatSecSection(), aSection));
1.1750 + }
1.1751 +
1.1752 +TInt CIniFileIn::GetSectionLC(const TDesC16& aSectionId, HBufC*& aSection)
1.1753 + {
1.1754 + TBuf<KBufLen> buf;
1.1755 + TLexMark sectionMark;
1.1756 + aSection=NULL;
1.1757 +
1.1758 + SkipComments();
1.1759 +
1.1760 + iLex.Mark(sectionMark);
1.1761 +
1.1762 + iLex.Mark();
1.1763 + iLex.SkipCharacters();
1.1764 +
1.1765 + if( (iLex.TokenLength() != aSectionId.Length()) &&
1.1766 + (buf.CopyLC(iLex.MarkedToken()), buf.Compare( aSectionId )!=0) )
1.1767 + {
1.1768 + // Expected section not found at this point in the file
1.1769 + // Note that this is not an error
1.1770 + iLex.UnGetToMark();
1.1771 + return KErrNone;
1.1772 + }
1.1773 +
1.1774 + //
1.1775 + // Read in the section by grabbing text until we reach
1.1776 + // the start of another section.
1.1777 + //
1.1778 + while(!iLex.Eos())
1.1779 + {
1.1780 + // Wait for any other section marker
1.1781 + SkipComments();
1.1782 +
1.1783 + iLex.Mark();
1.1784 +
1.1785 + iLex.SkipCharacters();
1.1786 +
1.1787 + if(iLex.TokenLength() <= KBufLen)
1.1788 + {
1.1789 + buf.CopyLC(iLex.MarkedToken());
1.1790 + if((buf.Compare(KMainSection) == 0) ||
1.1791 + (buf.Compare(KOwnerSection) == 0) ||
1.1792 + (buf.Compare(KPlatSecSection) == 0) ||
1.1793 + (buf.Compare(KTimeStampSection) == 0) ||
1.1794 + (buf.Compare(KDefaultMetaSection) == 0))
1.1795 + {
1.1796 + iLex.Mark(iMainSectionMark);
1.1797 + iLex.UnGetToMark() ;
1.1798 + TPtrC lex = iLex.MarkedToken(sectionMark);
1.1799 + HBufC* section = HBufC::NewMaxLC(lex.Length()); //'\n'
1.1800 + TPtr ptr = section->Des();
1.1801 + ptr.Copy(lex);
1.1802 + aSection=section;
1.1803 + return KErrNone;
1.1804 + }
1.1805 + }
1.1806 + }
1.1807 + return KErrCorrupt;
1.1808 + }
1.1809 +
1.1810 +TInt CIniFileIn::FindMainSectionL(void)
1.1811 + {
1.1812 + TBuf<KBufLen> buf;
1.1813 +
1.1814 + //
1.1815 + // Check if a Main section is present
1.1816 + //
1.1817 +
1.1818 + SkipComments();
1.1819 +
1.1820 + // we will need this section later to write the out file...
1.1821 + iLex.Mark(iMainSectionMark);
1.1822 +
1.1823 + iLex.Mark();
1.1824 + iLex.SkipCharacters();
1.1825 +
1.1826 + if( iLex.TokenLength()!=KMainSectionLen ||
1.1827 + (buf.CopyLC( iLex.MarkedToken() ), buf.Compare( KMainSection )!=0) )
1.1828 + {
1.1829 + // Meta not available
1.1830 + iLex.UnGetToMark();
1.1831 + return KErrNotFound;
1.1832 + }
1.1833 +
1.1834 + iLex.Mark(iMainSectionMark);
1.1835 + return KErrNone ;
1.1836 + }
1.1837 +
1.1838 +#ifdef CENTREP_TRACE
1.1839 +HBufC* CIniFileIn::FullName()
1.1840 + {
1.1841 + return(iFullName);
1.1842 + }
1.1843 +#endif
1.1844 +
1.1845 +#ifdef CENTREP_CONV_TOOL
1.1846 +//===================================================================
1.1847 +// TCompiledSecurityPolicy class
1.1848 +// Used for accessing private data members of TSecurityPolicy. It
1.1849 +// uses the fact that TSecurityPolicy class has a friend whose name
1.1850 +// is TCompiledSecurityPolicy.
1.1851 +// See dbms/tdbms/securitypolicy.h for similar strategy.
1.1852 +//
1.1853 +
1.1854 +// The longest possible security string is one that has 7 capabilities.
1.1855 +static const TInt KSecPolicyStrSize = KMaxCapabilityStringLen * 7 + 10;
1.1856 +
1.1857 +class TCompiledSecurityPolicy
1.1858 + {
1.1859 +public:
1.1860 + TCompiledSecurityPolicy(const TSecurityPolicy& aSecurityPolicy) :
1.1861 + iSecurityPolicy(aSecurityPolicy) { }
1.1862 + const TDesC& TextualizePolicyL(TCapAccessMode aMode);
1.1863 +
1.1864 +private:
1.1865 + enum THeaderType
1.1866 + {
1.1867 + EHdrSecureId,
1.1868 + EHdrCapability
1.1869 + };
1.1870 +
1.1871 + TCapability CapabilityAt(TInt aIndex) const;
1.1872 + void DoCapabilitySection(TInt aMaxNumCaps);
1.1873 + void AppendModeHeader(TCapAccessMode aAccessMode, THeaderType aType);
1.1874 +
1.1875 +private:
1.1876 + const TSecurityPolicy& iSecurityPolicy;
1.1877 + TBuf<KSecPolicyStrSize> iBuf;
1.1878 + };
1.1879 +
1.1880 +/////////////////////////////////////////////////////////////////////////////////////////////////
1.1881 +// CIniFileOut class
1.1882 +/**
1.1883 +Standard, phase-one CIniFileOut instance creation method.
1.1884 +The created CIniFileOut instance will use a temporary text file to store the repository settings.
1.1885 +CIniFileOut::CommitL() should be called at the end to finalize the changes.
1.1886 +@return A pointer to a fully constructed CIniFileOut instance.
1.1887 +@leave System-wide error codes, including KErrNoMemory.
1.1888 +*/
1.1889 +CIniFileOut* CIniFileOut::NewLC(RFs& aFs,const TDesC& aOutFileName)
1.1890 + {
1.1891 + CIniFileOut* inifile = new(ELeave) CIniFileOut(aFs);
1.1892 + CleanupStack::PushL(inifile);
1.1893 + inifile->ConstructL(aOutFileName);
1.1894 + return inifile;
1.1895 + }
1.1896 +
1.1897 +CIniFileOut::CIniFileOut(RFs& aFs)
1.1898 + : iCommited(EFalse), iTransFileBuf(4 * 1024),iFs(aFs)// 4K buffer size
1.1899 + {
1.1900 + }
1.1901 +
1.1902 +/**
1.1903 +Standard, phase-two CIniFileOut instance creation method.
1.1904 +Creates the transaction file.
1.1905 +Initializes transaction file buffer - iTransFileBuf instance.
1.1906 +@leave System-wide error codes, including KErrNoMemory.
1.1907 +*/
1.1908 +void CIniFileOut::ConstructL(const TDesC& aOutFileName)
1.1909 + {
1.1910 + iOutFileName=aOutFileName.AllocL();
1.1911 + _LIT(KTmpExtension,"tmp");
1.1912 + User::LeaveIfError(iTransFilePath.Set(aOutFileName, NULL, &(KTmpExtension())));
1.1913 + User::LeaveIfError(iTransFile.Replace(iFs, iTransFilePath.FullName(), EFileWrite | EFileStreamText));
1.1914 + iTransFileBuf.Attach(iTransFile, 0);
1.1915 + }
1.1916 +
1.1917 +/**
1.1918 +Closes and deletes the transaction file.
1.1919 +If CIniFileOut::CommitL() has not been called prior the destructor call, all the changes
1.1920 +will be lost.
1.1921 +*/
1.1922 +CIniFileOut::~CIniFileOut()
1.1923 + {
1.1924 + if (!iCommited)
1.1925 + {
1.1926 + iTransFileBuf.Close();
1.1927 + // If a debug build - record error
1.1928 + TInt fileDeleteErr=iFs.Delete(iTransFilePath.FullName());
1.1929 + #ifdef _DEBUG
1.1930 + if (fileDeleteErr != KErrNone)
1.1931 + {
1.1932 + RDebug::Print(_L("CIniFileOut::~CIniFileOut - Failed to delete file. Error = %d"), fileDeleteErr);
1.1933 + }
1.1934 + #else
1.1935 + (void)fileDeleteErr;
1.1936 + #endif
1.1937 +
1.1938 + }
1.1939 + delete iOutFileName;
1.1940 + }
1.1941 +
1.1942 +/**
1.1943 +The method writes supplied setting value to the output file.
1.1944 +@param aSetting Setting instance, which value has to be written to the output file.
1.1945 +@param accessPolicies A string descriptor, referencing related to aSetting access policies.
1.1946 +@leave System-wide error codes, including KErrNoMemory.
1.1947 +*/
1.1948 +void CIniFileOut::WriteSettingL(const TServerSetting& aSetting
1.1949 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.1950 + ,TUint32 aCreVersion
1.1951 +#endif
1.1952 + )
1.1953 + {
1.1954 + iBuf.Zero();
1.1955 + DoSettingL(aSetting
1.1956 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.1957 + ,aCreVersion
1.1958 +#endif
1.1959 + );
1.1960 + WriteLineL(iBuf);
1.1961 + }
1.1962 +
1.1963 +void CIniFileOut::WriteSettingL(const TServerSetting& aSetting,
1.1964 + const TSettingsAccessPolicy& aAccessPolicy
1.1965 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.1966 + ,TUint32 aCreVersion
1.1967 +#endif
1.1968 + )
1.1969 + {
1.1970 + iBuf.Zero();
1.1971 + DoSettingL(aSetting
1.1972 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.1973 + ,aCreVersion
1.1974 +#endif
1.1975 + );
1.1976 + iBuf.Append(KSpace);
1.1977 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.1978 + if (aCreVersion<2 || (aCreVersion>=2 && aAccessPolicy.iHighKey!=0))
1.1979 +#endif
1.1980 + AppendSecurityPolicyL(aAccessPolicy.iReadAccessPolicy, ECapReadAccess);
1.1981 + iBuf.Append(KSpace);
1.1982 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.1983 + if (aCreVersion<2 || (aCreVersion>=2 && aAccessPolicy.iKeyMask!=0))
1.1984 +#endif
1.1985 + AppendSecurityPolicyL(aAccessPolicy.iWriteAccessPolicy, ECapWriteAccess);
1.1986 + WriteLineL(iBuf);
1.1987 + }
1.1988 +
1.1989 +void CIniFileOut::DoSettingL(const TServerSetting& aSetting
1.1990 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.1991 + ,TUint32 aCreVersion
1.1992 +#endif
1.1993 + )
1.1994 + {
1.1995 + iBuf.AppendNum(aSetting.Key(), EDecimal);
1.1996 + iBuf.Append(KSpace);
1.1997 +
1.1998 + ::AddSettingValueL(iBuf, aSetting);
1.1999 +
1.2000 + iBuf.Append(KSpace);
1.2001 +
1.2002 + if (!aSetting.Meta())
1.2003 + {
1.2004 + iBuf.AppendNum(0, EDecimal);
1.2005 + }
1.2006 + else
1.2007 + {
1.2008 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.2009 + //need to check on the CRE Version too
1.2010 + TBool isClean=const_cast<TServerSetting&>(aSetting).IsClean();
1.2011 + if (aCreVersion<2 || (aCreVersion>=2 && (aSetting.IsIndividualMeta() || (!aSetting.IsIndividualMeta() && isClean ))))
1.2012 + {
1.2013 + TUint32 metaToWrite=aSetting.Meta();
1.2014 + //special case
1.2015 + if (aCreVersion>=2 && isClean && aSetting.IsIndividualMeta())
1.2016 + {
1.2017 + metaToWrite|=KMetaIndividual;
1.2018 + }
1.2019 + iBuf.AppendFormat(KHexIntFormat, metaToWrite);
1.2020 + }
1.2021 +#else
1.2022 + iBuf.AppendFormat(KHexIntFormat, aSetting.Meta());
1.2023 +#endif
1.2024 + }
1.2025 + }
1.2026 +
1.2027 +/**
1.2028 +The method commits settings file changes.
1.2029 +If the commit operation fails, the existing settings file will stay unchanged.
1.2030 +@leave System-wide error codes.
1.2031 +*/
1.2032 +void CIniFileOut::CommitL()
1.2033 + {
1.2034 + iTransFileBuf.SynchL();
1.2035 + iTransFileBuf.Close();
1.2036 +
1.2037 + User::LeaveIfError(iFs.Replace(iTransFilePath.FullName(),*iOutFileName));
1.2038 +
1.2039 + iCommited = ETrue;
1.2040 + }
1.2041 +
1.2042 +void CIniFileOut::WriteMainSectionHeaderL()
1.2043 + {
1.2044 + WriteLineL(KMainSection());
1.2045 + }
1.2046 +
1.2047 +/**
1.2048 +Writes a text line to the repository file.
1.2049 +@param aData The string which will be written to the file as a single text line
1.2050 +@leave System-wide error codes
1.2051 +*/
1.2052 +void CIniFileOut::WriteLineL(const TDesC& aData)
1.2053 + {
1.2054 + iTransFileBuf.WriteL(reinterpret_cast <const TUint8*> (aData.Ptr()), aData.Size());
1.2055 + iTransFileBuf.WriteL(reinterpret_cast <const TUint8*> (KCrNl().Ptr()), KCrNl().Size());
1.2056 + }
1.2057 +
1.2058 +/**
1.2059 +Writes repository file header.
1.2060 +@leave System-wide error codes
1.2061 +*/
1.2062 +void CIniFileOut::WriteHeaderL()
1.2063 + {
1.2064 + TBuf<64> buf;
1.2065 +
1.2066 + buf.Append(KUcs2Bom);
1.2067 + buf.Append(KSignature);
1.2068 + WriteLineL(buf);
1.2069 +
1.2070 + buf.Zero();
1.2071 + buf.Append(KVersion);
1.2072 + buf.Append(KSpace);
1.2073 + buf.AppendNum(KCurrentVersion);
1.2074 + buf.Append(KCrNl);
1.2075 + WriteLineL(buf);
1.2076 + }
1.2077 +
1.2078 +/**
1.2079 +Writes owner section to repository file.
1.2080 +*/
1.2081 +void CIniFileOut::WriteOwnerSectionL(TUid aOwner)
1.2082 + {
1.2083 + if (aOwner.iUid != 0)
1.2084 + {
1.2085 + WriteLineL(KOwnerSection());
1.2086 + TBuf<32> buf;
1.2087 + buf.Format(KUidFormat, aOwner.iUid);
1.2088 + buf.Append(KCrNl);
1.2089 + WriteLineL(buf);
1.2090 + }
1.2091 + }
1.2092 +
1.2093 +/**
1.2094 +Writes time stamp to repository file.
1.2095 +@param aTime Time stamp
1.2096 +@leave System-wide error codes
1.2097 +*/
1.2098 +void CIniFileOut::WriteTimeStampL(const TTime& aTime)
1.2099 + {
1.2100 + if(aTime.Int64() != 0)
1.2101 + {
1.2102 + WriteLineL(KTimeStampSection());
1.2103 + TBuf<32> buf;
1.2104 + buf.Num(aTime.Int64());
1.2105 + buf.Append(KCrNl);
1.2106 + WriteLineL(buf);
1.2107 + }
1.2108 + }
1.2109 +
1.2110 +/**
1.2111 +Writes meta data to repository file.
1.2112 +@param aFileIn Input repository file
1.2113 +@leave System-wide error codes
1.2114 +*/
1.2115 +void CIniFileOut::WriteMetaDataL(TUint32 aDefaultMeta,
1.2116 + const RDefaultMetaArray& aDefaultMetaRanges)
1.2117 + {
1.2118 + if (!aDefaultMeta && !aDefaultMetaRanges.Count())
1.2119 + {
1.2120 + return;
1.2121 + }
1.2122 +
1.2123 + WriteLineL(KDefaultMetaSection);
1.2124 +
1.2125 + if (aDefaultMeta)
1.2126 + {
1.2127 + iBuf.Format(KHexIntFormat, aDefaultMeta);
1.2128 + WriteLineL(iBuf);
1.2129 + }
1.2130 +
1.2131 + for (TInt i = 0; i<aDefaultMetaRanges.Count(); i++)
1.2132 + {
1.2133 + const TSettingsDefaultMeta& entry = aDefaultMetaRanges[i];
1.2134 + if (entry.HighKey())
1.2135 + {
1.2136 + iBuf.Format(KRangeMetaFmt, entry.LowKey(), entry.HighKey(),
1.2137 + entry.GetDefaultMetadata());
1.2138 + }
1.2139 + else
1.2140 + {
1.2141 + iBuf.Format(KMaskMetaFmt, entry.LowKey(), entry.KeyMask(),
1.2142 + entry.GetDefaultMetadata());
1.2143 + }
1.2144 + WriteLineL(iBuf);
1.2145 + }
1.2146 +
1.2147 + WriteLineL(KCrNl());
1.2148 + }
1.2149 +
1.2150 +/**
1.2151 +Writes platsec info to repository file.
1.2152 +@param aFileIn Input repository file
1.2153 +@leave System-wide error codes
1.2154 +*/
1.2155 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.2156 +void CIniFileOut::WritePlatSecL(const TSettingsAccessPolicy& aDefaultAccessPolicy,
1.2157 + const RRangePolicyArray& aRangePolicies,TUint32 aCreVersion)
1.2158 +#else
1.2159 +void CIniFileOut::WritePlatSecL(const TSecurityPolicy& aDefaultReadPolicy,
1.2160 + const TSecurityPolicy& aDefaultWritePolicy,
1.2161 + const RRangePolicyArray& aRangePolicies)
1.2162 +#endif
1.2163 + {
1.2164 + WriteLineL(KPlatSecSection);
1.2165 +
1.2166 + iBuf.Zero();
1.2167 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.2168 + if (aCreVersion<2 || (aCreVersion>=2 && aDefaultAccessPolicy.iHighKey!=0))
1.2169 + AppendSecurityPolicyL(*(aDefaultAccessPolicy.GetReadAccessPolicy()), ECapReadAccess);
1.2170 + iBuf.Append(KSpace);
1.2171 + if (aCreVersion<2 || (aCreVersion>=2 && aDefaultAccessPolicy.iKeyMask!=0))
1.2172 + AppendSecurityPolicyL(*(aDefaultAccessPolicy.GetWriteAccessPolicy()), ECapWriteAccess);
1.2173 +#else
1.2174 + AppendSecurityPolicyL(aDefaultReadPolicy, ECapReadAccess);
1.2175 + iBuf.Append(KSpace);
1.2176 + AppendSecurityPolicyL(aDefaultWritePolicy, ECapWriteAccess);
1.2177 +#endif
1.2178 + WriteLineL(iBuf);
1.2179 +
1.2180 + for(TInt i=0; i < aRangePolicies.Count(); i++)
1.2181 + {
1.2182 + const TSettingsAccessPolicy& e = aRangePolicies[i];
1.2183 + if (e.iHighKey != 0)
1.2184 + {
1.2185 + iBuf.Format(KRangePrefix, e.iLowKey, e.iHighKey);
1.2186 + }
1.2187 + else
1.2188 + {
1.2189 + iBuf.Format(KMaskPrefix, e.iLowKey, e.iKeyMask);
1.2190 + }
1.2191 +
1.2192 + iBuf.Append(KSpace);
1.2193 +
1.2194 + AppendSecurityPolicyL(e.iReadAccessPolicy, ECapReadAccess);
1.2195 + iBuf.Append(KSpace);
1.2196 + AppendSecurityPolicyL(e.iWriteAccessPolicy, ECapWriteAccess);
1.2197 + WriteLineL(iBuf);
1.2198 + }
1.2199 +
1.2200 + WriteLineL(KCrNl());
1.2201 + }
1.2202 +
1.2203 +void CIniFileOut::AppendSecurityPolicyL(const TSecurityPolicy& aPolicy,
1.2204 + TCapAccessMode aRdWrMode)
1.2205 + {
1.2206 + TCompiledSecurityPolicy policy(aPolicy);
1.2207 + iBuf.Append(policy.TextualizePolicyL(aRdWrMode));
1.2208 + }
1.2209 +
1.2210 +/////////////////////////////////////////////////////////////////////////////////////////////////
1.2211 +const TDesC& TCompiledSecurityPolicy::TextualizePolicyL(TCapAccessMode aMode)
1.2212 + {
1.2213 + iBuf.Zero();
1.2214 + AppendModeHeader(aMode, EHdrCapability);
1.2215 +
1.2216 + switch (static_cast<TSecurityPolicy::TType>(iSecurityPolicy.iType))
1.2217 + {
1.2218 + case TSecurityPolicy::ETypeFail:
1.2219 + iBuf.Append(KAccessAlwaysFail);
1.2220 + break;
1.2221 + case TSecurityPolicy::ETypePass:
1.2222 + iBuf.Append(KAccessAlwaysPass);
1.2223 + break;
1.2224 + case TSecurityPolicy::ETypeC3:
1.2225 + DoCapabilitySection(3);
1.2226 + break;
1.2227 + case TSecurityPolicy::ETypeC7:
1.2228 + DoCapabilitySection(7);
1.2229 + break;
1.2230 + case TSecurityPolicy::ETypeS3:
1.2231 + iBuf.Zero(); // erase the "cap_rd", replace with sid_rd
1.2232 + AppendModeHeader(aMode, EHdrSecureId);
1.2233 + iBuf.AppendNum(iSecurityPolicy.iSecureId);
1.2234 +
1.2235 + if (ECapability_HardLimit != iSecurityPolicy.iCaps[0])
1.2236 + {
1.2237 + iBuf.Append(KSpace);
1.2238 + AppendModeHeader(aMode, EHdrCapability);
1.2239 + DoCapabilitySection(3);
1.2240 + }
1.2241 + break;
1.2242 +
1.2243 + default:
1.2244 + User::Leave(KErrCorrupt);
1.2245 + } // switch
1.2246 +
1.2247 + return iBuf;
1.2248 + }
1.2249 +
1.2250 +TCapability TCompiledSecurityPolicy::CapabilityAt(TInt aIndex) const
1.2251 + {
1.2252 + if (aIndex < 3)
1.2253 + {
1.2254 + return static_cast <TCapability> (iSecurityPolicy.iCaps[aIndex]);
1.2255 + }
1.2256 + else if(aIndex < 7)
1.2257 + {
1.2258 + return static_cast <TCapability> (iSecurityPolicy.iExtraCaps[aIndex - 3]);
1.2259 + }
1.2260 + return ECapability_None;
1.2261 + }
1.2262 +
1.2263 +//
1.2264 +void TCompiledSecurityPolicy::DoCapabilitySection(TInt aMaxNumCaps)
1.2265 + {
1.2266 + for (TInt i = 0; i < aMaxNumCaps; i++)
1.2267 + {
1.2268 + TCapability cap = CapabilityAt(i);
1.2269 +
1.2270 + if (cap<0 || cap>= ECapability_Limit)
1.2271 + {
1.2272 + return;
1.2273 + }
1.2274 + if (i > 0)
1.2275 + {
1.2276 + iBuf.Append(',');
1.2277 + }
1.2278 +
1.2279 + for (const char* p=CapabilityNames[cap]; *p; p++)
1.2280 + {
1.2281 + iBuf.Append((TUint16)*p);
1.2282 + }
1.2283 + } // for i
1.2284 + }
1.2285 +
1.2286 +void TCompiledSecurityPolicy::AppendModeHeader(TCapAccessMode aAccessMode,
1.2287 + THeaderType aType)
1.2288 + {
1.2289 + if (aAccessMode == ECapReadAccess)
1.2290 + {
1.2291 + if (aType == EHdrSecureId)
1.2292 + {
1.2293 + iBuf.Append(KReadAccessSidString); // "sid_rd"
1.2294 + }
1.2295 + else
1.2296 + {
1.2297 + iBuf.Append(KReadAccessCapString); // "cap_rd"
1.2298 + }
1.2299 + }
1.2300 + else
1.2301 + {
1.2302 + if (aType == EHdrSecureId)
1.2303 + {
1.2304 + iBuf.Append(KWriteAccessSidString); // "sid_wr"
1.2305 + }
1.2306 + else
1.2307 + {
1.2308 + iBuf.Append(KWriteAccessCapString); // "cap_wr"
1.2309 + }
1.2310 + }
1.2311 + iBuf.Append('=');
1.2312 + }
1.2313 +#endif //CENTREP_CONV_TOOL