aesm_config.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * Copyright (C) 2011-2016 Intel Corporation. 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 of Intel Corporation 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 "aesm_config.h"
  32. #include "aesm_proxy_type.h"
  33. #include "oal.h"
  34. #include <sys/types.h>
  35. #include <regex.h>
  36. #include <stdio.h>
  37. #define AESM_CONFIG_FILE "/etc/aesmd.conf"
  38. #define MAX_LINE 1024
  39. #define URL_PATTERN "[[:blank:]]*(http[s]?://[^[:blank:]]*)[[:blank:]]*" //pattern used to match a URL which should be started with http:// or https://
  40. #define OPTION_COMMENT "(#.*)?"
  41. enum _config_value_t{
  42. config_comment,
  43. config_space,
  44. config_endpoint_url,
  45. config_pse_rl_url,
  46. config_pse_ocsp_url,
  47. config_aesm_proxy_url,
  48. config_aesm_proxy_type,
  49. config_value_nums
  50. };
  51. struct _config_patterns_t{
  52. enum _config_value_t id;
  53. const char *pattern;
  54. }config_patterns[]={
  55. {config_comment, "^[[:blank:]]*#"}, //matching a line with comments only (It is started by #)
  56. {config_space, "^[[:blank:]]*$"}, //matching empty line
  57. {config_endpoint_url, "^[[:blank:]]*endpoint[[:blank:]]*url[[:blank:]]*=" URL_PATTERN OPTION_COMMENT "$"}, //matching line in format: endpoint url = ....
  58. {config_pse_rl_url, "^[[:blank:]]*pse[[:blank:]]*rl[[:blank:]]*url[[:blank:]]*=" URL_PATTERN OPTION_COMMENT "$"}, //matching line in format: pse rl url = ...
  59. {config_pse_ocsp_url, "^[[:blank:]]*pse[[:blank:]]*ocsp[[:blank:]]*url[[:blank:]]*=" URL_PATTERN OPTION_COMMENT "$"}, //matching line in format: pse ocsp url = ...
  60. {config_aesm_proxy_url,"^[[:blank:]]*aesm[[:blank:]]*proxy[[:blank:]]*=" URL_PATTERN OPTION_COMMENT "$"}, //matching line in format: aesm proxy = ...
  61. {config_aesm_proxy_type, "^[[:blank:]]*proxy[[:blank:]]*type[[:blank:]]*=[[:blank:]]([^[:blank:]]+)[[:blank:]]*" OPTION_COMMENT "$"}//matching line in format: proxy type = [direct|default|manual]
  62. };
  63. #define NUM_CONFIG_PATTERNS (sizeof(config_patterns)/sizeof(config_patterns[0]))
  64. typedef struct _config_entry_t{
  65. bool initialized;
  66. regex_t reg;
  67. } config_entry_t;
  68. //static function to initialize all regular expression pattern
  69. static void init_config_patterns(config_entry_t entries[])
  70. {
  71. uint32_t i;
  72. for(i=0;i<NUM_CONFIG_PATTERNS;++i){
  73. uint32_t entry_id = config_patterns[i].id;
  74. if(entry_id>=config_value_nums){
  75. AESM_DBG_ERROR("config id %d is too large", entry_id);
  76. continue;
  77. }
  78. if(entries[entry_id].initialized){
  79. AESM_DBG_ERROR("duplicated item for config id %d",entry_id);
  80. continue;
  81. }
  82. if(regcomp(&entries[entry_id].reg,config_patterns[i].pattern, REG_EXTENDED|REG_ICASE)!=0){
  83. AESM_DBG_ERROR("Invalid config pattern %s", config_patterns[i].pattern);
  84. continue;
  85. }
  86. entries[entry_id].initialized=true;
  87. }
  88. }
  89. static void release_config_patterns(config_entry_t entries[])
  90. {
  91. uint32_t i;
  92. for(i=0;i<config_value_nums;++i){
  93. if(entries[i].initialized){
  94. entries[i].initialized=false;
  95. regfree(&entries[i].reg);
  96. }
  97. }
  98. }
  99. static const char *proxy_type_name[]={
  100. "direct",
  101. "default",
  102. "manual"
  103. };
  104. #define NUM_PROXY_TYPE (sizeof(proxy_type_name)/sizeof(proxy_type_name[0]))
  105. //function to decode proxy type from string to integer value
  106. static uint32_t read_aesm_proxy_type(const char *string, uint32_t len)
  107. {
  108. uint32_t i;
  109. for(i=0;i<NUM_PROXY_TYPE;++i){
  110. if(strncasecmp(proxy_type_name[i],string,len)==0){
  111. return i;
  112. }
  113. }
  114. AESM_DBG_TRACE("Invalid proxy type %.*s",len,string);
  115. return (uint32_t)NUM_PROXY_TYPE;
  116. }
  117. #define MAX_MATCHED_REG_EXP 3
  118. //Function to processing one line in config file
  119. // If any pattern is matched, get the correspondent data and set it into the output parameter 'infos'
  120. static bool config_process_one_line(const char *line, config_entry_t entries[], aesm_config_infos_t& infos)
  121. {
  122. uint32_t i;
  123. regmatch_t matches[MAX_MATCHED_REG_EXP];
  124. for(i=0;i<config_value_nums;++i){
  125. if(!entries[i].initialized){
  126. continue;
  127. }
  128. if(regexec(&entries[i].reg, line, MAX_MATCHED_REG_EXP, matches, 0)==0){
  129. switch(i){
  130. case config_comment:
  131. case config_space:
  132. //ignore comment and space only line
  133. break;
  134. case config_endpoint_url://Matching Endpoint URL setting
  135. if(matches[1].rm_eo-matches[1].rm_so>=MAX_PATH){
  136. AESM_DBG_ERROR("too long endpoint url in config file");
  137. }else{
  138. memcpy(infos.endpoint_url, line+matches[1].rm_so,matches[1].rm_eo-matches[1].rm_so);
  139. infos.endpoint_url[matches[1].rm_eo-matches[1].rm_so]='\0';
  140. }
  141. break;
  142. case config_pse_rl_url:
  143. if(matches[1].rm_eo-matches[1].rm_so>=MAX_PATH){
  144. AESM_DBG_ERROR("too long pse pr url in config file");
  145. }else{
  146. memcpy(infos.pse_rl_url, line+matches[1].rm_so,matches[1].rm_eo-matches[1].rm_so);
  147. infos.pse_rl_url[matches[1].rm_eo-matches[1].rm_so]='\0';
  148. }
  149. break;
  150. case config_pse_ocsp_url:
  151. if(matches[1].rm_eo-matches[1].rm_so>=MAX_PATH){
  152. AESM_DBG_ERROR("too long pse ocsp url in config file");
  153. }else{
  154. memcpy(infos.pse_ocsp_url, line+matches[1].rm_so,matches[1].rm_eo-matches[1].rm_so);
  155. infos.pse_ocsp_url[matches[1].rm_eo-matches[1].rm_so]='\0';
  156. }
  157. break;
  158. case config_aesm_proxy_url:
  159. if(matches[1].rm_eo-matches[1].rm_so>=MAX_PATH){
  160. AESM_DBG_ERROR("too long aesm proxy url in config file");
  161. }else{
  162. memcpy(infos.aesm_proxy, line+matches[1].rm_so,matches[1].rm_eo-matches[1].rm_so);
  163. infos.aesm_proxy[matches[1].rm_eo-matches[1].rm_so]='\0';
  164. }
  165. break;
  166. case config_aesm_proxy_type://It is a proxy type, we need change the string to integer by calling function read_aesm_proxy_type
  167. infos.proxy_type = read_aesm_proxy_type(line+matches[1].rm_so, matches[1].rm_eo-matches[1].rm_so);
  168. break;
  169. default:
  170. AESM_DBG_ERROR("reg exp type %d not processed", i);
  171. break;
  172. }
  173. break;
  174. }
  175. }
  176. if(i>=config_value_nums){//the line matching nothing
  177. AESM_DBG_ERROR("aesm config file error: invalid line[%s]",line);
  178. return false;
  179. }
  180. return true;
  181. }
  182. bool read_aesm_config(aesm_config_infos_t& infos)
  183. {
  184. char line[MAX_LINE];
  185. int line_no=0;
  186. bool ret = true;
  187. config_entry_t entries[config_value_nums];
  188. memset(&entries,0,sizeof(entries));
  189. memset(&infos, 0, sizeof(aesm_config_infos_t));
  190. strcpy(infos.endpoint_url, DEFAULT_URL);
  191. strcpy(infos.pse_rl_url, DEFAULT_PSE_RL_URL);
  192. strcpy(infos.pse_ocsp_url, DEFAULT_PSE_OCSP_URL);
  193. infos.proxy_type = AESM_PROXY_TYPE_DEFAULT_PROXY;
  194. FILE *f =fopen(AESM_CONFIG_FILE, "r");
  195. if(f==NULL){
  196. AESM_DBG_ERROR("Cannnot read aesm config file %s",AESM_CONFIG_FILE);
  197. return false;
  198. }
  199. init_config_patterns(entries);
  200. while(fgets(line, MAX_LINE, f)!=NULL){
  201. size_t len=strlen(line);
  202. if(len>0&&line[len-1]=='\n')line[len-1]='\0';//remove the line ending
  203. line_no++;
  204. if(!config_process_one_line(line, entries, infos)){
  205. AESM_LOG_WARN("format error in file %s:%d [%s]",AESM_CONFIG_FILE, line_no, line);
  206. ret = false;//continue process the file but save the error status
  207. }
  208. }
  209. release_config_patterns(entries);
  210. fclose(f);
  211. if(infos.proxy_type>=NUM_PROXY_TYPE||
  212. (infos.proxy_type==AESM_PROXY_TYPE_MANUAL_PROXY&&infos.aesm_proxy[0]=='\0')){
  213. AESM_DBG_WARN("Invalid proxy type %d",infos.proxy_type);
  214. infos.proxy_type = AESM_PROXY_TYPE_DIRECT_ACCESS;
  215. ret = false;
  216. }
  217. return ret;
  218. }