From 3e9b7b3401447532640abecebf01402f8d64998c Mon Sep 17 00:00:00 2001 From: benthompson15 Date: Fri, 6 Nov 2020 15:23:24 -0600 Subject: [PATCH] Initial commit for Encode/Decode. --- dbcon/execplan/functioncolumn.cpp | 17 +++++-- dbcon/execplan/functioncolumn.h | 1 + utils/funcexp/CMakeLists.txt | 5 ++- utils/funcexp/func_decode.cpp | 71 ++++++++++++++++++++++++++++++ utils/funcexp/func_encode.cpp | 73 +++++++++++++++++++++++++++++++ utils/funcexp/funcexp.cpp | 2 + utils/funcexp/functor_str.h | 59 +++++++++++++++++++++++++ utils/funcexp/sql_crypt.cpp | 56 ++++++++++++++++++++++++ utils/funcexp/sql_crypt.h | 40 +++++++++++++++++ 9 files changed, 320 insertions(+), 4 deletions(-) create mode 100644 utils/funcexp/func_decode.cpp create mode 100644 utils/funcexp/func_encode.cpp create mode 100644 utils/funcexp/sql_crypt.cpp create mode 100644 utils/funcexp/sql_crypt.h diff --git a/dbcon/execplan/functioncolumn.cpp b/dbcon/execplan/functioncolumn.cpp index beaddc967..4826a8c53 100644 --- a/dbcon/execplan/functioncolumn.cpp +++ b/dbcon/execplan/functioncolumn.cpp @@ -42,6 +42,7 @@ using namespace boost; #include "funcexp.h" #include "functor_export.h" +#include "functor_str.h" using namespace funcexp; #ifdef _MSC_VER @@ -97,7 +98,10 @@ FunctionColumn::FunctionColumn( const FunctionColumn& rhs, const uint32_t sessio } FunctionColumn::~FunctionColumn() -{} +{ + if (fDynamicFunctor) + delete fDynamicFunctor; +} /** * Methods @@ -306,9 +310,16 @@ void FunctionColumn::unserialize(messageqcpp::ByteStream& b) // @bug 3506. Special treatment for rand() function. reset the seed Func_rand* rand = dynamic_cast(fFunctor); - if (rand) - rand->seedSet(false); + fFunctor = fDynamicFunctor = new Func_rand(); + + Func_encode* encode = dynamic_cast(fFunctor); + if (encode) + fFunctor = fDynamicFunctor = new Func_encode(); + + Func_decode* decode = dynamic_cast(fFunctor); + if (decode) + fFunctor = fDynamicFunctor = new Func_decode(); } bool FunctionColumn::operator==(const FunctionColumn& t) const diff --git a/dbcon/execplan/functioncolumn.h b/dbcon/execplan/functioncolumn.h index 2326840d5..760b934e8 100644 --- a/dbcon/execplan/functioncolumn.h +++ b/dbcon/execplan/functioncolumn.h @@ -314,6 +314,7 @@ public: private: funcexp::FunctionParm fFunctionParms; funcexp::Func* fFunctor; /// functor to execute this function + funcexp::Func* fDynamicFunctor = NULL; // for rand encode decode }; /** diff --git a/utils/funcexp/CMakeLists.txt b/utils/funcexp/CMakeLists.txt index 8d194f105..9898d440b 100644 --- a/utils/funcexp/CMakeLists.txt +++ b/utils/funcexp/CMakeLists.txt @@ -30,8 +30,10 @@ set(funcexp_LIB_SRCS func_dayname.cpp func_dayofweek.cpp func_dayofyear.cpp + func_decode.cpp func_div.cpp func_elt.cpp + func_encode.cpp func_exp.cpp func_extract.cpp func_find_in_set.cpp @@ -106,7 +108,8 @@ set(funcexp_LIB_SRCS func_week.cpp func_weekday.cpp func_year.cpp - func_yearweek.cpp) + func_yearweek.cpp + sql_crypt.cpp) add_library(funcexp SHARED ${funcexp_LIB_SRCS}) diff --git a/utils/funcexp/func_decode.cpp b/utils/funcexp/func_decode.cpp new file mode 100644 index 000000000..e73d84818 --- /dev/null +++ b/utils/funcexp/func_decode.cpp @@ -0,0 +1,71 @@ +#include +#include +using namespace std; + +#include "functor_str.h" +#include "funchelpers.h" +#include "functioncolumn.h" +using namespace execplan; + +namespace funcexp +{ + +void Func_decode::hash_password(ulong *result, const char *password, uint password_len) +{ + ulong nr=1345345333L, add=7, nr2=0x12345671L; + ulong tmp; + const char *password_end= password + password_len; + for (; password < password_end; password++) + { + if (*password == ' ' || *password == '\t') + continue; + tmp= (ulong) (unsigned char) *password; + nr^= (((nr & 63)+add)*tmp)+ (nr << 8); + nr2+=(nr2 << 8) ^ nr; + add+=tmp; + } + result[0]=nr & (((ulong) 1L << 31) -1L); + result[1]=nr2 & (((ulong) 1L << 31) -1L); +} + +CalpontSystemCatalog::ColType Func_decode::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType ) +{ + return resultType; +} + +string Func_decode::getStrVal(rowgroup::Row& row, + FunctionParm& parm, + bool& isNull, + CalpontSystemCatalog::ColType&) +{ + const string& str = parm[0]->data()->getStrVal(row, isNull); + if (isNull) + { + return ""; + } + const string& password = parm[1]->data()->getStrVal(row, isNull); + if (isNull) + { + return ""; + } + + int nStrLen = str.length(); + int nPassLen = password.length(); + char res[nStrLen+1]; + memset(res,0,nStrLen+1); + + if (!fSeeded) + { + hash_password(fSeeds, password.c_str(), nPassLen); + sql_crypt.init(fSeeds); + fSeeded = true; + } + + memcpy(res,str.c_str(),nStrLen); + sql_crypt.decode(res,nStrLen); + sql_crypt.reinit(); + + return res; +} + +} diff --git a/utils/funcexp/func_encode.cpp b/utils/funcexp/func_encode.cpp new file mode 100644 index 000000000..20cda7665 --- /dev/null +++ b/utils/funcexp/func_encode.cpp @@ -0,0 +1,73 @@ +#include +#include +using namespace std; + +#include "functor_str.h" +#include "funchelpers.h" +#include "functioncolumn.h" +using namespace execplan; + +namespace funcexp +{ + +void Func_encode::hash_password(ulong *result, const char *password, uint password_len) +{ + ulong nr=1345345333L, add=7, nr2=0x12345671L; + ulong tmp; + const char *password_end= password + password_len; + for (; password < password_end; password++) + { + if (*password == ' ' || *password == '\t') + continue; + tmp= (ulong) (unsigned char) *password; + nr^= (((nr & 63)+add)*tmp)+ (nr << 8); + nr2+=(nr2 << 8) ^ nr; + add+=tmp; + } + result[0]=nr & (((ulong) 1L << 31) -1L); + result[1]=nr2 & (((ulong) 1L << 31) -1L); +} + +CalpontSystemCatalog::ColType Func_encode::operationType( FunctionParm& fp, CalpontSystemCatalog::ColType& resultType ) +{ + return resultType; +} + +string Func_encode::getStrVal(rowgroup::Row& row, + FunctionParm& parm, + bool& isNull, + CalpontSystemCatalog::ColType&) +{ + + + const string& str = parm[0]->data()->getStrVal(row, isNull); + if (isNull) + { + return ""; + } + const string& password = parm[1]->data()->getStrVal(row, isNull); + if (isNull) + { + return ""; + } + + int nStrLen = str.length(); + int nPassLen = password.length(); + char res[nStrLen+1]; + memset(res,0,nStrLen+1); + + if (!fSeeded) + { + hash_password(fSeeds, password.c_str(), nPassLen); + sql_crypt.init(fSeeds); + fSeeded = true; + } + + memcpy(res,str.c_str(),nStrLen); + sql_crypt.encode(res,nStrLen); + sql_crypt.reinit(); + + return res; +} + +} diff --git a/utils/funcexp/funcexp.cpp b/utils/funcexp/funcexp.cpp index 3cf0373b9..6b33bad6e 100644 --- a/utils/funcexp/funcexp.cpp +++ b/utils/funcexp/funcexp.cpp @@ -111,9 +111,11 @@ FuncExp::FuncExp() fFuncMap["dayofmonth"] = new Func_day(); //dlh fFuncMap["dayofweek"] = new Func_dayofweek(); //dlh fFuncMap["dayofyear"] = new Func_dayofyear(); //dlh + fFuncMap["decode"] = new Func_decode(); // BT fFuncMap["degrees"] = new Func_degrees(); fFuncMap["DIV"] = new Func_div(); // MySQL use upper case for this function name fFuncMap["elt"] = new Func_elt(); + fFuncMap["encode"] = new Func_encode(); // BT fFuncMap["exp"] = new Func_exp(); fFuncMap["extract"] = new Func_extract(); //dlh fFuncMap["find_in_set"] = new Func_find_in_set(); diff --git a/utils/funcexp/functor_str.h b/utils/funcexp/functor_str.h index 8706f918d..8229aab8a 100644 --- a/utils/funcexp/functor_str.h +++ b/utils/funcexp/functor_str.h @@ -24,6 +24,7 @@ #define FUNCTOR_STR_H #include "functor.h" +#include "sql_crypt.h" namespace funcexp { @@ -882,6 +883,64 @@ public: execplan::CalpontSystemCatalog::ColType& op_ct); }; +/** @brief Func_encode class + */ + +class Func_encode : public Func_Str +{ +public: + Func_encode() : Func_Str("encode") , fSeeded(false) , fSeeds{0,0} {} + virtual ~Func_encode() {} + + execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType); + + std::string getStrVal(rowgroup::Row& row, + FunctionParm& fp, + bool& isNull, + execplan::CalpontSystemCatalog::ColType& op_ct); + + void resetSeed() + { + fSeeded = false; + fSeeds[0] = 0; + fSeeds[1] = 0; + } +private: + void hash_password(ulong *result, const char *password, uint password_len); + bool fSeeded; + SQL_CRYPT sql_crypt; + ulong fSeeds[2]; +}; + +/** @brief Func_encode class + */ + +class Func_decode : public Func_Str +{ +public: + Func_decode() : Func_Str("decode") , fSeeded(false) , fSeeds{0,0} {} + virtual ~Func_decode() {} + + execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType); + + std::string getStrVal(rowgroup::Row& row, + FunctionParm& fp, + bool& isNull, + execplan::CalpontSystemCatalog::ColType& op_ct); + + void resetSeed() + { + fSeeded = false; + fSeeds[0] = 0; + fSeeds[1] = 0; + } +private: + void hash_password(ulong *result, const char *password, uint password_len); + bool fSeeded; + SQL_CRYPT sql_crypt; + ulong fSeeds[2]; +}; + } #endif diff --git a/utils/funcexp/sql_crypt.cpp b/utils/funcexp/sql_crypt.cpp new file mode 100644 index 000000000..24dd9392c --- /dev/null +++ b/utils/funcexp/sql_crypt.cpp @@ -0,0 +1,56 @@ +#include +#include +using namespace std; + +#include "sql_crypt.h" + +namespace funcexp +{ + +void SQL_CRYPT::init(ulong *rand_nr) +{ + uint i; + my_rnd_init(&rand,rand_nr[0],rand_nr[1]); + + for (i=0 ; i<=255; i++) + decode_buff[i]= (char) i; + + for (i=0 ; i<= 255 ; i++) + { + int idx= (uint) (my_rnd(&rand)*255.0); + char a= decode_buff[idx]; + decode_buff[idx]= decode_buff[i]; + decode_buff[+i]=a; + } + for (i=0 ; i <= 255 ; i++) + encode_buff[(unsigned char) decode_buff[i]]=i; + org_rand=rand; + shift=0; +} + + +void SQL_CRYPT::encode(char *str,uint length) +{ + for (uint i=0; i < length; i++) + { + shift^=(uint) (my_rnd(&rand)*255.0); + uint idx= (uint) (unsigned char) str[0]; + *str++ = (char) ((unsigned char) encode_buff[idx] ^ shift); + shift^= idx; + } +} + + +void SQL_CRYPT::decode(char *str,uint length) +{ + for (uint i=0; i < length; i++) + { + shift^=(uint) (my_rnd(&rand)*255.0); + uint idx= (uint) ((unsigned char) str[0] ^ shift); + *str = decode_buff[idx]; + shift^= (uint) (unsigned char) *str++; + } +} + +} + diff --git a/utils/funcexp/sql_crypt.h b/utils/funcexp/sql_crypt.h new file mode 100644 index 000000000..dbcba424a --- /dev/null +++ b/utils/funcexp/sql_crypt.h @@ -0,0 +1,40 @@ +#ifndef _SQL_CRYPT_H_ +#define _SQL_CRYPT_H_ + +//#include "my_global.h" +/* Macros to make switching between C and C++ mode easier */ +#ifdef __cplusplus +#define C_MODE_START extern "C" { +#define C_MODE_END } +#else +#define C_MODE_START +#define C_MODE_END +#endif +#include "my_rnd.h" + +namespace funcexp +{ + +class SQL_CRYPT +{ + struct my_rnd_struct rand,org_rand; + char decode_buff[256],encode_buff[256]; + uint shift; + + public: + SQL_CRYPT() {} + SQL_CRYPT(ulong *seed) + { + init(seed); + } + ~SQL_CRYPT() {} + void init(ulong *seed); + void reinit() { shift=0; rand=org_rand; } + void encode(char *str, uint length); + void decode(char *str, uint length); +}; + +} + + +#endif /* _SQL_CRYPT_H_ */