1 /*
2 * Copyright (c) 2021 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 #include "softbus_log.h"
17
18 #include <regex.h>
19 #include <securec.h>
20 #include <string.h>
21
22 #include "softbus_adapter_mem.h"
23 #include "softbus_common.h"
24 #include "softbus_errcode.h"
25 #include "softbus_feature_config.h"
26 #include "softbus_utils.h"
27
28 #define LOG_NAME_MAX_LEN 5
29 #ifndef SOFTBUS_DEBUG
30 #define LOG_PRINT_MAX_LEN 256
31 #else
32 #define LOG_PRINT_MAX_LEN 512
33 #endif
34
35 // anonymize should mask more than half of the string
36 #define EXPECTED_ANONYMIZED_TIMES 2
37
38 #define PMATCH_SIZE 2
39 #define REG_ID_PATTERN "[0-9A-Za-z]{64}"
40 #define REG_IDT_PATTERN "\\\"[0-9A-Za-z]{32}\\\""
41 #define REG_IP_PATTERN "[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}"
42 #define REG_MAC_PATTERN "([0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}"
43 #define REG_KEY_PATTERN "[0-9A-Za-z+-//]{43}="
44 #define REG_PATTERN_MAX_LEN 256
45 #define INLEN_MULTIPLE_FACTOR 2
46
47 #define PLAINTEXT_LEN_SHORT 1
48 #define PLAINTEXT_LEN_NORMAL 4
49 #define ANONYMIZE_LEN 6
50 #define SHORT_ID_LENGTH 20
51 #define SESSION_NAME_DEVICE_ID_LEN 96
52 #define SESSION_NAME_DEVICE_PATTERN "([0-9A-Z]{32}){1,3}"
53 #define CUST_NSTACKX_DFINDER_LOG 5
54
55 static int32_t g_logLevel;
56
57 typedef struct {
58 SoftBusLogModule mod;
59 char name[LOG_NAME_MAX_LEN];
60 } LogInfo;
61
62 typedef enum {
63 ANONYMIZE_NORMAL = 1,
64 ANONYMIZE_ENHANCE
65 } AnonymizeMode;
66
67 static LogInfo g_logInfo[SOFTBUS_LOG_MODULE_MAX] = {
68 {SOFTBUS_LOG_AUTH, "AUTH"},
69 {SOFTBUS_LOG_TRAN, "TRAN"},
70 {SOFTBUS_LOG_CONN, "CONN"},
71 {SOFTBUS_LOG_LNN, "LNN"},
72 {SOFTBUS_LOG_DISC, "DISC"},
73 {SOFTBUS_LOG_COMM, "COMM"},
74 };
75
NstackxLog(const char * moduleName,uint32_t nstackLevel,const char * format,...)76 NO_SANITIZE("cfi") void NstackxLog(const char *moduleName, uint32_t nstackLevel, const char *format, ...)
77 {
78 uint32_t ulPos;
79 uint32_t level = CUST_NSTACKX_DFINDER_LOG - nstackLevel;
80 char szStr[LOG_PRINT_MAX_LEN] = {0};
81 va_list arg;
82 int32_t ret;
83
84 if (moduleName == NULL || level >= SOFTBUS_LOG_LEVEL_MAX) {
85 HILOG_ERROR(SOFTBUS_HILOG_ID, "Nstackx log moduleName or level error");
86 return;
87 }
88
89 SoftbusGetConfig(SOFTBUS_INT_ADAPTER_LOG_LEVEL, (unsigned char *)&g_logLevel, sizeof(g_logLevel));
90 if ((int32_t)level < g_logLevel) {
91 return;
92 }
93
94 ret = sprintf_s(szStr, sizeof(szStr), "[%s]", moduleName);
95 if (ret < 0) {
96 HILOG_ERROR(SOFTBUS_HILOG_ID, "Nstackx log error");
97 return;
98 }
99 ulPos = strlen(szStr);
100 (void)memset_s(&arg, sizeof(va_list), 0, sizeof(va_list));
101 va_start(arg, format);
102 ret = vsprintf_s(&szStr[ulPos], sizeof(szStr) - ulPos, format, arg);
103 va_end(arg);
104 if (ret < 0) {
105 HILOG_WARN(SOFTBUS_HILOG_ID, "Nstackx log len error");
106 return;
107 }
108 SoftBusOutPrint(szStr, (SoftBusLogLevel)level);
109
110 return;
111 }
112
SoftBusLogImpl(SoftBusLogModule module,SoftBusLogLevel level,const char * funcName,int lineNo,const char * fmt,...)113 NO_SANITIZE("cfi") void SoftBusLogImpl(SoftBusLogModule module, SoftBusLogLevel level, const char* funcName,
114 int lineNo, const char *fmt, ...)
115 {
116 uint32_t ulPos;
117 char szStr[LOG_PRINT_MAX_LEN] = {0};
118 va_list arg;
119 int32_t ret;
120
121 if (module >= SOFTBUS_LOG_MODULE_MAX || level >= SOFTBUS_LOG_LEVEL_MAX) {
122 HILOG_ERROR(SOFTBUS_HILOG_ID, "[COMM]softbus log type or module error");
123 return;
124 }
125
126 SoftbusGetConfig(SOFTBUS_INT_ADAPTER_LOG_LEVEL, (unsigned char *)&g_logLevel, sizeof(g_logLevel));
127 if ((int32_t)level < g_logLevel) {
128 return;
129 }
130
131 ret = sprintf_s(szStr, sizeof(szStr), "[%s][%s:%d]", g_logInfo[module].name, funcName, lineNo);
132 if (ret < 0) {
133 HILOG_ERROR(SOFTBUS_HILOG_ID, "[COMM]softbus log error");
134 return;
135 }
136 ulPos = strlen(szStr);
137 (void)memset_s(&arg, sizeof(va_list), 0, sizeof(va_list));
138 va_start(arg, fmt);
139 ret = vsprintf_s(&szStr[ulPos], sizeof(szStr) - ulPos, fmt, arg);
140 va_end(arg);
141 if (ret < 0) {
142 HILOG_WARN(SOFTBUS_HILOG_ID, "[COMM]softbus log len error");
143 return;
144 }
145 SoftBusOutPrint(szStr, level);
146
147 return;
148 }
149
Anonymizes(const char * target,const uint8_t expectAnonymizedLength)150 NO_SANITIZE("cfi") const char *Anonymizes(const char *target, const uint8_t expectAnonymizedLength)
151 {
152 if (target == NULL) {
153 return "NULL";
154 }
155 if (expectAnonymizedLength == 0) {
156 return "BADLENGTH";
157 }
158 size_t targetLen = strlen(target);
159 if (targetLen / expectAnonymizedLength < EXPECTED_ANONYMIZED_TIMES) {
160 return "TOOSHORT";
161 }
162
163 return target + (targetLen - expectAnonymizedLength);
164 }
165
AnonymizeRegInit(regex_t * preg,const char * pattern)166 static int32_t AnonymizeRegInit(regex_t *preg, const char *pattern)
167 {
168 if (regcomp(preg, pattern, REG_EXTENDED) != 0) {
169 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "init anonymize reg: compile reg pattern fail");
170 return SOFTBUS_ERR;
171 }
172 return SOFTBUS_OK;
173 }
174
AnonymizeRegDeinit(regex_t * preg)175 static void AnonymizeRegDeinit(regex_t *preg)
176 {
177 regfree(preg);
178 }
179
AnonymizeStringProcess(char * str,size_t len,AnonymizeMode mode)180 static int32_t AnonymizeStringProcess(char *str, size_t len, AnonymizeMode mode)
181 {
182 if (len < ANONYMIZE_LEN || mode == ANONYMIZE_ENHANCE) {
183 if (strcpy_s(str, len, "******") != EOK) {
184 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "anonymize string: strncpy fail.");
185 return SOFTBUS_MEM_ERR;
186 }
187 } else {
188 uint32_t plaintextLen = len < SHORT_ID_LENGTH ? PLAINTEXT_LEN_SHORT : PLAINTEXT_LEN_NORMAL;
189 if (memset_s(str + plaintextLen, len - plaintextLen, '*', ANONYMIZE_LEN) != EOK) {
190 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "anonymize string: memset fail.");
191 return SOFTBUS_MEM_ERR;
192 }
193 uint32_t offset = plaintextLen + ANONYMIZE_LEN;
194 if (strncpy_s(str + offset, len - offset, str + len - plaintextLen, plaintextLen) != EOK) {
195 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "anonymize string: strncpy fail.");
196 return SOFTBUS_MEM_ERR;
197 }
198 }
199 return SOFTBUS_OK;
200 }
201
AnonymizeString(char ** output,const char * in,size_t inLen,const char * pattern,AnonymizeMode mode)202 static int32_t AnonymizeString(char **output, const char *in, size_t inLen, const char *pattern, AnonymizeMode mode)
203 {
204 if (in == NULL) {
205 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "anonymize string: in is null");
206 return SOFTBUS_INVALID_PARAM;
207 }
208
209 char *str = (char *)SoftBusCalloc(inLen + 1);
210 if (str == NULL) {
211 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "anonymize string: malloc fail.");
212 return SOFTBUS_MEM_ERR;
213 }
214 if (strcpy_s(str, inLen + 1, in) != EOK) {
215 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "anonymize string: strcpy fail.");
216 SoftBusFree(str);
217 return SOFTBUS_MEM_ERR;
218 }
219 regex_t preg;
220 if (AnonymizeRegInit(&preg, pattern) != SOFTBUS_OK) {
221 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "anonymize string: init reg failed.");
222 SoftBusFree(str);
223 return SOFTBUS_ERR;
224 }
225 regmatch_t pmatch[PMATCH_SIZE];
226 (void)memset_s(pmatch, sizeof(regmatch_t) * PMATCH_SIZE, 0, sizeof(regmatch_t) * PMATCH_SIZE);
227 char *outexec = str;
228 do {
229 if (regexec(&preg, outexec, PMATCH_SIZE, pmatch, 0) != 0) {
230 break;
231 }
232 regoff_t start = pmatch[0].rm_so;
233 regoff_t end = pmatch[0].rm_eo;
234 if (start != end) {
235 if (AnonymizeStringProcess(outexec + start, end - start, mode) != SOFTBUS_OK) {
236 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "anonymizeStringProcess fail");
237 SoftBusFree(str);
238 AnonymizeRegDeinit(&preg);
239 return SOFTBUS_ERR;
240 }
241 int32_t offset = start + (int32_t)strlen(outexec + start);
242 char tmpStr[inLen + 1];
243 if (strcpy_s(tmpStr, inLen + 1, outexec + end) != EOK || strcat_s(str, inLen, tmpStr) != EOK) {
244 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "anonymize string: strcat fail.");
245 break;
246 }
247 outexec += offset;
248 }
249 } while (true);
250 *output = str;
251 AnonymizeRegDeinit(&preg);
252 return SOFTBUS_OK;
253 }
254
AnonyPacketPrintout(SoftBusLogModule module,const char * msg,const char * packet,size_t packetLen)255 NO_SANITIZE("cfi") void AnonyPacketPrintout(SoftBusLogModule module, const char *msg, const char *packet,
256 size_t packetLen)
257 {
258 if (!GetSignalingMsgSwitch()) {
259 return;
260 }
261 if (msg == NULL) {
262 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "anonymize packet: msg is null.");
263 return;
264 }
265 if (packet == NULL || packetLen == 0) {
266 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "anonymize packet: packet is null.");
267 return;
268 }
269 if (packetLen > LOG_PRINT_MAX_LEN * INLEN_MULTIPLE_FACTOR) {
270 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "anonymize packet: packet is too long.");
271 return;
272 }
273
274 #ifdef __LITEOS_M__
275 SoftBusLog(module, SOFTBUS_LOG_INFO, "%s******", msg);
276 #else
277 char pattern[REG_PATTERN_MAX_LEN] = {0};
278 if (sprintf_s(pattern, REG_PATTERN_MAX_LEN, "%s|%s|%s|%s|%s",
279 REG_ID_PATTERN, REG_IDT_PATTERN, REG_IP_PATTERN, REG_MAC_PATTERN, REG_KEY_PATTERN) < 0) {
280 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "anonymize packet: concatenate reg pattern fail");
281 return;
282 }
283 char *anonymizedOut = NULL;
284 int32_t ret = AnonymizeString(&anonymizedOut, packet, packetLen, pattern, ANONYMIZE_NORMAL);
285 if (ret == SOFTBUS_OK) {
286 SoftBusLog(module, SOFTBUS_LOG_INFO, "%s%s", msg, anonymizedOut);
287 SoftBusFree(anonymizedOut);
288 }
289 #endif
290 }
291
AnonyDevId(char ** outName,const char * inName)292 NO_SANITIZE("cfi") const char *AnonyDevId(char **outName, const char *inName)
293 {
294 if (inName == NULL) {
295 return "null";
296 }
297 if (strlen(inName) < SESSION_NAME_DEVICE_ID_LEN) {
298 return inName;
299 }
300 #ifdef __LITEOS_M__
301 return "******";
302 #else
303 if (AnonymizeString(outName, inName, strlen(inName), SESSION_NAME_DEVICE_PATTERN, ANONYMIZE_NORMAL) != SOFTBUS_OK) {
304 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "anony sessionname fail.");
305 return "******";
306 }
307 return *outName;
308 #endif
309 }
310
StringAppend(char * dst,uint32_t size,const char * src,uint32_t start,uint32_t nSize)311 static inline void StringAppend(char *dst, uint32_t size, const char *src, uint32_t start, uint32_t nSize)
312 {
313 uint32_t len = strlen(dst);
314 if (strncpy_s(dst + len, size - len, src + start, nSize) != EOK) {
315 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "strncpy_s outputStr fail.");
316 }
317 }
318
ToSecureStrDeviceID(const char * deviceId,char ** outputStr)319 NO_SANITIZE("cfi") const char *ToSecureStrDeviceID(const char *deviceId, char **outputStr)
320 {
321 #define SECURE_PRINT_PREFIX_LEN 4
322 #define SECURE_PRINT_SUFFIX_LEN 4
323 #define SECURE_PRINT_STARKEY_SIZE 3
324 if (deviceId == NULL || outputStr == NULL) {
325 return "unknown";
326 }
327 uint32_t deviceIdLen = strlen(deviceId);
328 if (deviceIdLen < SECURE_PRINT_PREFIX_LEN + SECURE_PRINT_SUFFIX_LEN) {
329 return "unknown";
330 }
331 uint32_t outputSize = SECURE_PRINT_PREFIX_LEN + SECURE_PRINT_SUFFIX_LEN + SECURE_PRINT_STARKEY_SIZE + 1;
332 *outputStr = (char *)SoftBusCalloc(outputSize);
333 if (*outputStr == NULL) {
334 SoftBusLog(SOFTBUS_LOG_COMM, SOFTBUS_LOG_ERROR, "malloc outputStr fail.");
335 return "unknown";
336 }
337 StringAppend(*outputStr, outputSize, deviceId, 0, SECURE_PRINT_PREFIX_LEN);
338 StringAppend(*outputStr, outputSize, "***", 0, SECURE_PRINT_STARKEY_SIZE);
339 StringAppend(*outputStr, outputSize, deviceId, deviceIdLen - SECURE_PRINT_SUFFIX_LEN, SECURE_PRINT_SUFFIX_LEN);
340 return *outputStr;
341 }