feat: support encryption
This commit is contained in:
parent
d6ae4d37cc
commit
9e4d692d6b
|
@ -58,9 +58,11 @@ typedef enum {
|
|||
TSDB_GRANT_BACKUP_RESTORE,
|
||||
} EGrantType;
|
||||
|
||||
int32_t checkAndGetCryptKey(const char *encryptCode, const char *machineId, char **key);
|
||||
int32_t generateEncryptCode(const char *key, const char *machineId, char **encryptCode);
|
||||
int32_t grantCheck(EGrantType grant);
|
||||
int32_t grantCheckExpire(EGrantType grant);
|
||||
char* tGetMachineId();
|
||||
char *tGetMachineId();
|
||||
|
||||
// #ifndef GRANTS_CFG
|
||||
#ifdef TD_ENTERPRISE
|
||||
|
|
|
@ -296,8 +296,6 @@ typedef enum ELogicConditionType {
|
|||
#define TSDB_DNODE_CONFIG_LEN 128
|
||||
#define TSDB_DNODE_VALUE_LEN 256
|
||||
|
||||
#define TSDB_ENCRYPT_KEY_LEN 16
|
||||
|
||||
#define TSDB_CLUSTER_VALUE_LEN 1000
|
||||
#define TSDB_GRANT_LOG_COL_LEN 15600
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ int64_t tsDndUpTime = 0;
|
|||
|
||||
// dnode misc
|
||||
uint32_t tsEncryptionKeyChksum = 0;
|
||||
int8_t tsEncryptionKeyStat = ENCRYPT_KEY_STAT_LOADED; //ENCRYPT_KEY_STAT_UNKNOWN;
|
||||
int8_t tsEncryptionKeyStat = ENCRYPT_KEY_STAT_UNKNOWN;
|
||||
int8_t tsGrant = 1;
|
||||
|
||||
// monitor
|
||||
|
|
|
@ -57,6 +57,7 @@ int32_t dmProcessServerRunStatus(SDnodeMgmt *pMgmt, SRpcMsg *pMsg);
|
|||
int32_t dmProcessRetrieve(SDnodeMgmt *pMgmt, SRpcMsg *pMsg);
|
||||
int32_t dmProcessGrantReq(void *pInfo, SRpcMsg *pMsg);
|
||||
int32_t dmProcessGrantNotify(void *pInfo, SRpcMsg *pMsg);
|
||||
int32_t dmProcessCreateEncryptKeyReq(SDnodeMgmt *pMgmt, SRpcMsg *pMsg);
|
||||
|
||||
// dmWorker.c
|
||||
int32_t dmPutNodeMsgToMgmtQueue(SDnodeMgmt *pMgmt, SRpcMsg *pMsg);
|
||||
|
|
|
@ -224,6 +224,26 @@ int32_t dmProcessConfigReq(SDnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t dmProcessCreateEncryptKeyReq(SDnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
||||
#ifdef TD_ENTERPRISE
|
||||
int32_t code = 0;
|
||||
SDCfgDnodeReq cfgReq = {0};
|
||||
if (tDeserializeSDCfgDnodeReq(pMsg->pCont, pMsg->contLen, &cfgReq) != 0) {
|
||||
code = TSDB_CODE_INVALID_MSG;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
code = updateEncryptKey(cfgReq.value);
|
||||
|
||||
pMsg->code = code;
|
||||
pMsg->info.rsp = NULL;
|
||||
pMsg->info.rspLen = 0;
|
||||
_exit:
|
||||
return code;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dmGetServerRunStatus(SDnodeMgmt *pMgmt, SServerStatusRsp *pStatus) {
|
||||
pStatus->statusCode = TSDB_SRV_STATUS_SERVICE_OK;
|
||||
pStatus->details[0] = 0;
|
||||
|
|
|
@ -359,6 +359,9 @@ static void dmProcessMgmtQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) {
|
|||
case TDMT_MND_GRANT_NOTIFY:
|
||||
code = dmProcessGrantNotify(NULL, pMsg);
|
||||
break;
|
||||
case TDMT_DND_CREATE_ENCRYPT_KEY:
|
||||
code = dmProcessCreateEncryptKeyReq(pMgmt, pMsg);
|
||||
break;
|
||||
default:
|
||||
terrno = TSDB_CODE_MSG_NOT_PROCESSED;
|
||||
dGError("msg:%p, not processed in mgmt queue", pMsg);
|
||||
|
|
|
@ -113,6 +113,7 @@ SArray *mmGetMsgHandles() {
|
|||
if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_VNODE_TYPE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_DND_CHECK_VNODE_LEARNER_CATCHUP_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_SYNC_CONFIG_CHANGE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_ENCRYPT_KEY_RSP, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||
|
||||
if (dmSetMgmtHandle(pArray, TDMT_MND_CONNECT, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_ACCT, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "dmUtil.h"
|
||||
#include "tchecksum.h"
|
||||
#include "tjson.h"
|
||||
#include "tgrant.h"
|
||||
#include "crypt.h"
|
||||
|
@ -304,15 +305,17 @@ _OVER:
|
|||
}
|
||||
|
||||
int32_t updateEncryptKey(char *key) {
|
||||
int32_t code = -1;
|
||||
int32_t code = -1;
|
||||
char *machineId = NULL;
|
||||
char *encryptCode = NULL;
|
||||
|
||||
char folder[PATH_MAX] = {0};
|
||||
char folder[PATH_MAX] = {0};
|
||||
|
||||
char encryptFile[PATH_MAX] = {0};
|
||||
char realEncryptFile[PATH_MAX] = {0};
|
||||
char encryptFile[PATH_MAX] = {0};
|
||||
char realEncryptFile[PATH_MAX] = {0};
|
||||
|
||||
char checkFile[PATH_MAX] = {0};
|
||||
char realCheckFile[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);
|
||||
|
@ -335,8 +338,14 @@ int32_t updateEncryptKey(char *key) {
|
|||
}
|
||||
|
||||
//TODO: dmchen parse key from code
|
||||
char* encryptCode = NULL;
|
||||
//generateEncryptCode(key, tGetMachineId(), &encryptCode);
|
||||
if (!(machineId = tGetMachineId())) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (generateEncryptCode(key, machineId, &encryptCode) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if(writeEncryptCode(encryptFile, realEncryptFile, encryptCode) != 0){
|
||||
goto _OVER;
|
||||
|
@ -346,9 +355,13 @@ int32_t updateEncryptKey(char *key) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
tsEncryptionKeyChksum = taosCalcChecksum(0, key, strlen(key));
|
||||
tsEncryptionKeyStat = ENCRYPT_KEY_STAT_LOADED;
|
||||
|
||||
code = 0;
|
||||
_OVER:
|
||||
|
||||
taosMemoryFree(encryptCode);
|
||||
taosMemoryFree(machineId);
|
||||
if (code != 0) {
|
||||
if (terrno == 0) terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
dError("failed to update encrypt key since %s", terrstr());
|
||||
|
|
|
@ -104,6 +104,13 @@ typedef struct {
|
|||
int64_t timeseriesAllowed;
|
||||
} SGrantInfo;
|
||||
|
||||
typedef struct {
|
||||
int8_t encrypting;
|
||||
int16_t nEncrypt;
|
||||
int16_t nSuccess;
|
||||
int16_t nFailed;
|
||||
} SEncryptMgmt;
|
||||
|
||||
typedef struct SMnode {
|
||||
int32_t selfDnodeId;
|
||||
int64_t clusterId;
|
||||
|
@ -114,7 +121,6 @@ typedef struct SMnode {
|
|||
bool stopped;
|
||||
bool restored;
|
||||
bool deploy;
|
||||
int8_t encrypting;
|
||||
char *path;
|
||||
int64_t checkTime;
|
||||
SyncIndex applied;
|
||||
|
@ -128,6 +134,7 @@ typedef struct SMnode {
|
|||
SProfileMgmt profileMgmt;
|
||||
STelemMgmt telemMgmt;
|
||||
SSyncMgmt syncMgmt;
|
||||
SEncryptMgmt encryptMgmt;
|
||||
SGrantInfo grant;
|
||||
MndMsgFp msgFp[TDMT_MAX];
|
||||
SMsgCb msgCb;
|
||||
|
|
|
@ -80,6 +80,7 @@ static int32_t mndProcessStatusReq(SRpcMsg *pReq);
|
|||
static int32_t mndProcessNotifyReq(SRpcMsg *pReq);
|
||||
static int32_t mndProcessRestoreDnodeReq(SRpcMsg *pReq);
|
||||
static int32_t mndProcessStatisReq(SRpcMsg *pReq);
|
||||
static int32_t mndProcessCreateEncryptKeyRsp(SRpcMsg *pRsp);
|
||||
|
||||
static int32_t mndRetrieveConfigs(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
|
||||
static void mndCancelGetNextConfig(SMnode *pMnode, void *pIter);
|
||||
|
@ -116,6 +117,7 @@ int32_t mndInitDnode(SMnode *pMnode) {
|
|||
mndSetMsgHandle(pMnode, TDMT_MND_SHOW_VARIABLES, mndProcessShowVariablesReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_RESTORE_DNODE, mndProcessRestoreDnodeReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_STATIS, mndProcessStatisReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_DND_CREATE_ENCRYPT_KEY_RSP, mndProcessCreateEncryptKeyRsp);
|
||||
|
||||
mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_CONFIGS, mndRetrieveConfigs);
|
||||
mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_CONFIGS, mndCancelGetNextConfig);
|
||||
|
@ -468,7 +470,7 @@ static int32_t mndCheckClusterCfgPara(SMnode *pMnode, SDnodeObj *pDnode, const S
|
|||
return DND_REASON_ENABLE_WHITELIST_NOT_MATCH;
|
||||
}
|
||||
|
||||
if (!atomic_load_8(&pMnode->encrypting) &&
|
||||
if (!atomic_load_8(&pMnode->encryptMgmt.encrypting) &&
|
||||
(pCfg->encryptionKeyStat != tsEncryptionKeyStat || pCfg->encryptionKeyChksum != tsEncryptionKeyChksum)) {
|
||||
mError("dnode:%d, encryptionKey:%" PRIi8 "-%u inconsistent with cluster:%" PRIi8 "-%u", pDnode->id,
|
||||
pCfg->encryptionKeyStat, pCfg->encryptionKeyChksum, tsEncryptionKeyStat, tsEncryptionKeyChksum);
|
||||
|
@ -1407,32 +1409,49 @@ _err:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int32_t mndProcessCreateEncryptKeyReq(SMnode *pMnode, int32_t dnodeId, SDCfgDnodeReq *pDcfgReq) {
|
||||
static int32_t mndProcessCreateEncryptKeyReq(SRpcMsg *pReq, int32_t dnodeId, SDCfgDnodeReq *pDcfgReq) {
|
||||
int32_t code = 0;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
int8_t encrypting = 0;
|
||||
|
||||
if (0 != atomic_val_compare_exchange_8(&pMnode->encrypting, 0, 1)) {
|
||||
const STraceId *trace = &pReq->info.traceId;
|
||||
if (0 != (encrypting = atomic_val_compare_exchange_8(&pMnode->encryptMgmt.encrypting, 0, 1))) {
|
||||
mGWarn("msg:%p, failed to create encrypt key since %s, encrypting:%" PRIi8, pReq, tstrerror(code), encrypting);
|
||||
code = TSDB_CODE_QRY_DUPLICATED_OPERATION;
|
||||
return code; // don't use go to exit since encrypting is released in _exit
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
if (tsEncryptionKeyStat == ENCRYPT_KEY_STAT_SET || tsEncryptionKeyStat == ENCRYPT_KEY_STAT_LOADED) {
|
||||
code = TSDB_CODE_QRY_DUPLICATED_OPERATION;
|
||||
atomic_store_8(&pMnode->encryptMgmt.encrypting, 0);
|
||||
mGWarn("msg:%p, failed to create encrypt key since %s, stat:%" PRIi8 ", checksum:%u", pReq, tstrerror(code),
|
||||
tsEncryptionKeyStat, tsEncryptionKeyChksum);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
atomic_store_16(&pMnode->encryptMgmt.nEncrypt, 0);
|
||||
atomic_store_16(&pMnode->encryptMgmt.nSuccess, 0);
|
||||
atomic_store_16(&pMnode->encryptMgmt.nFailed, 0);
|
||||
|
||||
while (1) {
|
||||
SDnodeObj *pDnode = NULL;
|
||||
pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
|
||||
if (pIter == NULL) break;
|
||||
if (pDnode->offlineReason != DND_REASON_ONLINE) continue;
|
||||
|
||||
if (pDnode->id == dnodeId || dnodeId == -1 || dnodeId == 0) {
|
||||
if (dnodeId == -1 || pDnode->id == dnodeId || dnodeId == 0) {
|
||||
SEpSet epSet = mndGetDnodeEpset(pDnode);
|
||||
int32_t bufLen = tSerializeSDCfgDnodeReq(NULL, 0, pDcfgReq);
|
||||
void *pBuf = rpcMallocCont(bufLen);
|
||||
|
||||
if (pBuf != NULL) {
|
||||
tSerializeSDCfgDnodeReq(pBuf, bufLen, pDcfgReq);
|
||||
SRpcMsg rpcMsg = {.msgType = TDMT_DND_CONFIG_DNODE, .pCont = pBuf, .contLen = bufLen};
|
||||
tmsgSendReq(&epSet, &rpcMsg);
|
||||
code = 0;
|
||||
SRpcMsg rpcMsg = {.msgType = TDMT_DND_CREATE_ENCRYPT_KEY, .pCont = pBuf, .contLen = bufLen};
|
||||
if (0 == tmsgSendReq(&epSet, &rpcMsg)) {
|
||||
atomic_add_fetch_16(&pMnode->encryptMgmt.nEncrypt, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1440,7 +1459,6 @@ static int32_t mndProcessCreateEncryptKeyReq(SMnode *pMnode, int32_t dnodeId, SD
|
|||
}
|
||||
|
||||
_exit:
|
||||
atomic_store_8(&pMnode->encrypting, 0);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -1512,16 +1530,16 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
|
|||
snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag);
|
||||
} else if (strncasecmp(cfgReq.config, "encrypt_key", 12) == 0) {
|
||||
int32_t vlen = strlen(cfgReq.value);
|
||||
if (vlen > TSDB_ENCRYPT_KEY_LEN || vlen < 8) {
|
||||
mError("dnode:%d, failed to create encrypt_key since invalid vlen:%d, valid range:[%d, %d]", cfgReq.dnodeId,
|
||||
vlen, 8, TSDB_ENCRYPT_KEY_LEN);
|
||||
if (vlen > ENCRYPT_KEY_LEN || vlen < 8) {
|
||||
mError("dnode:%d, failed to create encrypt_key since invalid vlen:%d, valid range:[%d, %d]", cfgReq.dnodeId, vlen,
|
||||
8, ENCRYPT_KEY_LEN); // ENCRYPT_TODO: range[min, max]
|
||||
terrno = TSDB_CODE_INVALID_CFG;
|
||||
goto _err_out;
|
||||
}
|
||||
strcpy(dcfgReq.config, cfgReq.config);
|
||||
strcpy(dcfgReq.value, cfgReq.value);
|
||||
tFreeSMCfgDnodeReq(&cfgReq);
|
||||
return mndProcessCreateEncryptKeyReq(pMnode, cfgReq.dnodeId, &dcfgReq);
|
||||
return mndProcessCreateEncryptKeyReq(pReq, cfgReq.dnodeId, &dcfgReq);
|
||||
#endif
|
||||
} else {
|
||||
if (mndMCfg2DCfg(&cfgReq, &dcfgReq)) goto _err_out;
|
||||
|
@ -1555,6 +1573,30 @@ static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndProcessCreateEncryptKeyRsp(SRpcMsg *pRsp) {
|
||||
SMnode *pMnode = pRsp->info.node;
|
||||
int16_t nSuccess = 0;
|
||||
int16_t nFailed = 0;
|
||||
|
||||
if (0 == pRsp->code) {
|
||||
nSuccess = atomic_add_fetch_16(&pMnode->encryptMgmt.nSuccess, 1);
|
||||
} else {
|
||||
nFailed = atomic_add_fetch_16(&pMnode->encryptMgmt.nFailed, 1);
|
||||
}
|
||||
|
||||
int16_t nReq = atomic_load_16(&pMnode->encryptMgmt.nEncrypt);
|
||||
bool finished = nSuccess + nFailed >= nReq;
|
||||
|
||||
if (finished) {
|
||||
atomic_store_8(&pMnode->encryptMgmt.encrypting, 0);
|
||||
}
|
||||
|
||||
mInfo("create encrypt key rsp, nReq:%" PRIi16 ", nSucess:%" PRIi16 ", nFailed:%" PRIi16 ", %s", nReq, nSuccess,
|
||||
nFailed, finished ? "encrypt done" : "in encrypting") return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndRetrieveConfigs(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
int32_t totalRows = 0;
|
||||
|
|
|
@ -5574,7 +5574,7 @@ static int32_t checkDatabaseOptions(STranslateContext* pCxt, const char* pDbName
|
|||
TSDB_MAX_DB_WITH_ARBITRATOR);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = checkDbEnumOption(pCxt, "encryptionAlgorithm", pOptions->encryptAlgorithm, TSDB_MIN_ENCRYPT_ALGO,
|
||||
code = checkDbEnumOption(pCxt, "encryptAlgorithm", pOptions->encryptAlgorithm, TSDB_MIN_ENCRYPT_ALGO,
|
||||
TSDB_MAX_ENCRYPT_ALGO);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
|
Loading…
Reference in New Issue