|
|
|
|
@@ -4,7 +4,7 @@
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include <openssl/evp.h>
|
|
|
|
|
const char* module_config_monitor="CONFIG_MONITOR";
|
|
|
|
|
|
|
|
|
|
#define CM_UPDATE_TYPE_ERR -1
|
|
|
|
|
@@ -13,6 +13,14 @@ const char* module_config_monitor="CONFIG_MONITOR";
|
|
|
|
|
#define CM_MAX_TABLE_NUM 256
|
|
|
|
|
#define MAX_CONFIG_FN_LEN 256
|
|
|
|
|
#define MAX_CONFIG_LINE 1024*4
|
|
|
|
|
|
|
|
|
|
#ifndef MAX
|
|
|
|
|
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef MIN
|
|
|
|
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
|
|
|
|
#endif
|
|
|
|
|
//#define USING_DICTATOR 1
|
|
|
|
|
extern "C" void __real_free(void*p);
|
|
|
|
|
struct cm_table_info_t
|
|
|
|
|
@@ -20,7 +28,118 @@ struct cm_table_info_t
|
|
|
|
|
char table_name[MAX_CONFIG_FN_LEN];
|
|
|
|
|
char cfg_path[MAX_CONFIG_FN_LEN];
|
|
|
|
|
int cfg_num;
|
|
|
|
|
char encryp_algorithm[MAX_CONFIG_FN_LEN];
|
|
|
|
|
};
|
|
|
|
|
int decrypt_open(FILE* in,const unsigned char* key, const char* algorithm,unsigned char**pp_out,void *logger)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
unsigned char inbuf[MAX_CONFIG_LINE];
|
|
|
|
|
int inlen, out_blk_len=0;
|
|
|
|
|
int out_buff_len=0,buff_offset=0;
|
|
|
|
|
EVP_CIPHER_CTX *ctx;
|
|
|
|
|
|
|
|
|
|
unsigned char cipher_key[EVP_MAX_KEY_LENGTH];
|
|
|
|
|
unsigned char cipher_iv[EVP_MAX_IV_LENGTH];
|
|
|
|
|
memset(cipher_key,0,sizeof(cipher_key));
|
|
|
|
|
memset(cipher_iv,0,sizeof(cipher_iv));
|
|
|
|
|
|
|
|
|
|
const EVP_CIPHER *cipher;
|
|
|
|
|
const EVP_MD *dgst=NULL;
|
|
|
|
|
const unsigned char *salt=NULL;
|
|
|
|
|
int ret=0;
|
|
|
|
|
|
|
|
|
|
OpenSSL_add_all_algorithms();
|
|
|
|
|
cipher=EVP_get_cipherbyname(algorithm);
|
|
|
|
|
if(cipher==NULL)
|
|
|
|
|
{
|
|
|
|
|
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor,"Not cipher:%s not supported.");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
dgst=EVP_get_digestbyname("md5");
|
|
|
|
|
if(dgst==NULL)
|
|
|
|
|
{
|
|
|
|
|
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor,"Get MD5 object failed.");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
ret=EVP_BytesToKey(cipher,dgst,salt,key,strlen((const char*)key),1,cipher_key,cipher_iv);
|
|
|
|
|
if(ret==0)
|
|
|
|
|
{
|
|
|
|
|
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor,"Key and IV generatioin failed.");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
/* Don't set key or IV right away; we want to check lengths */
|
|
|
|
|
ctx = EVP_CIPHER_CTX_new();
|
|
|
|
|
EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL,0);
|
|
|
|
|
OPENSSL_assert(EVP_CIPHER_CTX_key_length(ctx) == 16);
|
|
|
|
|
OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) == 16);
|
|
|
|
|
|
|
|
|
|
/* Now we can set key and IV */
|
|
|
|
|
EVP_CipherInit_ex(ctx, NULL, NULL, cipher_key, cipher_iv, 0);
|
|
|
|
|
out_buff_len=16*1024;
|
|
|
|
|
*pp_out=(unsigned char*)malloc(out_buff_len*sizeof(unsigned char));
|
|
|
|
|
for (;;)
|
|
|
|
|
{
|
|
|
|
|
inlen = fread(inbuf, 1, MAX_CONFIG_LINE, in);
|
|
|
|
|
if (inlen <= 0)
|
|
|
|
|
break;
|
|
|
|
|
out_blk_len=out_buff_len-buff_offset;
|
|
|
|
|
if (!EVP_CipherUpdate(ctx, *pp_out+buff_offset, &out_blk_len, inbuf, inlen))
|
|
|
|
|
{
|
|
|
|
|
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor,"EVP_CipherUpdate failed.");
|
|
|
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
|
|
|
goto error_out;
|
|
|
|
|
}
|
|
|
|
|
buff_offset+=out_blk_len;
|
|
|
|
|
if(buff_offset==out_buff_len)
|
|
|
|
|
{
|
|
|
|
|
out_buff_len*=2;
|
|
|
|
|
*pp_out=(unsigned char*)realloc(*pp_out,out_buff_len);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!EVP_CipherFinal_ex(ctx, *pp_out+buff_offset, &out_blk_len))
|
|
|
|
|
{
|
|
|
|
|
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor,"EVP_CipherFinal_ex failed.");
|
|
|
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
|
|
|
goto error_out;
|
|
|
|
|
}
|
|
|
|
|
buff_offset+=out_blk_len;
|
|
|
|
|
EVP_CIPHER_CTX_free(ctx);
|
|
|
|
|
return buff_offset;
|
|
|
|
|
error_out:
|
|
|
|
|
free(*pp_out);
|
|
|
|
|
*pp_out=NULL;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
char* read_nxt_line_from_buff(const unsigned char* buff, int buff_size, int* offset, char*line ,int line_size)
|
|
|
|
|
{
|
|
|
|
|
int this_offset=0;
|
|
|
|
|
const unsigned char* p;
|
|
|
|
|
//search for CRLF, aka '\r', '\n' or "\r\n"
|
|
|
|
|
p=(const unsigned char*)memchr(buff+*offset,'\r',buff_size-*offset);
|
|
|
|
|
if(p==NULL)
|
|
|
|
|
{
|
|
|
|
|
p=(const unsigned char*)memchr(buff+*offset,'\n',buff_size-*offset);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(p-buff<buff_size-1&&*(p+1)=='\n')
|
|
|
|
|
{
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(p!=NULL)//point to next character
|
|
|
|
|
{
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
else //Treat rest buff has no CRLF as a line.
|
|
|
|
|
{
|
|
|
|
|
p=buff+buff_size;
|
|
|
|
|
}
|
|
|
|
|
this_offset=p-(buff+*offset);
|
|
|
|
|
memcpy(line,buff+*offset,MIN(this_offset,line_size));
|
|
|
|
|
*offset+=this_offset;
|
|
|
|
|
return line;
|
|
|
|
|
}
|
|
|
|
|
//replacement of glibc scandir, to adapt dictator malloc wrap
|
|
|
|
|
#define ENLARGE_STEP 1024
|
|
|
|
|
int my_scandir(const char *dir, struct dirent ***namelist,
|
|
|
|
|
@@ -202,12 +321,15 @@ int cm_read_cfg_index_file(const char* path,struct cm_table_info_t* idx,int size
|
|
|
|
|
FILE* fp=NULL;
|
|
|
|
|
fp=fopen(path,"r");
|
|
|
|
|
int ret=0,i=0;
|
|
|
|
|
char line[MAX_CONFIG_LINE];
|
|
|
|
|
while(!feof(fp))
|
|
|
|
|
{
|
|
|
|
|
ret=fscanf(fp,"%s\t%d\t%s",idx[i].table_name
|
|
|
|
|
fgets(line,sizeof(line),fp);
|
|
|
|
|
ret=sscanf(line,"%s\t%d\t%s\t%s",idx[i].table_name
|
|
|
|
|
,&(idx[i].cfg_num)
|
|
|
|
|
,idx[i].cfg_path);
|
|
|
|
|
if(ret==3&&idx[i].cfg_num>=0)//jump over empty line
|
|
|
|
|
,idx[i].cfg_path
|
|
|
|
|
,idx[i].encryp_algorithm);
|
|
|
|
|
if((ret==3||ret==4)&&idx[i].cfg_num>=0)//jump over empty line
|
|
|
|
|
{
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
@@ -224,17 +346,40 @@ int cm_read_cfg_index_file(const char* path,struct cm_table_info_t* idx,int size
|
|
|
|
|
int cm_read_table_file(struct cm_table_info_t* index,
|
|
|
|
|
void (*update)(const char*,const char*,void*),
|
|
|
|
|
void* u_para,
|
|
|
|
|
const unsigned char* key,
|
|
|
|
|
void* logger)
|
|
|
|
|
{
|
|
|
|
|
int cfg_num=0,i=0;
|
|
|
|
|
char line[MAX_CONFIG_LINE]={0},*ret_str=NULL;
|
|
|
|
|
unsigned char* decrypt_buff=NULL;
|
|
|
|
|
int decrypt_len=0,do_decrypt=0,decrypt_offset=0;
|
|
|
|
|
FILE*fp=fopen(index->cfg_path,"r");
|
|
|
|
|
if(fp==NULL)
|
|
|
|
|
{
|
|
|
|
|
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor,"update error,open %s failed.",index->cfg_path);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
fscanf(fp,"%d\n",&cfg_num);
|
|
|
|
|
if(strlen(index->encryp_algorithm)>0)
|
|
|
|
|
{
|
|
|
|
|
if(key==NULL||strlen((const char*)key)==0)
|
|
|
|
|
{
|
|
|
|
|
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor,"update error,no key to decrypt %s.",index->cfg_path);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
decrypt_len=decrypt_open(fp, key,index->encryp_algorithm, &decrypt_buff,logger);
|
|
|
|
|
if(decrypt_len==0)
|
|
|
|
|
{
|
|
|
|
|
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor,"update error,%s decrypt failed.",index->cfg_path);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
read_nxt_line_from_buff(decrypt_buff, decrypt_len, &decrypt_offset, line, sizeof(line));
|
|
|
|
|
sscanf(line,"%d\n",&cfg_num);
|
|
|
|
|
do_decrypt=1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fscanf(fp,"%d\n",&cfg_num);
|
|
|
|
|
}
|
|
|
|
|
if(cfg_num!=index->cfg_num)
|
|
|
|
|
{
|
|
|
|
|
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor ,"file %s config num not matched",index->cfg_path);
|
|
|
|
|
@@ -244,7 +389,14 @@ int cm_read_table_file(struct cm_table_info_t* index,
|
|
|
|
|
for(i=0;i<cfg_num;i++)
|
|
|
|
|
{
|
|
|
|
|
line[sizeof(line)-1]='\0';
|
|
|
|
|
ret_str=fgets(line,sizeof(line),fp);
|
|
|
|
|
if(do_decrypt==1)
|
|
|
|
|
{
|
|
|
|
|
ret_str=read_nxt_line_from_buff(decrypt_buff, decrypt_len, &decrypt_offset, line, sizeof(line));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ret_str=fgets(line,sizeof(line),fp);
|
|
|
|
|
}
|
|
|
|
|
if(ret_str==NULL)
|
|
|
|
|
{
|
|
|
|
|
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,module_config_monitor ,
|
|
|
|
|
@@ -262,6 +414,10 @@ int cm_read_table_file(struct cm_table_info_t* index,
|
|
|
|
|
update(index->table_name,line,u_para);
|
|
|
|
|
}
|
|
|
|
|
fclose(fp);
|
|
|
|
|
if(decrypt_buff!=NULL)
|
|
|
|
|
{
|
|
|
|
|
free(decrypt_buff);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
const char* path2filename(const char*path)
|
|
|
|
|
@@ -281,6 +437,7 @@ void config_monitor_traverse(unsigned int version,const char*idx_dir,
|
|
|
|
|
void (*update)(const char* ,const char*,void* ),
|
|
|
|
|
void (*finish)(void*),
|
|
|
|
|
void* u_para,
|
|
|
|
|
const unsigned char* dec_key,
|
|
|
|
|
void* logger)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
@@ -305,7 +462,7 @@ void config_monitor_traverse(unsigned int version,const char*idx_dir,
|
|
|
|
|
start(new_version,update_type,u_para);
|
|
|
|
|
for(j=0;j<table_num;j++)
|
|
|
|
|
{
|
|
|
|
|
cm_read_table_file(table_array+j,update,u_para,logger);
|
|
|
|
|
cm_read_table_file(table_array+j,update,u_para,dec_key,logger);
|
|
|
|
|
}
|
|
|
|
|
finish(u_para);
|
|
|
|
|
}
|
|
|
|
|
|