diff --git a/source/dnode/mgmt/exe/dmMain.c b/source/dnode/mgmt/exe/dmMain.c index 73aace44b7..a682978035 100644 --- a/source/dnode/mgmt/exe/dmMain.c +++ b/source/dnode/mgmt/exe/dmMain.c @@ -22,7 +22,7 @@ #ifdef TD_JEMALLOC_ENABLED #include "jemalloc/jemalloc.h" #endif -#include "crypt.h" +#include "dmUtil.h" #if defined(CUS_NAME) || defined(CUS_PROMPT) || defined(CUS_EMAIL) #include "cus_name.h" @@ -50,10 +50,8 @@ #define DM_VERSION "Print program version." #define DM_EMAIL "" #define DM_MEM_DBG "Enable memory debug" -#define DM_SET_ENCRYPTKEY "Set encrypt key. such as: -e 1234567890abcdef, the length should be less or equal to 16." -#define DM_KEY_INDICATOR "this indicator!" -#define DM_ENCRYPT_CODE_FILE "encryptCode.cfg" -#define DM_CHECK_CODE_FILE "checkCode.bin" +#define DM_SET_ENCRYPTKEY "Set encrypt key. such as: -y 1234567890abcdef, the length should be less or equal to 16." + // clang-format on static struct { #ifdef WINDOWS @@ -295,260 +293,6 @@ static void taosCleanupArgs() { if (global.envCmd != NULL) taosMemoryFreeClear(global.envCmd); } -static int32_t compareCheckCode(char* file, char* key){ - char *content = NULL; - int64_t size = 0; - TdFilePtr pFile = NULL; - char *result = NULL; - int32_t code = -1; - - pFile = taosOpenFile(file, TD_FILE_READ); - if (pFile == NULL) { - terrno = TAOS_SYSTEM_ERROR(errno); - dError("failed to open dnode file:%s since %s", file, terrstr()); - goto _OVER; - } - - if (taosFStatFile(pFile, &size, NULL) < 0) { - terrno = TAOS_SYSTEM_ERROR(errno); - dError("failed to fstat dnode file:%s since %s", file, terrstr()); - goto _OVER; - } - - content = taosMemoryMalloc(size); - if (content == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - goto _OVER; - } - - if (taosReadFile(pFile, content, size) != size) { - terrno = TAOS_SYSTEM_ERROR(errno); - dError("failed to read dnode file:%s since %s", file, terrstr()); - goto _OVER; - } - - dInfo("succeed to read checkCode file:%s", file); - - int len = ENCRYPTED_LEN(size); - result = taosMemoryMalloc(len); - - SCryptOpts opts = {0}; - strncpy(opts.key, key, ENCRYPT_KEY_LEN); - opts.len = len; - opts.source = content; - opts.result = result; - opts.unitLen = 16; - CBC_Decrypt(&opts); - - if(strcmp(opts.result, DM_KEY_INDICATOR) != 0) { - terrno = TSDB_CODE_DNODE_ENCRYPTKEY_CHANGED; - dError("failed to compare decrypted result"); - goto _OVER; - } - - dInfo("succeed to compare checkCode file:%s", file); - code = 0; -_OVER: - if(result != NULL) taosMemoryFree(result); - if(content != NULL) taosMemoryFree(content); - if(pFile != NULL) taosCloseFile(&pFile); - - return code; -} - -static int32_t writeCheckCode(char* file, char* realfile, char* key){ - TdFilePtr pFile = NULL; - char *result = NULL; - int32_t code = -1; - - int32_t len = ENCRYPTED_LEN(sizeof(DM_KEY_INDICATOR)); - result = taosMemoryMalloc(len); - - SCryptOpts opts; - strncpy(opts.key, key, ENCRYPT_KEY_LEN); - opts.len = len; - opts.source = DM_KEY_INDICATOR; - opts.result = result; - opts.unitLen = 16; - CBC_Encrypt(&opts); - - pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH); - if (pFile == NULL) goto _OVER; - - if (taosWriteFile(pFile, opts.result, len) <= 0) goto _OVER; - if (taosFsyncFile(pFile) < 0) goto _OVER; - - taosCloseFile(&pFile); - if (taosRenameFile(file, realfile) != 0) goto _OVER; - - dInfo("succeed to write checkCode file:%s", realfile); - code = 0; -_OVER: - if(pFile != NULL) taosCloseFile(&pFile); - if(result != NULL) taosMemoryFree(result); - - return code; -} - -static int32_t readEncryptCode(char* file, char** output){ - TdFilePtr pFile = NULL; - int32_t code = -1; - char *content = NULL; - - pFile = taosOpenFile(file, TD_FILE_READ); - if (pFile == NULL) { - terrno = TAOS_SYSTEM_ERROR(errno); - dError("failed to open dnode file:%s since %s", file, terrstr()); - goto _OVER; - } - - int64_t size = 0; - if (taosFStatFile(pFile, &size, NULL) < 0) { - terrno = TAOS_SYSTEM_ERROR(errno); - dError("failed to fstat dnode file:%s since %s", file, terrstr()); - goto _OVER; - } - - content = taosMemoryMalloc(size + 1); - if (content == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - goto _OVER; - } - - if (taosReadFile(pFile, content, size) != size) { - terrno = TAOS_SYSTEM_ERROR(errno); - dError("failed to read dnode file:%s since %s", file, terrstr()); - goto _OVER; - } - - content[size] = '\0'; - - *output = content; - - dInfo("succeed to read encryptCode file:%s", file); - code = 0; -_OVER: - if(pFile != NULL) taosCloseFile(&pFile); - - return code; -} - -static int32_t writeEncryptCode(char* file, char* realfile, char* encryptCode){ - TdFilePtr pFile = NULL; - int32_t code = -1; - - pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH); - if (pFile == NULL) goto _OVER; - - int32_t len = strlen(encryptCode); - if (taosWriteFile(pFile, encryptCode, len) <= 0) goto _OVER; - if (taosFsyncFile(pFile) < 0) goto _OVER; - - taosCloseFile(&pFile); - if (taosRenameFile(file, realfile) != 0) goto _OVER; - - dInfo("succeed to write encryptCode file:%s", realfile); - - code = 0; -_OVER: - if(pFile != NULL) taosCloseFile(&pFile); - - return code; -} - -static int32_t getEncryptKey(){ - int32_t code = -1; - char encryptFile[PATH_MAX] = {0}; - char checkFile[PATH_MAX] = {0}; - - snprintf(encryptFile, sizeof(encryptFile), "%s%sdnode%s%s", tsDataDir, TD_DIRSEP, TD_DIRSEP, DM_ENCRYPT_CODE_FILE); - snprintf(checkFile, sizeof(checkFile), "%s%sdnode%s%s", tsDataDir, TD_DIRSEP, TD_DIRSEP, DM_CHECK_CODE_FILE); - - if(!taosCheckExistFile(encryptFile)){ - dInfo("no exist, checkCode file:%s", encryptFile); - return 0; - } - - char *content = NULL; - if(readEncryptCode(encryptFile, &content) != 0){ - goto _OVER; - } - - //TODO: dmchen parse key from code - - strncpy(tsEncryptKey, content, ENCRYPT_KEY_LEN); - - taosMemoryFreeClear(content); - - if(tsEncryptKey[0] == '\0'){ - terrno = TSDB_CODE_DNODE_INVALID_ENCRYPTKEY; - dError("failed to read key since %s", terrstr()); - goto _OVER; - } - - if(compareCheckCode(checkFile, tsEncryptKey) != 0){ - goto _OVER; - } - - code = 0; -_OVER: - if (content != NULL) taosMemoryFree(content); - if (code != 0) { - if (terrno == 0) terrno = TAOS_SYSTEM_ERROR(errno); - dError("failed to get encrypt key since %s", terrstr()); - } - return code; -} - -int32_t updateEncryptKey(char *key) { - int32_t code = -1; - - char folder[PATH_MAX] = {0}; - - char encryptFile[PATH_MAX] = {0}; - char realEncryptFile[PATH_MAX] = {0}; - - char checkFile[PATH_MAX] = {0}; - char realCheckFile[PATH_MAX] = {0}; - - snprintf(folder, sizeof(folder), "%s%sdnode", tsDataDir, TD_DIRSEP); - snprintf(encryptFile, sizeof(realEncryptFile), "%s%s%s.bak", folder, TD_DIRSEP, DM_ENCRYPT_CODE_FILE); - snprintf(realEncryptFile, sizeof(realEncryptFile), "%s%s%s", folder, TD_DIRSEP, DM_ENCRYPT_CODE_FILE); - snprintf(checkFile, sizeof(checkFile), "%s%s%s.bak", folder, TD_DIRSEP, DM_CHECK_CODE_FILE); - snprintf(realCheckFile, sizeof(realCheckFile), "%s%s%s", folder, TD_DIRSEP, DM_CHECK_CODE_FILE); - - terrno = 0; - - if (taosMkDir(folder) != 0) { - terrno = TAOS_SYSTEM_ERROR(errno); - dError("failed to create dir:%s since %s", folder, terrstr()); - goto _OVER; - } - - if(taosCheckExistFile(realCheckFile)){ - if(compareCheckCode(realCheckFile, key) != 0){ - goto _OVER; - } - } - - if(writeEncryptCode(encryptFile, realEncryptFile, key) != 0){ - goto _OVER; - } - - if(writeCheckCode(checkFile, realCheckFile, key) != 0){ - goto _OVER; - } - - code = 0; -_OVER: - - if (code != 0) { - if (terrno == 0) terrno = TAOS_SYSTEM_ERROR(errno); - dError("failed to update encrypt key since %s", terrstr()); - } - return code; -} - int main(int argc, char const *argv[]) { #ifdef TD_JEMALLOC_ENABLED bool jeBackgroundThread = true; diff --git a/source/dnode/mgmt/node_util/inc/dmUtil.h b/source/dnode/mgmt/node_util/inc/dmUtil.h index 49bae11eab..46a13b8715 100644 --- a/source/dnode/mgmt/node_util/inc/dmUtil.h +++ b/source/dnode/mgmt/node_util/inc/dmUtil.h @@ -193,7 +193,8 @@ void dmSetMnodeEpSet(SDnodeData *pData, SEpSet *pEpSet); bool dmUpdateDnodeInfo(void *pData, int32_t *dnodeId, int64_t *clusterId, char *fqdn, uint16_t *port); void dmRemoveDnodePairs(SDnodeData *pData); void dmGetDnodeEp(void *pData, int32_t dnodeId, char *pEp, char *pFqdn, uint16_t *pPort); - +int32_t updateEncryptKey(char *key); +int32_t getEncryptKey(); #ifdef __cplusplus } #endif diff --git a/source/dnode/mgmt/node_util/src/dmFile.c b/source/dnode/mgmt/node_util/src/dmFile.c index 5cbeeebc14..40394526e1 100644 --- a/source/dnode/mgmt/node_util/src/dmFile.c +++ b/source/dnode/mgmt/node_util/src/dmFile.c @@ -16,8 +16,13 @@ #define _DEFAULT_SOURCE #include "dmUtil.h" #include "tjson.h" +#include "tgrant.h" +#include "crypt.h" #define MAXLEN 1024 +#define DM_KEY_INDICATOR "this indicator!" +#define DM_ENCRYPT_CODE_FILE "encryptCode.cfg" +#define DM_CHECK_CODE_FILE "checkCode.bin" static int32_t dmDecodeFile(SJson *pJson, bool *deployed) { int32_t code = 0; @@ -177,3 +182,268 @@ TdFilePtr dmCheckRunning(const char *dataDir) { dDebug("lock file:%s to prevent repeated starts", filepath); return pFile; } + +extern int32_t generateEncryptCode(const char *key, const char *machineId, char **encryptCode); + +static int32_t writeCheckCode(char* file, char* realfile, char* key){ + TdFilePtr pFile = NULL; + char *result = NULL; + int32_t code = -1; + + int32_t len = ENCRYPTED_LEN(sizeof(DM_KEY_INDICATOR)); + result = taosMemoryMalloc(len); + + SCryptOpts opts; + strncpy(opts.key, key, ENCRYPT_KEY_LEN); + opts.len = len; + opts.source = DM_KEY_INDICATOR; + opts.result = result; + opts.unitLen = 16; + CBC_Encrypt(&opts); + + pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH); + if (pFile == NULL) goto _OVER; + + if (taosWriteFile(pFile, opts.result, len) <= 0) goto _OVER; + if (taosFsyncFile(pFile) < 0) goto _OVER; + + taosCloseFile(&pFile); + if (taosRenameFile(file, realfile) != 0) goto _OVER; + + dInfo("succeed to write checkCode file:%s", realfile); + code = 0; +_OVER: + if(pFile != NULL) taosCloseFile(&pFile); + if(result != NULL) taosMemoryFree(result); + + return code; +} + +static int32_t writeEncryptCode(char* file, char* realfile, char* encryptCode){ + TdFilePtr pFile = NULL; + int32_t code = -1; + + pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH); + if (pFile == NULL) goto _OVER; + + int32_t len = strlen(encryptCode); + if (taosWriteFile(pFile, encryptCode, len) <= 0) goto _OVER; + if (taosFsyncFile(pFile) < 0) goto _OVER; + + taosCloseFile(&pFile); + if (taosRenameFile(file, realfile) != 0) goto _OVER; + + dInfo("succeed to write encryptCode file:%s", realfile); + + code = 0; +_OVER: + if(pFile != NULL) taosCloseFile(&pFile); + + return code; +} + +static int32_t compareCheckCode(char* file, char* key){ + char *content = NULL; + int64_t size = 0; + TdFilePtr pFile = NULL; + char *result = NULL; + int32_t code = -1; + + pFile = taosOpenFile(file, TD_FILE_READ); + if (pFile == NULL) { + terrno = TAOS_SYSTEM_ERROR(errno); + dError("failed to open dnode file:%s since %s", file, terrstr()); + goto _OVER; + } + + if (taosFStatFile(pFile, &size, NULL) < 0) { + terrno = TAOS_SYSTEM_ERROR(errno); + dError("failed to fstat dnode file:%s since %s", file, terrstr()); + goto _OVER; + } + + content = taosMemoryMalloc(size); + if (content == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + goto _OVER; + } + + if (taosReadFile(pFile, content, size) != size) { + terrno = TAOS_SYSTEM_ERROR(errno); + dError("failed to read dnode file:%s since %s", file, terrstr()); + goto _OVER; + } + + dInfo("succeed to read checkCode file:%s", file); + + int len = ENCRYPTED_LEN(size); + result = taosMemoryMalloc(len); + + SCryptOpts opts = {0}; + strncpy(opts.key, key, ENCRYPT_KEY_LEN); + opts.len = len; + opts.source = content; + opts.result = result; + opts.unitLen = 16; + CBC_Decrypt(&opts); + + if(strcmp(opts.result, DM_KEY_INDICATOR) != 0) { + terrno = TSDB_CODE_DNODE_ENCRYPTKEY_CHANGED; + dError("failed to compare decrypted result"); + goto _OVER; + } + + dInfo("succeed to compare checkCode file:%s", file); + code = 0; +_OVER: + if(result != NULL) taosMemoryFree(result); + if(content != NULL) taosMemoryFree(content); + if(pFile != NULL) taosCloseFile(&pFile); + + return code; +} + +int32_t updateEncryptKey(char *key) { + int32_t code = -1; + + char folder[PATH_MAX] = {0}; + + char encryptFile[PATH_MAX] = {0}; + char realEncryptFile[PATH_MAX] = {0}; + + char checkFile[PATH_MAX] = {0}; + char realCheckFile[PATH_MAX] = {0}; + + snprintf(folder, sizeof(folder), "%s%sdnode", tsDataDir, TD_DIRSEP); + snprintf(encryptFile, sizeof(realEncryptFile), "%s%s%s.bak", folder, TD_DIRSEP, DM_ENCRYPT_CODE_FILE); + snprintf(realEncryptFile, sizeof(realEncryptFile), "%s%s%s", folder, TD_DIRSEP, DM_ENCRYPT_CODE_FILE); + snprintf(checkFile, sizeof(checkFile), "%s%s%s.bak", folder, TD_DIRSEP, DM_CHECK_CODE_FILE); + snprintf(realCheckFile, sizeof(realCheckFile), "%s%s%s", folder, TD_DIRSEP, DM_CHECK_CODE_FILE); + + terrno = 0; + + if (taosMkDir(folder) != 0) { + terrno = TAOS_SYSTEM_ERROR(errno); + dError("failed to create dir:%s since %s", folder, terrstr()); + goto _OVER; + } + + if(taosCheckExistFile(realCheckFile)){ + if(compareCheckCode(realCheckFile, key) != 0){ + goto _OVER; + } + } + + //TODO: dmchen parse key from code + char* encryptCode = NULL; + //generateEncryptCode(key, tGetMachineId(), &encryptCode); + + if(writeEncryptCode(encryptFile, realEncryptFile, encryptCode) != 0){ + goto _OVER; + } + + if(writeCheckCode(checkFile, realCheckFile, key) != 0){ + goto _OVER; + } + + code = 0; +_OVER: + + if (code != 0) { + if (terrno == 0) terrno = TAOS_SYSTEM_ERROR(errno); + dError("failed to update encrypt key since %s", terrstr()); + } + return code; +} + +extern int32_t checkAndGetCryptKey(const char *encryptCode, const char *machineId, char **key); + +static int32_t readEncryptCode(char* file, char** output){ + TdFilePtr pFile = NULL; + int32_t code = -1; + char *content = NULL; + + pFile = taosOpenFile(file, TD_FILE_READ); + if (pFile == NULL) { + terrno = TAOS_SYSTEM_ERROR(errno); + dError("failed to open dnode file:%s since %s", file, terrstr()); + goto _OVER; + } + + int64_t size = 0; + if (taosFStatFile(pFile, &size, NULL) < 0) { + terrno = TAOS_SYSTEM_ERROR(errno); + dError("failed to fstat dnode file:%s since %s", file, terrstr()); + goto _OVER; + } + + content = taosMemoryMalloc(size + 1); + if (content == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + goto _OVER; + } + + if (taosReadFile(pFile, content, size) != size) { + terrno = TAOS_SYSTEM_ERROR(errno); + dError("failed to read dnode file:%s since %s", file, terrstr()); + goto _OVER; + } + + content[size] = '\0'; + + *output = content; + + dInfo("succeed to read encryptCode file:%s", file); + code = 0; +_OVER: + if(pFile != NULL) taosCloseFile(&pFile); + + return code; +} + +int32_t getEncryptKey(){ + int32_t code = -1; + char encryptFile[PATH_MAX] = {0}; + char checkFile[PATH_MAX] = {0}; + + snprintf(encryptFile, sizeof(encryptFile), "%s%sdnode%s%s", tsDataDir, TD_DIRSEP, TD_DIRSEP, DM_ENCRYPT_CODE_FILE); + snprintf(checkFile, sizeof(checkFile), "%s%sdnode%s%s", tsDataDir, TD_DIRSEP, TD_DIRSEP, DM_CHECK_CODE_FILE); + + if(!taosCheckExistFile(encryptFile)){ + dInfo("no exist, checkCode file:%s", encryptFile); + return 0; + } + + char *content = NULL; + if(readEncryptCode(encryptFile, &content) != 0){ + goto _OVER; + } + + //TODO: dmchen parse key from code + //checkAndGetCryptKey(content, tGetMachineId(), (char**)&tsEncryptKey); + + //TODO: dmchen checksum + strncpy(tsEncryptKey, content, ENCRYPT_KEY_LEN); + tsEncryptionKeyStat = ENCRYPT_KEY_STAT_LOADED; + + taosMemoryFreeClear(content); + + if(tsEncryptKey[0] == '\0'){ + terrno = TSDB_CODE_DNODE_INVALID_ENCRYPTKEY; + dError("failed to read key since %s", terrstr()); + goto _OVER; + } + + if(compareCheckCode(checkFile, tsEncryptKey) != 0){ + goto _OVER; + } + + code = 0; +_OVER: + if (content != NULL) taosMemoryFree(content); + if (code != 0) { + if (terrno == 0) terrno = TAOS_SYSTEM_ERROR(errno); + dError("failed to get encrypt key since %s", terrstr()); + } + return code; +} \ No newline at end of file