1 /**
2 * Copyright(c) 2011 Trusted Logic. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name Trusted Logic nor the names of its
15 * contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <errno.h>
36 #include <sys/types.h>
37 #include <fcntl.h>
38
39 #if defined(_WIN32_WCE)
40 #include "os_wm.h"
41 #else
42 #include <sys/stat.h>
43 #endif
44
45 #include "smc_properties.h"
46 #include "smc_properties_parser.h"
47 #include "s_type.h"
48 #include "s_error.h"
49
50 #if defined(__SYMBIAN32__)
51 #include "smc_properties_symbian.h"
52 #endif
53
54
55 #define SECURE_CONFIG_FILE_HDR 66
56 #define SECURE_CONFIG_FILE_VERSION 01
57
58
59 #define SYSTEM_SECTION_NAME "Global"
60
61 typedef enum {
62 MANDATORY_FILE_SYSTEM_FILE_NAME,
63 MANDATORY_KEYSTORE_SYSTEM_FILE_NAME,
64 MANDATORY_KEYSTORE_USER_FILE_NAME,
65 MANDATORY_SUPER_PARTITION_FILE_NAME,
66
67 NB_MANDATORY_PROPS,
68 } MANDATORY_PROPS;
69
70
71 typedef enum
72 {
73 STATE_NONE,
74 STATE_DECIMAL,
75 STATE_HEXA,
76 STATE_BINARY
77 } INTEGER_FORMAT;
78
79 #if defined (LINUX) || defined(__ANDROID32__)
80 #define SEPARATOR_CHAR '/'
81
82 #elif defined (WIN32) || defined (__SYMBIAN32__) || defined (_WIN32_WCE)
83 #define SEPARATOR_CHAR '\\'
84
85 #else
86 #error SEPARATOR_CHAR not implemented...
87 #endif
88
89 #if defined(__SYMBIAN32__)
90 #define printf RDebugPrintf
91 #endif
92
93
94 /** the sturct that keep the data stored in the config file */
95 static CONF_FILE gConfFile;
96
97
98
99 /**
100 * check the validity of a given path (is a directory, has the READ/WRITE access rights)
101 * @param pPath the path we want to check
102 * @return true if the path is OK, else false
103 */
checkFilePath(char * pPath)104 static bool checkFilePath(char *pPath)
105 {
106 struct stat buf;
107 uint32_t result;
108 char *pDir = pPath;
109
110 // cobra & buffalo version : complete path (directory and filename) is given in the config file.
111 // so we extract from this path the parent directory
112 {
113 uint32_t nSlashIndex = 0;
114 uint32_t i = 0;
115 while(pPath[i] != '\0')
116 {
117 if (pPath[i] == SEPARATOR_CHAR)
118 nSlashIndex = i;
119 i++;
120 }
121 pDir = malloc(sizeof(char) * nSlashIndex);
122 if (pDir == NULL)
123 {
124 printf("Out of memory.");
125 return false;
126 }
127 strncpy(pDir, pPath, nSlashIndex);
128 pDir[nSlashIndex] = '\0';
129 }
130
131 /* check if file exists */
132 result = stat(pDir, &buf);
133 if(result != 0 )
134 {
135 #if defined(__SYMBIAN32__)
136 if (SymbianCheckFSDirectory(pDir) == -1)
137 {
138 printf("Cannot create directory : %s\n.", pDir);
139 return false;
140 }
141 #else
142 printf("Unknown path : %s\n.", pDir);
143 return false;
144 #endif
145 }
146 else
147 {
148 /* check it's a directory */
149 if ((buf.st_mode & S_IFDIR) != S_IFDIR)
150 {
151 printf("Path %s doesn't point on a directory.\n", pDir);
152 return false;
153 }
154 #if (!defined(__SYMBIAN32__)) && (!defined(_WIN32_WCE)) && (!defined(__ANDROID32__))
155 // TODO : under Symbian, Android and WM, check access right of a directory failed? I don't know why...
156 /* check read access */
157 if ((buf.st_mode & S_IREAD) != S_IREAD)
158 {
159 printf("Path %s doesn't have the READ access rights.\n", pDir);
160 return false;
161 }
162 /* check write */
163 if ((buf.st_mode & S_IWRITE) != S_IWRITE)
164 {
165 printf("Path %s doesn't have the WRITE access rights.\n", pDir);
166 return false;
167 }
168 #endif
169 }
170
171 return true;
172 }
173
174 /**
175 * check properties (value, range...)
176 * @param sConfFile struct where are stored the properties we will check
177 * @return true if the check succeed, else false
178 */
smcPropertiesCheck(CONF_FILE sConfFile)179 static bool smcPropertiesCheck(CONF_FILE sConfFile)
180 {
181 NODE* pNext = NULL;
182 char *pPropVal = NULL;
183 bool bCheckResult = true;
184 bool pMandatoryProps[NB_MANDATORY_PROPS];
185 uint32_t i = 0;
186
187 // reset properties table
188 for (i=0; i<NB_MANDATORY_PROPS; i++)
189 pMandatoryProps[i] = false;
190
191 // check properties type and set MandatoryProps field to true (check later)
192 pNext = sConfFile.sSystemSectionPropertyList.pFirst;
193 while(pNext != NULL)
194 {
195 pPropVal = ((PROPERTY*)pNext)->pValue;
196
197 //printf("Checking %s = %s.\n", pNext->pName, pPropVal);
198 if(strcmp(pNext->pName, FILE_SYSTEM_FILE_NAME) == 0)
199 {
200 /* File System */
201 bCheckResult = checkFilePath(pPropVal);
202 pMandatoryProps[MANDATORY_FILE_SYSTEM_FILE_NAME] = true;
203 }
204 else if(strcmp(pNext->pName, KEYSTORE_SYSTEM_FILE_NAME) == 0)
205 {
206 bCheckResult = checkFilePath(pPropVal);
207 pMandatoryProps[MANDATORY_KEYSTORE_SYSTEM_FILE_NAME] = true;
208 }
209 else if(strcmp(pNext->pName, KEYSTORE_USER_FILE_NAME) == 0)
210 {
211 bCheckResult = checkFilePath(pPropVal);
212 pMandatoryProps[MANDATORY_KEYSTORE_USER_FILE_NAME] = true;
213 }
214 else if(strcmp(pNext->pName, SUPER_PARTITION_FILE_NAME) == 0)
215 {
216 bCheckResult = checkFilePath(pPropVal);
217 pMandatoryProps[MANDATORY_SUPER_PARTITION_FILE_NAME] = true;
218 }
219 else
220 {
221 bCheckResult = true;
222 }
223
224 if (! bCheckResult)
225 {
226 printf("Property %s = %s. Bad value!!!\n", pNext->pName, pPropVal);
227 return false;
228 }
229 pNext=pNext->pNext;
230 }
231
232 /* check all mandatory properties had been found */
233 for (i=0; i<NB_MANDATORY_PROPS; i++)
234 {
235 if (!pMandatoryProps[i])
236 {
237 char *pMissingProp = NULL;
238 switch(i){
239 case MANDATORY_FILE_SYSTEM_FILE_NAME :
240 pMissingProp = FILE_SYSTEM_FILE_NAME;
241 break;
242 case MANDATORY_KEYSTORE_SYSTEM_FILE_NAME :
243 pMissingProp = KEYSTORE_SYSTEM_FILE_NAME;
244 break;
245 case MANDATORY_KEYSTORE_USER_FILE_NAME :
246 pMissingProp = KEYSTORE_USER_FILE_NAME;
247 break;
248 case MANDATORY_SUPER_PARTITION_FILE_NAME :
249 pMissingProp = SUPER_PARTITION_FILE_NAME;
250 break;
251 }
252 printf("Mandatory property %s is missing.\n", pMissingProp);
253 bCheckResult = false;
254 }
255 }
256
257 return bCheckResult;
258 }
259
260
261
262 /**
263 * parse the config file
264 * @param configFile the path of the configuration file
265 * @return 0 if succeed, else 1
266 */
smcPropertiesParse(const char * configFile)267 int smcPropertiesParse(const char *configFile)
268 {
269 S_RESULT nResult = S_SUCCESS;
270
271 // first : parse the config file
272 memset(&gConfFile, 0x00, sizeof(CONF_FILE));
273 nResult=SMCPropParseConfigFile((char *)configFile, &gConfFile);
274 if (nResult!=S_SUCCESS)
275 {
276 printf("Parsing error in file %s : %x.\n", configFile, nResult);
277 return 1;
278 }
279
280 // check properties
281 if (!smcPropertiesCheck(gConfFile))
282 {
283 printf("Properties check failed.\n");
284 return 1;
285 }
286
287 return 0;
288 }
289
290
291
292 /**
293 * get the value of a property
294 * @param pProp we are asking the value of this property
295 * @return the value if found, else NULL
296 */
smcGetPropertyAsString(char * pProp)297 char *smcGetPropertyAsString(char *pProp)
298 {
299 return SMCPropGetSystemProperty(&gConfFile, pProp);
300 }
301
302
303 /**
304 * get the value of a property
305 * @param pProp we are asking the value of this property
306 * @param pVal the value of the property
307 * @return 0 if found, else 1 (and pVal set to 0)
308 */
smcGetPropertyAsInt(char * pProp,int * pVal)309 int smcGetPropertyAsInt(char *pProp, int *pVal)
310 {
311 char *pStr = SMCPropGetSystemProperty(&gConfFile, pProp);
312 if (pStr == NULL)
313 {
314 *pVal = 0;
315 return 1;
316 }
317 if (libString2GetStringAsInt(pStr, (uint32_t*)pVal) == S_SUCCESS)
318 {
319 return 0;
320 }
321 *pVal = 0;
322 return 1;
323 }
324