| /** |
| * 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(__ANDROID32__) |
| #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(__ANDROID32__)) |
| // 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; |
| } |