1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #define LOG_TAG "RdbGqlUtils"
17 #include "gdb_utils.h"
18
19 #include <algorithm>
20 #include <securec.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23
24 #include "gdb_errors.h"
25
26 namespace OHOS::DistributedDataAip {
27 constexpr int32_t CONTINUOUS_DIGITS_MINI_SIZE = 5;
28 constexpr int32_t FILE_PATH_MINI_SIZE = 6;
29 constexpr int32_t AREA_MINI_SIZE = 4;
30 constexpr int32_t AREA_OFFSET_SIZE = 5;
31 constexpr int32_t PRE_OFFSET_SIZE = 1;
32 constexpr int32_t PREFIX_POS = 0;
33 constexpr int32_t PREFIX_LEN = 3;
34
IsTransactionGql(const std::string & gql)35 bool GdbUtils::IsTransactionGql(const std::string &gql)
36 {
37 auto prefix = gql.substr(PREFIX_POS, PREFIX_LEN);
38 if (prefix == "STA" || prefix == "COM" || prefix == "ROL") {
39 return true;
40 }
41 return false;
42 }
43
CreateDirectory(const std::string & databaseDir)44 int GdbUtils::CreateDirectory(const std::string &databaseDir)
45 {
46 std::string tempDirectory = databaseDir;
47 std::vector<std::string> directories;
48
49 size_t pos = tempDirectory.find('/');
50 while (pos != std::string::npos) {
51 std::string directory = tempDirectory.substr(0, pos);
52 directories.push_back(directory);
53 tempDirectory = tempDirectory.substr(pos + 1);
54 pos = tempDirectory.find('/');
55 }
56 directories.push_back(tempDirectory);
57
58 std::string databaseDirectory;
59 for (const std::string &directory : directories) {
60 databaseDirectory += "/" + directory;
61 if (access(databaseDirectory.c_str(), F_OK) != 0) {
62 if (mkdir(databaseDirectory.c_str(), DIR_RWXRWS__X)) {
63 return E_CREATE_FOLDER_FAIT;
64 }
65 }
66 }
67 return E_OK;
68 }
69
Anonymous(const std::string & srcFile)70 std::string GdbUtils::Anonymous(const std::string &srcFile)
71 {
72 auto pre = srcFile.find("/");
73 auto end = srcFile.rfind("/");
74 if (pre == std::string::npos || end - pre < FILE_PATH_MINI_SIZE) {
75 return GetAnonymousName(srcFile);
76 }
77 auto path = srcFile.substr(pre, end - pre);
78 auto area = path.find("/el");
79 if (area == std::string::npos || area + AREA_MINI_SIZE > path.size()) {
80 path = "";
81 } else if (area + AREA_OFFSET_SIZE < path.size()) {
82 path = path.substr(area, AREA_MINI_SIZE) + "/***";
83 } else {
84 path = path.substr(area, AREA_MINI_SIZE);
85 }
86 std::string fileName = srcFile.substr(end); // rdb file name
87 fileName = GetAnonymousName(fileName);
88 return srcFile.substr(0, pre + PRE_OFFSET_SIZE) + "***" + path + fileName;
89 }
90
GetAnonymousName(const std::string & fileName)91 std::string GdbUtils::GetAnonymousName(const std::string &fileName)
92 {
93 std::vector<std::string> alnum;
94 std::vector<std::string> noAlnum;
95 std::string alnumStr;
96 std::string noAlnumStr;
97 for (const auto &letter : fileName) {
98 if (isxdigit(letter)) {
99 if (!noAlnumStr.empty()) {
100 noAlnum.push_back(noAlnumStr);
101 noAlnumStr.clear();
102 alnum.push_back("");
103 }
104 alnumStr += letter;
105 } else {
106 if (!alnumStr.empty()) {
107 alnum.push_back(alnumStr);
108 alnumStr.clear();
109 noAlnum.push_back("");
110 }
111 noAlnumStr += letter;
112 }
113 }
114 if (!alnumStr.empty()) {
115 alnum.push_back(alnumStr);
116 noAlnum.push_back("");
117 }
118 if (!noAlnumStr.empty()) {
119 noAlnum.push_back(alnumStr);
120 alnum.push_back("");
121 }
122 std::string res = "";
123 for (size_t i = 0; i < alnum.size(); ++i) {
124 res += (AnonyDigits(alnum[i]) + noAlnum[i]);
125 }
126 return res;
127 }
128
AnonyDigits(const std::string & fileName)129 std::string GdbUtils::AnonyDigits(const std::string &fileName)
130 {
131 std::string::size_type digitsNum = fileName.size();
132 if (digitsNum < CONTINUOUS_DIGITS_MINI_SIZE) {
133 return fileName;
134 }
135 constexpr std::string::size_type longDigits = 7;
136 std::string::size_type endDigitsNum = 4;
137 std::string::size_type shortEndDigitsNum = 3;
138 std::string name = fileName;
139 std::string last = "";
140 if (digitsNum >= CONTINUOUS_DIGITS_MINI_SIZE && digitsNum < longDigits) {
141 last = name.substr(name.size() - shortEndDigitsNum);
142 } else {
143 last = name.substr(name.size() - endDigitsNum);
144 }
145
146 return "***" + last;
147 }
148
ClearAndZeroString(std::string & str)149 void GdbUtils::ClearAndZeroString(std::string &str)
150 {
151 str.clear();
152 std::fill(str.begin(), str.end(), char(0));
153 }
154
GetConfigStr(const std::vector<uint8_t> & keys,bool isEncrypt)155 std::string GdbUtils::GetConfigStr(const std::vector<uint8_t> &keys, bool isEncrypt)
156 {
157 std::string config = "{";
158 if (isEncrypt) {
159 const size_t keyBuffSize = keys.size() * 2 + 1; // 2 hex number can represent a uint8_t, 1 is for '\0'
160 std::vector<char> keyBuff(keyBuffSize);
161 config += "\"isEncrypted\":1,";
162 config += "\"hexPassword\":\"";
163 config += GetEncryptKey(keys, keyBuff.data(), keyBuffSize);
164 config += "\",";
165 keyBuff.assign(keyBuffSize, 0);
166 }
167 config += GRD_OPEN_CONFIG_STR;
168 config += "}";
169 return config;
170 }
171
GetEncryptKey(const std::vector<uint8_t> & encryptedKey,char outBuff[],size_t outBufSize)172 const char *GdbUtils::GetEncryptKey(const std::vector<uint8_t> &encryptedKey, char outBuff[], size_t outBufSize)
173 {
174 char *buffer = nullptr;
175 auto keySize = encryptedKey.size();
176 for (size_t i = 0; i < keySize; i++) {
177 buffer = (char *)(outBuff + i * 2); // each uint8_t will convert to 2 hex char
178 // each uint8_t will convert to 2 hex char
179 errno_t err = snprintf_s(buffer, outBufSize - i * 2, outBufSize - i * 2, "%02x", encryptedKey[i]);
180 if (err < 0) {
181 return nullptr;
182 }
183 }
184 return outBuff;
185 }
186 } // namespace OHOS::DistributedDataAip
187