diff --git a/include/common/tmsg.h b/include/common/tmsg.h index c27dd2f78f..897870ef3f 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -1089,7 +1089,7 @@ typedef struct { char* sql; int8_t isImport; int8_t createDb; - char longPass[TSDB_USET_PASSWORD_LONGLEN]; + int8_t passIsMd5; } SCreateUserReq; int32_t tSerializeSCreateUserReq(void* buf, int32_t bufLen, SCreateUserReq* pReq); @@ -1160,7 +1160,7 @@ typedef struct { int64_t privileges; int32_t sqlLen; char* sql; - char longPass[TSDB_USET_PASSWORD_LONGLEN]; + int8_t passIsMd5; } SAlterUserReq; int32_t tSerializeSAlterUserReq(void* buf, int32_t bufLen, SAlterUserReq* pReq); @@ -3533,6 +3533,7 @@ typedef struct { SArray* rsps; // SArray SMonitorParas monitorParas; int8_t enableAuditDelete; + int8_t enableStrongPass; } SClientHbBatchRsp; static FORCE_INLINE uint32_t hbKeyHashFunc(const char* key, uint32_t keyLen) { return taosIntHash_64(key, keyLen); } diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 2543a1f3ec..2e1dc56800 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -113,6 +113,7 @@ typedef struct SQueryExecMetric { typedef struct { SMonitorParas monitorParas; int8_t enableAuditDelete; + int8_t enableStrongPass; } SAppInstServerCFG; struct SAppInstInfo { int64_t numOfConns; diff --git a/source/client/src/clientHb.c b/source/client/src/clientHb.c index b3e288c816..274b7df032 100644 --- a/source/client/src/clientHb.c +++ b/source/client/src/clientHb.c @@ -608,6 +608,8 @@ static int32_t hbAsyncCallBack(void *param, SDataBuf *pMsg, int32_t code) { pInst->serverCfg.monitorParas = pRsp.monitorParas; pInst->serverCfg.enableAuditDelete = pRsp.enableAuditDelete; + pInst->serverCfg.enableStrongPass = pRsp.enableStrongPass; + tsEnableStrongPassword = pInst->serverCfg.enableStrongPass; tscDebug("[monitor] paras from hb, clusterId:%" PRIx64 " monitorParas threshold:%d scope:%d", pInst->clusterId, pRsp.monitorParas.tsSlowLogThreshold, pRsp.monitorParas.tsSlowLogScope); diff --git a/source/common/src/msg/tmsg.c b/source/common/src/msg/tmsg.c index b54e3c10a1..8bd1ff4f4c 100644 --- a/source/common/src/msg/tmsg.c +++ b/source/common/src/msg/tmsg.c @@ -575,6 +575,7 @@ int32_t tSerializeSClientHbBatchRsp(void *buf, int32_t bufLen, const SClientHbBa } TAOS_CHECK_EXIT(tSerializeSMonitorParas(&encoder, &pBatchRsp->monitorParas)); TAOS_CHECK_EXIT(tEncodeI8(&encoder, pBatchRsp->enableAuditDelete)); + TAOS_CHECK_EXIT(tEncodeI8(&encoder, pBatchRsp->enableStrongPass)); tEndEncode(&encoder); _exit: @@ -623,6 +624,12 @@ int32_t tDeserializeSClientHbBatchRsp(void *buf, int32_t bufLen, SClientHbBatchR pBatchRsp->enableAuditDelete = 0; } + if (!tDecodeIsEnd(&decoder)) { + TAOS_CHECK_EXIT(tDecodeI8(&decoder, &pBatchRsp->enableStrongPass)); + } else { + pBatchRsp->enableStrongPass = 1; + } + tEndDecode(&decoder); _exit: @@ -2007,7 +2014,7 @@ int32_t tSerializeSCreateUserReq(void *buf, int32_t bufLen, SCreateUserReq *pReq ENCODESQL(); TAOS_CHECK_EXIT(tEncodeI8(&encoder, pReq->isImport)); TAOS_CHECK_EXIT(tEncodeI8(&encoder, pReq->createDb)); - TAOS_CHECK_EXIT(tEncodeCStr(&encoder, pReq->longPass)); + TAOS_CHECK_EXIT(tEncodeI8(&encoder, pReq->passIsMd5)); tEndEncode(&encoder); @@ -2049,7 +2056,7 @@ int32_t tDeserializeSCreateUserReq(void *buf, int32_t bufLen, SCreateUserReq *pR TAOS_CHECK_EXIT(tDecodeI8(&decoder, &pReq->isImport)); } if (!tDecodeIsEnd(&decoder)) { - TAOS_CHECK_EXIT(tDecodeCStrTo(&decoder, pReq->longPass)); + TAOS_CHECK_EXIT(tDecodeI8(&decoder, &pReq->passIsMd5)); } tEndDecode(&decoder); @@ -2406,7 +2413,7 @@ int32_t tSerializeSAlterUserReq(void *buf, int32_t bufLen, SAlterUserReq *pReq) TAOS_CHECK_EXIT(tEncodeI64(&encoder, pReq->privileges)); ENCODESQL(); TAOS_CHECK_EXIT(tEncodeU8(&encoder, pReq->flag)); - TAOS_CHECK_EXIT(tEncodeCStr(&encoder, pReq->longPass)); + TAOS_CHECK_EXIT(tEncodeU8(&encoder, pReq->passIsMd5)); tEndEncode(&encoder); _exit: @@ -2459,7 +2466,7 @@ int32_t tDeserializeSAlterUserReq(void *buf, int32_t bufLen, SAlterUserReq *pReq TAOS_CHECK_EXIT(tDecodeU8(&decoder, &pReq->flag)); } if (!tDecodeIsEnd(&decoder)) { - TAOS_CHECK_EXIT(tDecodeCStrTo(&decoder, pReq->longPass)); + TAOS_CHECK_EXIT(tDecodeU8(&decoder, &pReq->passIsMd5)); } tEndDecode(&decoder); diff --git a/source/dnode/mnode/impl/src/mndProfile.c b/source/dnode/mnode/impl/src/mndProfile.c index 8fe36ca0c4..fc8ff4bea7 100644 --- a/source/dnode/mnode/impl/src/mndProfile.c +++ b/source/dnode/mnode/impl/src/mndProfile.c @@ -722,6 +722,7 @@ static int32_t mndProcessHeartBeatReq(SRpcMsg *pReq) { batchRsp.monitorParas.tsSlowLogMaxLen = tsSlowLogMaxLen; batchRsp.monitorParas.tsSlowLogScope = tsSlowLogScope; batchRsp.enableAuditDelete = tsEnableAuditDelete; + batchRsp.enableStrongPass = tsEnableStrongPassword; int32_t sz = taosArrayGetSize(batchReq.reqs); for (int i = 0; i < sz; i++) { diff --git a/source/dnode/mnode/impl/src/mndUser.c b/source/dnode/mnode/impl/src/mndUser.c index 8572c954c8..c7730e8546 100644 --- a/source/dnode/mnode/impl/src/mndUser.c +++ b/source/dnode/mnode/impl/src/mndUser.c @@ -1705,23 +1705,18 @@ static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate int32_t code = 0; int32_t lino = 0; SUserObj userObj = {0}; - char pass[TSDB_USET_PASSWORD_LONGLEN] = {0}; - - int32_t len = strlen(pCreate->longPass); - - if (len > 0) { - strncpy(pass, pCreate->longPass, TSDB_USET_PASSWORD_LONGLEN); - } else { - len = strlen(pCreate->pass); - strncpy(pass, pCreate->pass, TSDB_PASSWORD_LEN); - } if (pCreate->isImport != 1) { - taosEncryptPass_c((uint8_t *)pass, strlen(pass), userObj.pass); + if (pCreate->passIsMd5 == 1) { + memcpy(userObj.pass, pCreate->pass, TSDB_PASSWORD_LEN); + } else { + taosEncryptPass_c((uint8_t *)pCreate->pass, strlen(pCreate->pass), userObj.pass); + } } else { // mInfo("pCreate->pass:%s", pCreate->eass) - memcpy(userObj.pass, pass, TSDB_PASSWORD_LEN); + memcpy(userObj.pass, pCreate->pass, TSDB_PASSWORD_LEN); } + tstrncpy(userObj.user, pCreate->user, TSDB_USER_LEN); tstrncpy(userObj.acct, acct, TSDB_USER_LEN); userObj.createdTime = taosGetTimestampMs(); @@ -1816,52 +1811,6 @@ _OVER: TAOS_RETURN(code); } -static int32_t mndCheckPasswordMinLen(const char *pwd, int32_t len) { - if (len < TSDB_PASSWORD_MIN_LEN) { - return -1; - } - return 0; -} - -static int32_t mndCheckPasswordMaxLen(const char *pwd, int32_t len) { - if (len > TSDB_PASSWORD_MAX_LEN) { - return -1; - } - return 0; -} - -static int32_t mndCheckPasswordFmt(const char *pwd, int32_t len) { - if (strcmp(pwd, "taosdata") == 0) { - return 0; - } - - bool charTypes[4] = {0}; - for (int32_t i = 0; i < len; ++i) { - if (taosIsBigChar(pwd[i])) { - charTypes[0] = true; - } else if (taosIsSmallChar(pwd[i])) { - charTypes[1] = true; - } else if (taosIsNumberChar(pwd[i])) { - charTypes[2] = true; - } else if (taosIsSpecialChar(pwd[i])) { - charTypes[3] = true; - } else { - return -1; - } - } - - int32_t numOfTypes = 0; - for (int32_t i = 0; i < 4; ++i) { - numOfTypes += charTypes[i]; - } - - if (numOfTypes < 3) { - return -1; - } - - return 0; -} - static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) { SMnode *pMnode = pReq->info.node; int32_t code = 0; @@ -1895,31 +1844,6 @@ static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) { TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER); } - char pass[TSDB_USET_PASSWORD_LONGLEN] = {0}; - - int32_t len = strlen(createReq.longPass); - - if (len > 0) { - strncpy(pass, createReq.longPass, TSDB_USET_PASSWORD_LONGLEN); - } else { - len = strlen(createReq.pass); - strncpy(pass, createReq.pass, TSDB_PASSWORD_LEN); - } - - if (createReq.isImport != 1) { - if (mndCheckPasswordMinLen(pass, len) != 0) { - TAOS_CHECK_GOTO(TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY, &lino, _OVER); - } - if (mndCheckPasswordMaxLen(pass, len) != 0) { - TAOS_CHECK_GOTO(TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG, &lino, _OVER); - } - if (tsEnableStrongPassword) { - if (mndCheckPasswordFmt(pass, len) != 0) { - TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_PASS_FORMAT, &lino, _OVER); - } - } - } - code = mndAcquireUser(pMnode, createReq.user, &pUser); if (pUser != NULL) { TAOS_CHECK_GOTO(TSDB_CODE_MND_USER_ALREADY_EXIST, &lino, _OVER); @@ -2399,30 +2323,6 @@ static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) { TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_USER_FORMAT, &lino, _OVER); } - char userSetPass[TSDB_USET_PASSWORD_LONGLEN] = {0}; - int32_t len = strlen(alterReq.longPass); - - if (TSDB_ALTER_USER_PASSWD == alterReq.alterType) { - if (len > 0) { - strncpy(userSetPass, alterReq.longPass, TSDB_USET_PASSWORD_LONGLEN); - } else { - len = strlen(alterReq.pass); - strncpy(userSetPass, alterReq.pass, TSDB_USET_PASSWORD_LEN); - } - - if (mndCheckPasswordMinLen(userSetPass, len) != 0) { - TAOS_CHECK_GOTO(TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY, &lino, _OVER); - } - if (mndCheckPasswordMaxLen(userSetPass, len) != 0) { - TAOS_CHECK_GOTO(TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG, &lino, _OVER); - } - if (tsEnableStrongPassword) { - if (mndCheckPasswordFmt(userSetPass, len) != 0) { - TAOS_CHECK_GOTO(TSDB_CODE_MND_INVALID_PASS_FORMAT, &lino, _OVER); - } - } - } - TAOS_CHECK_GOTO(mndAcquireUser(pMnode, alterReq.user, &pUser), &lino, _OVER); (void)mndAcquireUser(pMnode, pReq->info.conn.user, &pOperUser); @@ -2435,11 +2335,13 @@ static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) { TAOS_CHECK_GOTO(mndUserDupObj(pUser, &newUser), &lino, _OVER); if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) { - char pass[TSDB_PASSWORD_LEN + 1] = {0}; + if (alterReq.passIsMd5 == 1) { + (void)memcpy(newUser.pass, alterReq.pass, TSDB_PASSWORD_LEN); + } else { + taosEncryptPass_c((uint8_t *)alterReq.pass, strlen(alterReq.pass), newUser.pass); + } - taosEncryptPass_c((uint8_t *)userSetPass, len, pass); - (void)memcpy(newUser.pass, pass, TSDB_PASSWORD_LEN); - if (0 != strncmp(pUser->pass, pass, TSDB_PASSWORD_LEN)) { + if (0 != strncmp(pUser->pass, newUser.pass, TSDB_PASSWORD_LEN)) { ++newUser.passVersion; } } diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index 51fa970299..4d9e9d1fb0 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -104,7 +104,37 @@ static bool invalidPassword(const char* pPassword) { /* Execute regular expression */ int32_t res = regexec(®ex, pPassword, 0, NULL, 0); regfree(®ex); - return 0 == res; + if(0 != res) return false; + + if (strcmp(pPassword, "taosdata") == 0) { + return false; + } + + bool charTypes[4] = {0}; + for (int32_t i = 0; i < strlen(pPassword); ++i) { + if (taosIsBigChar(pPassword[i])) { + charTypes[0] = true; + } else if (taosIsSmallChar(pPassword[i])) { + charTypes[1] = true; + } else if (taosIsNumberChar(pPassword[i])) { + charTypes[2] = true; + } else if (taosIsSpecialChar(pPassword[i])) { + charTypes[3] = true; + } else { + return false; + } + } + + int32_t numOfTypes = 0; + for (int32_t i = 0; i < 4; ++i) { + numOfTypes += charTypes[i]; + } + + if (numOfTypes < 3) { + return false; + } + + return true; } static bool checkPassword(SAstCreateContext* pCxt, const SToken* pPasswordToken, char* pPassword) { @@ -115,7 +145,7 @@ static bool checkPassword(SAstCreateContext* pCxt, const SToken* pPasswordToken, } else { strncpy(pPassword, pPasswordToken->z, pPasswordToken->n); (void)strdequote(pPassword); - if (strtrim(pPassword) <= 0) { + if (strtrim(pPassword) < TSDB_PASSWORD_MIN_LEN) { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_PASSWD_TOO_SHORT_OR_EMPTY); } else if (invalidPassword(pPassword)) { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PASSWD); diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index a10ab0be16..dd1fa6c6e8 100755 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -10045,10 +10045,12 @@ static int32_t translateCreateUser(STranslateContext* pCxt, SCreateUserStmt* pSt createReq.superUser = 0; createReq.sysInfo = pStmt->sysinfo; createReq.enable = 1; - tstrncpy(createReq.longPass, pStmt->password, TSDB_USET_PASSWORD_LONGLEN); createReq.isImport = pStmt->isImport; createReq.createDb = pStmt->createDb; + taosEncryptPass_c((uint8_t*)pStmt->password, strlen(pStmt->password), createReq.pass); + createReq.passIsMd5 = 1; + createReq.numIpRanges = pStmt->numIpRanges; if (pStmt->numIpRanges > 0) { createReq.pIpRanges = taosMemoryMalloc(createReq.numIpRanges * sizeof(SIpV4Range)); @@ -10090,7 +10092,10 @@ static int32_t translateAlterUser(STranslateContext* pCxt, SAlterUserStmt* pStmt alterReq.enable = pStmt->enable; alterReq.sysInfo = pStmt->sysinfo; alterReq.createdb = pStmt->createdb ? 1 : 0; - snprintf(alterReq.longPass, sizeof(alterReq.pass), "%s", pStmt->password); + + taosEncryptPass_c((uint8_t*)pStmt->password, strlen(pStmt->password), alterReq.pass); + alterReq.passIsMd5 = 1; + if (NULL != pCxt->pParseCxt->db) { snprintf(alterReq.objname, sizeof(alterReq.objname), "%s", pCxt->pParseCxt->db); } diff --git a/source/libs/parser/test/parAlterToBalanceTest.cpp b/source/libs/parser/test/parAlterToBalanceTest.cpp index e82c0eeab7..172c729f34 100644 --- a/source/libs/parser/test/parAlterToBalanceTest.cpp +++ b/source/libs/parser/test/parAlterToBalanceTest.cpp @@ -833,7 +833,7 @@ TEST_F(ParserInitialATest, alterUser) { ASSERT_EQ(req.sysInfo, expect.sysInfo); ASSERT_EQ(req.enable, expect.enable); ASSERT_EQ(std::string(req.user), std::string(expect.user)); - ASSERT_EQ(std::string(req.longPass), std::string(expect.pass)); + ASSERT_EQ(std::string(req.pass), std::string(expect.pass)); ASSERT_EQ(std::string(req.objname), std::string(expect.objname)); tFreeSAlterUserReq(&req); }); diff --git a/source/libs/parser/test/parInitialCTest.cpp b/source/libs/parser/test/parInitialCTest.cpp index b4d277f5d5..2412bf4e78 100644 --- a/source/libs/parser/test/parInitialCTest.cpp +++ b/source/libs/parser/test/parInitialCTest.cpp @@ -1362,7 +1362,7 @@ TEST_F(ParserInitialCTest, createUser) { ASSERT_EQ(req.sysInfo, expect.sysInfo); ASSERT_EQ(req.enable, expect.enable); ASSERT_EQ(std::string(req.user), std::string(expect.user)); - ASSERT_EQ(std::string(req.longPass), std::string(expect.pass)); + ASSERT_EQ(std::string(req.pass), std::string(expect.pass)); tFreeSCreateUserReq(&req); }); diff --git a/tests/army/cluster/strongPassword.py b/tests/army/cluster/strongPassword.py index 01dba7f394..dc6dbd7c7e 100644 --- a/tests/army/cluster/strongPassword.py +++ b/tests/army/cluster/strongPassword.py @@ -38,11 +38,24 @@ class TDTestCase(TBase): # change setting tdSql.execute("ALTER ALL DNODES 'enableStrongPassword' '0'") + time.sleep(3) + # weak tdSql.execute("create user test1 pass '12345678' sysinfo 0;") tdSql.execute("alter user test1 pass '12345678';") + # pass length + tdSql.error("alter user test1 pass '1234567';", expectErrInfo="Password too short or empty") + + tdSql.error("create user test2 pass '1234567' sysinfo 0;", expectErrInfo="Password too short or empty") + + tdSql.error("create user test2 pass '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456' sysinfo 0;", expectErrInfo="Name or password too long") + + tdSql.execute("create user test2 pass '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345' sysinfo 0;") + + tdSql.error("alter user test2 pass '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456';", expectErrInfo="Name or password too long") + def stop(self): tdSql.close() tdLog.success(f"{__file__} successfully executed")