summaryrefslogtreecommitdiffstats
path: root/security/tf_daemon/smc_properties.c
blob: 48bfa8cd4bbd46bd67fa8132fa45741299fa7636 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
/**
 * Copyright(c) 2011 Trusted Logic.   All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name Trusted Logic nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <fcntl.h>

#if defined(_WIN32_WCE)
#include "os_wm.h"
#else
#include <sys/stat.h>
#endif

#include "smc_properties.h"
#include "smc_properties_parser.h"
#include "s_type.h"
#include "s_error.h"

#if defined(__SYMBIAN32__)
#include "smc_properties_symbian.h"
#endif


#define SECURE_CONFIG_FILE_HDR     66
#define SECURE_CONFIG_FILE_VERSION 01


#define SYSTEM_SECTION_NAME               "Global"

typedef enum {
   MANDATORY_FILE_SYSTEM_FILE_NAME,
   MANDATORY_KEYSTORE_SYSTEM_FILE_NAME,
   MANDATORY_KEYSTORE_USER_FILE_NAME,
   MANDATORY_SUPER_PARTITION_FILE_NAME,

   NB_MANDATORY_PROPS,
} MANDATORY_PROPS;


typedef enum
{
   STATE_NONE,
   STATE_DECIMAL,
   STATE_HEXA,
   STATE_BINARY
} INTEGER_FORMAT;

#if defined (LINUX) || defined(ANDROID)
#define SEPARATOR_CHAR '/'

#elif defined (WIN32) || defined (__SYMBIAN32__) || defined (_WIN32_WCE)
#define SEPARATOR_CHAR '\\'

#else
#error SEPARATOR_CHAR not implemented...
#endif

#if defined(__SYMBIAN32__)
#define printf RDebugPrintf
#endif


/** the sturct that keep the data stored in the config file */
static CONF_FILE gConfFile;



/**
 * check the validity of a given path (is a directory, has the READ/WRITE access rights)
 * @param pPath the path we want to check
 * @return true if the path is OK, else false
 */
static bool checkFilePath(char *pPath)
{
   struct stat buf;
   uint32_t  result;
   char *pDir = pPath;

   // cobra & buffalo version : complete path (directory and filename) is given in the config file.
   // so we extract from this path the parent directory
   {
      uint32_t nSlashIndex = 0;
      uint32_t i = 0;
      while(pPath[i] != '\0')
      {
         if (pPath[i] == SEPARATOR_CHAR)
            nSlashIndex = i;
         i++;
      }
      pDir = malloc(sizeof(char) * nSlashIndex);
      if (pDir == NULL)
      {
         printf("Out of memory.");
         return false;
      }
      strncpy(pDir, pPath, nSlashIndex);
      pDir[nSlashIndex] = '\0';
   }

   /* check if file exists */
   result = stat(pDir, &buf);
   if(result != 0 )
   {
#if defined(__SYMBIAN32__)
      if (SymbianCheckFSDirectory(pDir) == -1)
      {
         printf("Cannot create directory : %s\n.", pDir);
         return false;
      }
#else
      printf("Unknown path : %s\n.", pDir);
      return false;
#endif
   }
   else
   {
      /* check it's a directory */
      if ((buf.st_mode & S_IFDIR) != S_IFDIR)
      {
         printf("Path %s doesn't point on a directory.\n", pDir);
         return false;
      }
#if (!defined(__SYMBIAN32__)) && (!defined(_WIN32_WCE)) && (!defined(ANDROID))
      // TODO : under Symbian, Android and WM, check access right of a directory failed? I don't know why...
       /* check read access */
       if ((buf.st_mode & S_IREAD) != S_IREAD)
       {
          printf("Path %s doesn't have the READ access rights.\n", pDir);
          return false;
       }
       /* check write */
       if ((buf.st_mode & S_IWRITE) != S_IWRITE)
       {
          printf("Path %s doesn't have the WRITE access rights.\n", pDir);
          return false;
       }
#endif
   }

   return true;
}

/**
 * check properties (value, range...)
 * @param sConfFile struct where are stored the properties we will check
 * @return true if the check succeed, else false
 */
