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