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