static bool smcPropertiesCheck(CONF_FILE sConfFile)
{
   NODE* pNext = NULL;
   char *pPropVal = NULL;
   bool bCheckResult = true;
   bool pMandatoryProps[NB_MANDATORY_PROPS];
   uint32_t i = 0;

   // reset properties table
   for (i=0; i<NB_MANDATORY_PROPS; i++)
      pMandatoryProps[i] = false;

   // check properties type and set MandatoryProps field to true (check later)
   pNext = sConfFile.sSystemSectionPropertyList.pFirst;
   while(pNext != NULL)
   {
      pPropVal = ((PROPERTY*)pNext)->pValue;

      //printf("Checking %s = %s.\n", pNext->pName, pPropVal);
      if(strcmp(pNext->pName, FILE_SYSTEM_FILE_NAME) == 0)
      {
         /* File System */
         bCheckResult = checkFilePath(pPropVal);
         pMandatoryProps[MANDATORY_FILE_SYSTEM_FILE_NAME] = true;
      }
      else if(strcmp(pNext->pName, KEYSTORE_SYSTEM_FILE_NAME) == 0)
      {
         bCheckResult = checkFilePath(pPropVal);
         pMandatoryProps[MANDATORY_KEYSTORE_SYSTEM_FILE_NAME] = true;
      }
      else if(strcmp(pNext->pName, KEYSTORE_USER_FILE_NAME) == 0)
      {
         bCheckResult = checkFilePath(pPropVal);
         pMandatoryProps[MANDATORY_KEYSTORE_USER_FILE_NAME] = true;
      }
      else if(strcmp(pNext->pName, SUPER_PARTITION_FILE_NAME) == 0)
      {
         bCheckResult = checkFilePath(pPropVal);
         pMandatoryProps[MANDATORY_SUPER_PARTITION_FILE_NAME] = true;
      }
      else
      {
         bCheckResult = true;
      }

      if (! bCheckResult)
      {
         printf("Property %s = %s. Bad value!!!\n", pNext->pName, pPropVal);
         return false;
      }
      pNext=pNext->pNext;
   }

   /* check all mandatory properties had been found */
   for (i=0; i<NB_MANDATORY_PROPS; i++)
   {
      if (!pMandatoryProps[i])
      {
         char *pMissingProp = NULL;
         switch(i){
            case MANDATORY_FILE_SYSTEM_FILE_NAME :
               pMissingProp = FILE_SYSTEM_FILE_NAME;
               break;
            case MANDATORY_KEYSTORE_SYSTEM_FILE_NAME :
               pMissingProp = KEYSTORE_SYSTEM_FILE_NAME;
               break;
            case MANDATORY_KEYSTORE_USER_FILE_NAME :
               pMissingProp = KEYSTORE_USER_FILE_NAME;
               break;
            case MANDATORY_SUPER_PARTITION_FILE_NAME :
               pMissingProp = SUPER_PARTITION_FILE_NAME;
               break;
         }
         printf("Mandatory property %s is missing.\n", pMissingProp);
         bCheckResult = false;
      }
   }

   return bCheckResult;
}



/**
 * parse the config file
 * @param configFile the path of the configuration file
 * @return 0 if succeed, else 1
 */
int smcPropertiesParse(const char *configFile)
{
   S_RESULT nResult = S_SUCCESS;

   // first : parse the config file
   memset(&gConfFile, 0x00, sizeof(CONF_FILE));
   nResult=SMCPropParseConfigFile((char *)configFile, &gConfFile);
   if (nResult!=S_SUCCESS)
   {
      printf("Parsing error in file %s : %x.\n", configFile, nResult);
      return 1;
   }

   // check properties
   if (!smcPropertiesCheck(gConfFile))
   {
      printf("Properties check failed.\n");
      return 1;
   }

   return 0;
}



/**
 * get the value of a property
 * @param pProp we are asking the value of this property
 * @return the value if found, else NULL
 */
char *smcGetPropertyAsString(char *pProp)
{
   return SMCPropGetSystemProperty(&gConfFile, pProp);
}


/**
 * get the value of a property
 * @param pProp we are asking the value of this property
 * @param pVal the value of the property
 * @return 0 if found, else 1 (and pVal set to 0)
 */
int smcGetPropertyAsInt(char *pProp, int *pVal)
{
   char *pStr = SMCPropGetSystemProperty(&gConfFile, pProp);
   if (pStr == NULL)
   {
      *pVal = 0;
      return 1;
   }
   if (libString2GetStringAsInt(pStr, (uint32_t*)pVal) == S_SUCCESS)
   {
      return 0;
   }
   *pVal = 0;
   return 1;
}