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 */ 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 */ 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 */ 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 */ 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 */ 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