sl@0
|
1 |
/*
|
sl@0
|
2 |
* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
3 |
* All rights reserved.
|
sl@0
|
4 |
* This component and the accompanying materials are made available
|
sl@0
|
5 |
* under the terms of the License "Eclipse Public License v1.0"
|
sl@0
|
6 |
* which accompanies this distribution, and is available
|
sl@0
|
7 |
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
8 |
*
|
sl@0
|
9 |
* Initial Contributors:
|
sl@0
|
10 |
* Nokia Corporation - initial contribution.
|
sl@0
|
11 |
*
|
sl@0
|
12 |
* Contributors:
|
sl@0
|
13 |
*
|
sl@0
|
14 |
* Description:
|
sl@0
|
15 |
* Common security functions
|
sl@0
|
16 |
*
|
sl@0
|
17 |
*/
|
sl@0
|
18 |
|
sl@0
|
19 |
|
sl@0
|
20 |
/**
|
sl@0
|
21 |
@file
|
sl@0
|
22 |
*/
|
sl@0
|
23 |
|
sl@0
|
24 |
|
sl@0
|
25 |
#include "securityutils.h"
|
sl@0
|
26 |
|
sl@0
|
27 |
#include <f32file.h>
|
sl@0
|
28 |
|
sl@0
|
29 |
// Extracts the next sub-dir name, i.e. "directory1" for "directory1\directory2\...". As a second parameter, returns the remaining path without the leading slash
|
sl@0
|
30 |
// Return ETrue iff a directory was found in the path
|
sl@0
|
31 |
TBool GetNextDirNameL(const TPtrC& aPath, TPtrC& aNextDir, TPtrC& aRemainingPath)
|
sl@0
|
32 |
{
|
sl@0
|
33 |
TInt nextSlashPos = aPath.Locate('\\');
|
sl@0
|
34 |
if (nextSlashPos < 0)
|
sl@0
|
35 |
return EFalse;
|
sl@0
|
36 |
|
sl@0
|
37 |
aNextDir.Set(aPath.Left(nextSlashPos));
|
sl@0
|
38 |
TPtrC remainingPath = nextSlashPos < aPath.Length() - 1 ? aPath.Mid(nextSlashPos + 1) : TPtrC();
|
sl@0
|
39 |
aRemainingPath.Set(remainingPath);
|
sl@0
|
40 |
|
sl@0
|
41 |
return ETrue;
|
sl@0
|
42 |
}
|
sl@0
|
43 |
|
sl@0
|
44 |
TCapabilitySet PrivateModificationRequiredCapabilitiesL(const TDesC& aPrivateSubPath, TSecureId aClientSid)
|
sl@0
|
45 |
{
|
sl@0
|
46 |
TPtrC privateSubDirName;
|
sl@0
|
47 |
TPtrC remainingSubPath;
|
sl@0
|
48 |
TBool nextDirAvailable = GetNextDirNameL(aPrivateSubPath, privateSubDirName, remainingSubPath);
|
sl@0
|
49 |
// Filter out paths which do not have a /private/<SID> form - require TCB for them
|
sl@0
|
50 |
// First, filter out files directly under the /private directory
|
sl@0
|
51 |
if (!nextDirAvailable)
|
sl@0
|
52 |
return TCapabilitySet(ECapabilityTCB);
|
sl@0
|
53 |
|
sl@0
|
54 |
if (privateSubDirName.Length() != 8)
|
sl@0
|
55 |
return TCapabilitySet(ECapabilityTCB); // Filter out sub-dir names which do not have 8 bytes, i.e. do not represent a SID
|
sl@0
|
56 |
|
sl@0
|
57 |
TLex hexConverter(privateSubDirName);
|
sl@0
|
58 |
TUint32 foundSecureIdInt;
|
sl@0
|
59 |
if (hexConverter.Val(foundSecureIdInt, EHex) != KErrNone)
|
sl@0
|
60 |
return TCapabilitySet(ECapabilityTCB); // Filter out paths which do not have a <secureId> subdir under private
|
sl@0
|
61 |
|
sl@0
|
62 |
TSecureId foundSecureId(foundSecureIdInt);
|
sl@0
|
63 |
if (foundSecureId != aClientSid) // Check whether this the client's SID
|
sl@0
|
64 |
{
|
sl@0
|
65 |
TPtrC nextSubPath; // Check for /private/<SID>/import directories
|
sl@0
|
66 |
TPtrC nextSubDir;
|
sl@0
|
67 |
if (!GetNextDirNameL(remainingSubPath, nextSubDir, nextSubPath) || nextSubDir.CompareF(_L("import")) != 0)
|
sl@0
|
68 |
{
|
sl@0
|
69 |
// If not an import directory, require TCB or AllFiles
|
sl@0
|
70 |
TCapabilitySet ret(ECapabilityTCB);
|
sl@0
|
71 |
ret.AddCapability(ECapabilityAllFiles);
|
sl@0
|
72 |
return ret;
|
sl@0
|
73 |
}
|
sl@0
|
74 |
}
|
sl@0
|
75 |
|
sl@0
|
76 |
TCapabilitySet emptySet;
|
sl@0
|
77 |
emptySet.SetEmpty();
|
sl@0
|
78 |
return emptySet;
|
sl@0
|
79 |
}
|
sl@0
|
80 |
|
sl@0
|
81 |
EXPORT_C TCapabilitySet SecCommonUtils::FileModificationRequiredCapabilitiesL(const TDesC& aFileName, TSecureId aClientSid)
|
sl@0
|
82 |
{
|
sl@0
|
83 |
TCapabilitySet emptySet;
|
sl@0
|
84 |
emptySet.SetEmpty();
|
sl@0
|
85 |
|
sl@0
|
86 |
// TParsePtrC is unusable, since it panics on incorrect paths. We have to use TParse and create a temporary buffer for it (as there's no TParseC)
|
sl@0
|
87 |
RBuf tempbuf;
|
sl@0
|
88 |
tempbuf.CreateL(aFileName);
|
sl@0
|
89 |
tempbuf.CleanupClosePushL();
|
sl@0
|
90 |
|
sl@0
|
91 |
TParse pathParse;
|
sl@0
|
92 |
if (pathParse.Set(tempbuf, NULL, NULL) != KErrNone)
|
sl@0
|
93 |
{
|
sl@0
|
94 |
CleanupStack::PopAndDestroy(&tempbuf);
|
sl@0
|
95 |
// Path failed to parse - require TCB, as it is the only capability which allows modification anywhere on the FS
|
sl@0
|
96 |
// (and we do not know where on the FS this file is)
|
sl@0
|
97 |
return TCapabilitySet(ECapabilityTCB);
|
sl@0
|
98 |
}
|
sl@0
|
99 |
|
sl@0
|
100 |
CleanupStack::PopAndDestroy(&tempbuf);
|
sl@0
|
101 |
|
sl@0
|
102 |
// check for wild cards (such as * or ?) in paths
|
sl@0
|
103 |
if(pathParse.IsWild())
|
sl@0
|
104 |
return TCapabilitySet(ECapabilityTCB);
|
sl@0
|
105 |
|
sl@0
|
106 |
// check for relative paths
|
sl@0
|
107 |
if(aFileName.Find(_L("..")) != KErrNotFound)
|
sl@0
|
108 |
return TCapabilitySet(ECapabilityTCB);
|
sl@0
|
109 |
|
sl@0
|
110 |
TPtrC pathTmp = pathParse.Path();
|
sl@0
|
111 |
if (pathTmp.Length() <= 1) // The should be at least one directory - otherwise there's nothing to check
|
sl@0
|
112 |
return emptySet;
|
sl@0
|
113 |
|
sl@0
|
114 |
// Get the first directory name
|
sl@0
|
115 |
TPtrC path = pathTmp.Mid(1); // Remove the leading slash
|
sl@0
|
116 |
|
sl@0
|
117 |
TPtrC firstDirName;
|
sl@0
|
118 |
TPtrC remainingPath;
|
sl@0
|
119 |
TBool nextDirAvailable = GetNextDirNameL(path, firstDirName, remainingPath);
|
sl@0
|
120 |
__ASSERT_ALWAYS(nextDirAvailable, User::Invariant()); // There should be at least one directory if the Path() was not empty
|
sl@0
|
121 |
|
sl@0
|
122 |
// For 'sys' or 'resource', require TCB
|
sl@0
|
123 |
if (firstDirName.CompareF(_L("sys")) == 0 || firstDirName.CompareF(_L("resource")) == 0)
|
sl@0
|
124 |
return TCapabilitySet(ECapabilityTCB);
|
sl@0
|
125 |
|
sl@0
|
126 |
if (firstDirName.CompareF(_L("private")) == 0)
|
sl@0
|
127 |
return PrivateModificationRequiredCapabilitiesL(remainingPath, aClientSid);
|
sl@0
|
128 |
|
sl@0
|
129 |
// If the directory name is not 'private', 'resource' or 'sys', no capabilities are required
|
sl@0
|
130 |
return emptySet;
|
sl@0
|
131 |
}
|