• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * wpa_supplicant/hostapd / Debug prints
3  * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "includes.h"
10 
11 #include "common.h"
12 
13 #ifdef CONFIG_DEBUG_SYSLOG
14 #include <syslog.h>
15 #endif /* CONFIG_DEBUG_SYSLOG */
16 
17 #ifdef CONFIG_DEBUG_LINUX_TRACING
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include <string.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 
25 static FILE *wpa_debug_tracing_file = NULL;
26 
27 #define WPAS_TRACE_PFX "wpas <%d>: "
28 #endif /* CONFIG_DEBUG_LINUX_TRACING */
29 
30 #define HIDDEN_CHAR '*'
31 int wpa_debug_level = MSG_DEBUG;
32 int wpa_debug_show_keys = 1;
33 int wpa_debug_timestamp = 0;
34 int wpa_debug_syslog = 0;
35 #ifndef CONFIG_NO_STDOUT_DEBUG
36 static FILE *out_file = NULL;
37 #endif /* CONFIG_NO_STDOUT_DEBUG */
38 
39 
40 #ifdef CONFIG_ANDROID_LOG
41 
42 #include <android/log.h>
43 
44 #ifndef ANDROID_LOG_NAME
45 #define ANDROID_LOG_NAME	"wpa_supplicant"
46 #endif /* ANDROID_LOG_NAME */
47 
wpa_to_android_level(int level)48 static int wpa_to_android_level(int level)
49 {
50 	if (level == MSG_ERROR)
51 		return ANDROID_LOG_ERROR;
52 	if (level == MSG_WARNING)
53 		return ANDROID_LOG_WARN;
54 	if (level == MSG_INFO)
55 		return ANDROID_LOG_INFO;
56 	return ANDROID_LOG_DEBUG;
57 }
58 
59 #endif /* CONFIG_ANDROID_LOG */
60 
61 #ifndef CONFIG_NO_STDOUT_DEBUG
62 
63 #ifdef CONFIG_DEBUG_FILE
64 #include <sys/types.h>
65 #include <sys/stat.h>
66 #include <fcntl.h>
67 #endif /* CONFIG_DEBUG_FILE */
68 #define WPA_MAX_ANONYMIZE_LENGTH 256
69 
70 
wpa_debug_print_timestamp(void)71 void wpa_debug_print_timestamp(void)
72 {
73 #ifndef CONFIG_ANDROID_LOG
74 	struct os_time tv;
75 
76 	if (!wpa_debug_timestamp)
77 		return;
78 
79 	os_get_time(&tv);
80 #ifdef CONFIG_DEBUG_FILE
81 	if (out_file)
82 		fprintf(out_file, "%ld.%06u: ", (long) tv.sec,
83 			(unsigned int) tv.usec);
84 #endif /* CONFIG_DEBUG_FILE */
85 	if (!out_file && !wpa_debug_syslog)
86 		printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
87 #endif /* CONFIG_ANDROID_LOG */
88 }
89 
90 
91 #ifdef CONFIG_DEBUG_SYSLOG
92 #ifndef LOG_HOSTAPD
93 #define LOG_HOSTAPD LOG_DAEMON
94 #endif /* LOG_HOSTAPD */
95 
wpa_debug_open_syslog(void)96 void wpa_debug_open_syslog(void)
97 {
98 	openlog("wpa_supplicant", LOG_PID | LOG_NDELAY, LOG_HOSTAPD);
99 	wpa_debug_syslog++;
100 }
101 
102 
wpa_debug_close_syslog(void)103 void wpa_debug_close_syslog(void)
104 {
105 	if (wpa_debug_syslog)
106 		closelog();
107 }
108 
109 
syslog_priority(int level)110 static int syslog_priority(int level)
111 {
112 	switch (level) {
113 	case MSG_MSGDUMP:
114 	case MSG_DEBUG:
115 		return LOG_DEBUG;
116 	case MSG_INFO:
117 		return LOG_NOTICE;
118 	case MSG_WARNING:
119 		return LOG_WARNING;
120 	case MSG_ERROR:
121 		return LOG_ERR;
122 	}
123 	return LOG_INFO;
124 }
125 #endif /* CONFIG_DEBUG_SYSLOG */
126 
127 
128 #ifdef CONFIG_DEBUG_LINUX_TRACING
129 
wpa_debug_open_linux_tracing(void)130 int wpa_debug_open_linux_tracing(void)
131 {
132 	int mounts, trace_fd;
133 	char buf[4096] = {};
134 	ssize_t buflen;
135 	char *line, *tmp1, *path = NULL;
136 
137 	mounts = open("/proc/mounts", O_RDONLY);
138 	if (mounts < 0) {
139 		printf("no /proc/mounts\n");
140 		return -1;
141 	}
142 
143 	buflen = read(mounts, buf, sizeof(buf) - 1);
144 	close(mounts);
145 	if (buflen < 0) {
146 		printf("failed to read /proc/mounts\n");
147 		return -1;
148 	}
149 	buf[buflen] = '\0';
150 
151 	line = strtok_r(buf, "\n", &tmp1);
152 	while (line) {
153 		char *tmp2, *tmp_path, *fstype;
154 		/* "<dev> <mountpoint> <fs type> ..." */
155 		strtok_r(line, " ", &tmp2);
156 		tmp_path = strtok_r(NULL, " ", &tmp2);
157 		fstype = strtok_r(NULL, " ", &tmp2);
158 		if (fstype && strcmp(fstype, "debugfs") == 0) {
159 			path = tmp_path;
160 			break;
161 		}
162 
163 		line = strtok_r(NULL, "\n", &tmp1);
164 	}
165 
166 	if (path == NULL) {
167 		printf("debugfs mountpoint not found\n");
168 		return -1;
169 	}
170 
171 	snprintf(buf, sizeof(buf) - 1, "%s/tracing/trace_marker", path);
172 
173 	trace_fd = open(buf, O_WRONLY);
174 	if (trace_fd < 0) {
175 		printf("failed to open trace_marker file\n");
176 		return -1;
177 	}
178 	wpa_debug_tracing_file = fdopen(trace_fd, "w");
179 	if (wpa_debug_tracing_file == NULL) {
180 		close(trace_fd);
181 		printf("failed to fdopen()\n");
182 		return -1;
183 	}
184 
185 	return 0;
186 }
187 
188 
wpa_debug_close_linux_tracing(void)189 void wpa_debug_close_linux_tracing(void)
190 {
191 	if (wpa_debug_tracing_file == NULL)
192 		return;
193 	fclose(wpa_debug_tracing_file);
194 	wpa_debug_tracing_file = NULL;
195 }
196 
197 #endif /* CONFIG_DEBUG_LINUX_TRACING */
198 
199 #ifdef CONFIG_OPEN_HARMONY_PATCH
200 #include "hilog/log_c.h"
201 #include "parameter.h"
202 
203 #ifdef LOG_DOMAIN
204 #undef LOG_DOMAIN
205 #endif // LOG_DOMAIN
206 #ifdef LOG_TAG
207 #undef LOG_TAG
208 #endif // LOG_TAG
209 #define LOG_DOMAIN 0xD005200
210 #define LOG_TAG "wpa_supplicant"
211 #define WPA_MAX_LOG_CHAR 8196
212 #define WPA_PROP_KEY_DEBUG_ON "persist.sys.wpa_debug_on"
213 #define PARAM_VALUE_MAX_LEN 10
214 
215 enum {
216 	WPA_HILOG_UNKNOWN, WPA_HILOG_UNSET, WPA_HILOG_SET
217 };
218 
219 int32_t wpa_debug_hilog_switch = WPA_HILOG_UNKNOWN;
220 
wpa_get_log_level(int level)221 static int wpa_get_log_level(int level)
222 {
223 	switch (level) {
224 		case MSG_ERROR:
225 			return LOG_ERROR;
226 		case MSG_WARNING:
227 			return LOG_WARN;
228 		case MSG_INFO:
229 			return LOG_INFO;
230 		default:
231 			return LOG_DEBUG;
232 	}
233 }
234 
wpa_can_hilog()235 static bool wpa_can_hilog()
236 {
237 	switch (wpa_debug_hilog_switch) {
238 		case WPA_HILOG_UNSET:
239 			return false;
240 		case WPA_HILOG_SET:
241 			return true;
242 		default:
243 			break;
244 	}
245 
246 	wpa_debug_hilog_switch = WPA_HILOG_SET;
247 	return true;
248 }
249 #endif // CONFIG_OPEN_HARMONY_PATCH
250 
251 /**
252  * wpa_printf - conditional printf
253  * @level: priority level (MSG_*) of the message
254  * @fmt: printf format string, followed by optional arguments
255  *
256  * This function is used to print conditional debugging and error messages. The
257  * output may be directed to stdout, stderr, and/or syslog based on
258  * configuration.
259  *
260  * Note: New line '\n' is added to the end of the text when printing to stdout.
261  */
wpa_printf(int level,const char * fmt,...)262 void wpa_printf(int level, const char *fmt, ...)
263 {
264 #ifdef CONFIG_OPEN_HARMONY_PATCH
265 	if (wpa_can_hilog()) {
266 		int32_t ulPos = 0;
267 		char szStr[WPA_MAX_LOG_CHAR] = {0};
268 		va_list arg = {0};
269 		int32_t ret;
270 
271 		va_start(arg, fmt);
272 		ret = vsprintf(&szStr[ulPos], fmt, arg);
273 		va_end(arg);
274 		if (ret > 0) {
275 			HiLogPrint(LOG_CORE, wpa_get_log_level(level), LOG_DOMAIN, LOG_TAG, "%{public}s", szStr);
276 		}
277 		return;
278 	}
279 #endif
280 
281 #ifdef CONFIG_WPA_NO_LOG
282     return;
283 #else
284 	va_list ap;
285 
286 	if (level >= wpa_debug_level) {
287 #ifdef CONFIG_ANDROID_LOG
288 		va_start(ap, fmt);
289 		__android_log_vprint(wpa_to_android_level(level),
290 				     ANDROID_LOG_NAME, fmt, ap);
291 		va_end(ap);
292 #else /* CONFIG_ANDROID_LOG */
293 #ifdef CONFIG_DEBUG_SYSLOG
294 		if (wpa_debug_syslog) {
295 			va_start(ap, fmt);
296 			vsyslog(syslog_priority(level), fmt, ap);
297 			va_end(ap);
298 		}
299 #endif /* CONFIG_DEBUG_SYSLOG */
300 		wpa_debug_print_timestamp();
301 #ifdef CONFIG_DEBUG_FILE
302 		if (out_file) {
303 			va_start(ap, fmt);
304 			vfprintf(out_file, fmt, ap);
305 			fprintf(out_file, "\n");
306 			va_end(ap);
307 		}
308 #endif /* CONFIG_DEBUG_FILE */
309 		if (!wpa_debug_syslog && !out_file) {
310 			va_start(ap, fmt);
311 			vprintf(fmt, ap);
312 			printf("\n");
313 			va_end(ap);
314 		}
315 #endif /* CONFIG_ANDROID_LOG */
316 	}
317 
318 #ifdef CONFIG_DEBUG_LINUX_TRACING
319 	if (wpa_debug_tracing_file != NULL) {
320 		va_start(ap, fmt);
321 		fprintf(wpa_debug_tracing_file, WPAS_TRACE_PFX, level);
322 		vfprintf(wpa_debug_tracing_file, fmt, ap);
323 		fprintf(wpa_debug_tracing_file, "\n");
324 		fflush(wpa_debug_tracing_file);
325 		va_end(ap);
326 	}
327 #endif /* CONFIG_DEBUG_LINUX_TRACING */
328 #endif /* CONFIG_WPA_NO_LOG */
329 }
330 
331 
_wpa_hexdump(int level,const char * title,const u8 * buf,size_t len,int show,int only_syslog)332 static void _wpa_hexdump(int level, const char *title, const u8 *buf,
333 			 size_t len, int show, int only_syslog)
334 {
335 #ifdef CONFIG_WPA_NO_LOG
336     return;
337 #else
338 	size_t i;
339 #ifdef CONFIG_OPEN_HARMONY_PATCH
340 	if (wpa_can_hilog()) {
341 		const char *display;
342 		char *strbuf = NULL;
343 		size_t slen = len;
344 		if (buf == NULL) {
345 			display = " [NULL]";
346 		} else if (len == 0) {
347 			display = "";
348 		} else if (show && len) {
349 			if (slen > 32)
350 				slen = 32;
351 			strbuf = os_malloc(1 + 3 * slen);
352 			if (strbuf == NULL) {
353 				wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
354 				                      "allocate message buffer");
355 				return;
356 			}
357 
358 			for (i = 0; i < slen; i++)
359 				os_snprintf(&strbuf[i * 3], 4, " %02x",
360 				            buf[i]);
361 
362 			display = strbuf;
363 		} else {
364 			display = " [REMOVED]";
365 		}
366 		HiLogPrint(LOG_CORE, wpa_get_log_level(level), LOG_DOMAIN,
367 		           LOG_TAG, "%{public}s - hexdump(len=%{public}lu):%{public}s%{public}s",
368 		           title, (long unsigned int) len, display,
369 		           len > slen ? " ..." : "");
370 		bin_clear_free(strbuf, 1 + 3 * slen);
371 		return;
372 	}
373 #endif
374 
375 #ifdef CONFIG_DEBUG_LINUX_TRACING
376 	if (wpa_debug_tracing_file != NULL) {
377 		fprintf(wpa_debug_tracing_file,
378 			WPAS_TRACE_PFX "%s - hexdump(len=%lu):",
379 			level, title, (unsigned long) len);
380 		if (buf == NULL) {
381 			fprintf(wpa_debug_tracing_file, " [NULL]\n");
382 		} else if (!show) {
383 			fprintf(wpa_debug_tracing_file, " [REMOVED]\n");
384 		} else {
385 			for (i = 0; i < len; i++)
386 				fprintf(wpa_debug_tracing_file,
387 					" %02x", buf[i]);
388 		}
389 		fflush(wpa_debug_tracing_file);
390 	}
391 #endif /* CONFIG_DEBUG_LINUX_TRACING */
392 
393 	if (level < wpa_debug_level)
394 		return;
395 #ifdef CONFIG_ANDROID_LOG
396 	{
397 		const char *display;
398 		char *strbuf = NULL;
399 		size_t slen = len;
400 		if (buf == NULL) {
401 			display = " [NULL]";
402 		} else if (len == 0) {
403 			display = "";
404 		} else if (show && len) {
405 			/* Limit debug message length for Android log */
406 			if (slen > 32)
407 				slen = 32;
408 			strbuf = os_malloc(1 + 3 * slen);
409 			if (strbuf == NULL) {
410 				wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
411 					   "allocate message buffer");
412 				return;
413 			}
414 
415 			for (i = 0; i < slen; i++)
416 				os_snprintf(&strbuf[i * 3], 4, " %02x",
417 					    buf[i]);
418 
419 			display = strbuf;
420 		} else {
421 			display = " [REMOVED]";
422 		}
423 
424 		__android_log_print(wpa_to_android_level(level),
425 				    ANDROID_LOG_NAME,
426 				    "%s - hexdump(len=%lu):%s%s",
427 				    title, (long unsigned int) len, display,
428 				    len > slen ? " ..." : "");
429 		bin_clear_free(strbuf, 1 + 3 * slen);
430 		return;
431 	}
432 #else /* CONFIG_ANDROID_LOG */
433 #ifdef CONFIG_DEBUG_SYSLOG
434 	if (wpa_debug_syslog) {
435 		const char *display;
436 		char *strbuf = NULL;
437 
438 		if (buf == NULL) {
439 			display = " [NULL]";
440 		} else if (len == 0) {
441 			display = "";
442 		} else if (show && len) {
443 			strbuf = os_malloc(1 + 3 * len);
444 			if (strbuf == NULL) {
445 				wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
446 					   "allocate message buffer");
447 				return;
448 			}
449 
450 			for (i = 0; i < len; i++)
451 				os_snprintf(&strbuf[i * 3], 4, " %02x",
452 					    buf[i]);
453 
454 			display = strbuf;
455 		} else {
456 			display = " [REMOVED]";
457 		}
458 
459 		syslog(syslog_priority(level), "%s - hexdump(len=%lu):%s",
460 		       title, (unsigned long) len, display);
461 		bin_clear_free(strbuf, 1 + 3 * len);
462 		if (only_syslog)
463 			return;
464 	}
465 #endif /* CONFIG_DEBUG_SYSLOG */
466 	wpa_debug_print_timestamp();
467 #ifdef CONFIG_DEBUG_FILE
468 	if (out_file) {
469 		fprintf(out_file, "%s - hexdump(len=%lu):",
470 			title, (unsigned long) len);
471 		if (buf == NULL) {
472 			fprintf(out_file, " [NULL]");
473 		} else if (show) {
474 			for (i = 0; i < len; i++)
475 				fprintf(out_file, " %02x", buf[i]);
476 		} else {
477 			fprintf(out_file, " [REMOVED]");
478 		}
479 		fprintf(out_file, "\n");
480 	}
481 #endif /* CONFIG_DEBUG_FILE */
482 	if (!wpa_debug_syslog && !out_file) {
483 		printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
484 		if (buf == NULL) {
485 			printf(" [NULL]");
486 		} else if (show) {
487 			for (i = 0; i < len; i++)
488 				printf(" %02x", buf[i]);
489 		} else {
490 			printf(" [REMOVED]");
491 		}
492 		printf("\n");
493 	}
494 #endif /* CONFIG_ANDROID_LOG */
495 #endif /* CONFIG_WPA_NO_LOG */
496 }
497 
disable_anonymized_print()498 int disable_anonymized_print()
499 {
500 	char prop[PARAM_VALUE_MAX_LEN] = { 0 };
501 	if (GetParameter(WPA_PROP_KEY_DEBUG_ON, "0", prop, sizeof(prop)) > 0) {
502 		if (atoi(prop) > 0) {
503 			return 1;
504 		}
505 	}
506 	return 0;
507 }
508 
anonymize_ssid(const char * str)509 const char *anonymize_ssid(const char *str)
510 {
511 	if (str == NULL || *str == '\0') {
512 		return str;
513 	}
514 
515 	static char s[WPA_MAX_ANONYMIZE_LENGTH];
516 	int strLen = os_strlen(str);
517 	os_strlcpy(s, str, sizeof(s));
518 
519 	if (disable_anonymized_print()) {
520 		return s;
521 	}
522 	const char hiddenChar = HIDDEN_CHAR;
523 	const int minHiddenSize = 3;
524 	const int headKeepSize = 3;
525 	const int tailKeepSize = 3;
526 
527 	if (strLen < minHiddenSize) {
528 		os_memset(s, hiddenChar, strLen);
529 		return s;
530 	}
531 
532 	if (strLen < minHiddenSize + headKeepSize + tailKeepSize) {
533 		int beginIndex = 1;
534 		int hiddenSize = strLen - minHiddenSize + 1;
535 		hiddenSize = hiddenSize > minHiddenSize ? minHiddenSize : hiddenSize;
536 		os_memset(s + beginIndex, hiddenChar, hiddenSize);
537 		return s;
538 	}
539 	os_memset(s + headKeepSize, hiddenChar, strLen - headKeepSize - tailKeepSize);
540 	return s;
541 }
542 
anonymize_ip(const char * str)543 const char *anonymize_ip(const char *str)
544 {
545 	if (str == NULL || *str == '\0') {
546 		return str;
547 	}
548 	int colonCount = 0;
549 	const int maxDisplayNum = 2;
550 	static char s[40];
551 	int start = 0;
552 	os_strlcpy(s, str, sizeof(s));
553 	if (disable_anonymized_print()) {
554 		return s;
555 	}
556 	// ipv4 or ipv6 anonymize
557 	for (int i = 0; i < os_strlen(s); i++) {
558 		if (s[i] == ':' || s[i] == '.') {
559 			colonCount++;
560 			if (colonCount == maxDisplayNum) {
561 				start = i + 1;
562 			}
563 		}
564 	}
565 	for (int j = start; j < os_strlen(s); j++) {
566 		if (s[j] != ':' && s[j] != '.') {
567 			s[j] = HIDDEN_CHAR;
568 		}
569 	}
570 	return s;
571 }
572 
573 
get_anonymized_result_setnetwork(const char * str)574 const char *get_anonymized_result_setnetwork(const char *str)
575 {
576 	if (str == NULL || *str == '\0') {
577 		return str;
578 	}
579 	static char cmd[WPA_MAX_ANONYMIZE_LENGTH];
580 	os_strlcpy(cmd, str, sizeof(cmd));
581 	if (disable_anonymized_print()) {
582 		return cmd;
583 	}
584 	// cmd include ssid or identity
585 	if (os_strchr(cmd, '\"') && (os_strstr(cmd, "ssid") || os_strstr(cmd, "identity"))) {
586 		char tempssid[WPA_MAX_ANONYMIZE_LENGTH];
587 		os_strlcpy(tempssid, os_strchr(cmd, '\"') + 1, sizeof(tempssid));
588 		tempssid[os_strrchr(cmd, '\"') - os_strchr(cmd, '\"') - 1] = '\0';
589 		static char tempStr[WPA_MAX_ANONYMIZE_LENGTH];
590 		char *strOfStrtok = strtok(cmd, "\"");
591 		if (strOfStrtok == NULL) {
592 			return cmd;
593 		}
594 		os_strlcpy(tempStr, strOfStrtok, sizeof(tempStr));
595 		os_snprintf(cmd, sizeof(cmd), "%s\"%s\"", tempStr, anonymize_ssid(tempssid));
596 		return cmd;
597 	}
598 	//cmd include password or psk
599 	if (os_strchr(cmd, '\"') && (os_strstr(cmd, "password") || os_strstr(cmd, "psk"))) {
600 		char tempNumbel[WPA_MAX_ANONYMIZE_LENGTH];
601 		os_strlcpy(tempNumbel, os_strchr(cmd, '\"') + 1, sizeof(tempNumbel));
602 		tempNumbel[os_strrchr(cmd, '\"') - os_strchr(cmd, '\"') - 1] = '\0';
603 		for (int i = 0; i < os_strlen(tempNumbel); i++) {
604 			tempNumbel[i] = HIDDEN_CHAR;
605 		}
606 		static char tempStr[WPA_MAX_ANONYMIZE_LENGTH];
607 		char *strOfStrtok = strtok(cmd, "\"");
608 		if (strOfStrtok == NULL) {
609 			return cmd;
610 		}
611 		os_strlcpy(tempStr, strOfStrtok, sizeof(tempStr));
612 		os_snprintf(cmd, sizeof(cmd), "%s\"%s\"", tempStr, tempNumbel);
613 		os_memset(tempNumbel, 0, sizeof(tempNumbel));
614 		return cmd;
615 	}
616 	return cmd;
617 }
618 
get_anonymized_result_setnetwork_for_bssid(const char * str)619 const char *get_anonymized_result_setnetwork_for_bssid(const char *str)
620 {
621 	if (str == NULL || *str == '\0') {
622 		return str;
623 	}
624 	static const int colonCountNum = 2;
625 	static const int maxHiddenNum = 9;
626 	static char cmd[WPA_MAX_ANONYMIZE_LENGTH];
627 	os_strlcpy(cmd, str, sizeof(cmd));
628 	if (disable_anonymized_print()) {
629 		return cmd;
630 	}
631 	//cmd include bssid
632 	if (os_strchr(cmd, ':')) {
633 		int colonCount = 0;
634 		int start = 0;
635 		for (int j = 0; j < os_strlen(cmd); j++) {
636 			if (cmd[j] == ':') {
637 				colonCount++;
638 			}
639 			if (colonCount == colonCountNum) {
640 				start = j + 1;
641 				break;
642 			}
643 		}
644 		if (colonCount != colonCountNum) {
645 			return cmd;
646 		}
647 		for (int k = start; k < start + maxHiddenNum; k++) {
648 			if (cmd[k] != ':') {
649 				cmd[k] = HIDDEN_CHAR;
650 			}
651 		}
652 		return cmd;
653 	}
654 	return cmd;
655 }
656 
get_anonymized_result_for_set(const char * str)657 const char *get_anonymized_result_for_set(const char *str)
658 {
659 	if (str == NULL || *str == '\0') {
660 		return str;
661 	}
662 	static char cmd[WPA_MAX_ANONYMIZE_LENGTH];
663 	os_strlcpy(cmd, str, sizeof(cmd));
664 	if (disable_anonymized_print()) {
665 		return cmd;
666 	}
667 	if (os_strstr(cmd, "wpa_passphrase")) {
668 		char *value = os_strchr(cmd, ' ') + 1;
669 		if (value == NULL) {
670 			return cmd;
671 		}
672 		os_memset(value, HIDDEN_CHAR, os_strlen(value));
673 		return cmd;
674 	} else if (os_strstr(cmd, "ssid")) {
675 		char *value = os_strchr(cmd, ' ') + 1;
676 		os_snprintf(cmd, sizeof(cmd), "ssid=%s", anonymize_ssid(value));
677 		return cmd;
678 	} else if (os_strstr(cmd, "P2P_CONNECT")) {
679 		char *value = os_strchr(cmd, ' ') + 1;
680 		if (value == NULL) {
681 			return cmd;
682 		}
683 		os_snprintf(cmd, sizeof(cmd), "P2P_CONNECT=%s", get_anonymized_result_setnetwork_for_bssid(value));
684 		return cmd;
685 	}
686 	return cmd;
687 }
688 
wpa_hexdump(int level,const char * title,const void * buf,size_t len)689 void wpa_hexdump(int level, const char *title, const void *buf, size_t len)
690 {
691 	_wpa_hexdump(level, title, buf, len, 1, 0);
692 }
693 
694 
wpa_hexdump_key(int level,const char * title,const void * buf,size_t len)695 void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len)
696 {
697 	_wpa_hexdump(level, title, buf, len, wpa_debug_show_keys, 0);
698 }
699 
700 
_wpa_hexdump_ascii(int level,const char * title,const void * buf,size_t len,int show)701 static void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
702 			       size_t len, int show)
703 {
704 #ifdef CONFIG_WPA_NO_LOG
705     return;
706 #else
707 	size_t i, llen;
708 	const u8 *pos = buf;
709 	const size_t line_len = 16;
710 
711 #ifdef CONFIG_DEBUG_LINUX_TRACING
712 	if (wpa_debug_tracing_file != NULL) {
713 		fprintf(wpa_debug_tracing_file,
714 			WPAS_TRACE_PFX "%s - hexdump_ascii(len=%lu):",
715 			level, title, (unsigned long) len);
716 		if (buf == NULL) {
717 			fprintf(wpa_debug_tracing_file, " [NULL]\n");
718 		} else if (!show) {
719 			fprintf(wpa_debug_tracing_file, " [REMOVED]\n");
720 		} else {
721 			/* can do ascii processing in userspace */
722 			for (i = 0; i < len; i++)
723 				fprintf(wpa_debug_tracing_file,
724 					" %02x", pos[i]);
725 		}
726 		fflush(wpa_debug_tracing_file);
727 	}
728 #endif /* CONFIG_DEBUG_LINUX_TRACING */
729 
730 	if (level < wpa_debug_level)
731 		return;
732 #ifdef CONFIG_ANDROID_LOG
733 	_wpa_hexdump(level, title, buf, len, show, 0);
734 #else /* CONFIG_ANDROID_LOG */
735 #ifdef CONFIG_DEBUG_SYSLOG
736 	if (wpa_debug_syslog)
737 		_wpa_hexdump(level, title, buf, len, show, 1);
738 #endif /* CONFIG_DEBUG_SYSLOG */
739 	wpa_debug_print_timestamp();
740 #ifdef CONFIG_DEBUG_FILE
741 	if (out_file) {
742 		if (!show) {
743 			fprintf(out_file,
744 				"%s - hexdump_ascii(len=%lu): [REMOVED]\n",
745 				title, (unsigned long) len);
746 			goto file_done;
747 		}
748 		if (buf == NULL) {
749 			fprintf(out_file,
750 				"%s - hexdump_ascii(len=%lu): [NULL]\n",
751 				title, (unsigned long) len);
752 			goto file_done;
753 		}
754 		fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
755 			title, (unsigned long) len);
756 		while (len) {
757 			llen = len > line_len ? line_len : len;
758 			fprintf(out_file, "    ");
759 			for (i = 0; i < llen; i++)
760 				fprintf(out_file, " %02x", pos[i]);
761 			for (i = llen; i < line_len; i++)
762 				fprintf(out_file, "   ");
763 			fprintf(out_file, "   ");
764 			for (i = 0; i < llen; i++) {
765 				if (isprint(pos[i]))
766 					fprintf(out_file, "%c", pos[i]);
767 				else
768 					fprintf(out_file, "_");
769 			}
770 			for (i = llen; i < line_len; i++)
771 				fprintf(out_file, " ");
772 			fprintf(out_file, "\n");
773 			pos += llen;
774 			len -= llen;
775 		}
776 	}
777 file_done:
778 #endif /* CONFIG_DEBUG_FILE */
779 	if (!wpa_debug_syslog && !out_file) {
780 		if (!show) {
781 			printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
782 			       title, (unsigned long) len);
783 			return;
784 		}
785 		if (buf == NULL) {
786 			printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
787 			       title, (unsigned long) len);
788 			return;
789 		}
790 		printf("%s - hexdump_ascii(len=%lu):\n", title,
791 		       (unsigned long) len);
792 		while (len) {
793 			llen = len > line_len ? line_len : len;
794 			printf("    ");
795 			for (i = 0; i < llen; i++)
796 				printf(" %02x", pos[i]);
797 			for (i = llen; i < line_len; i++)
798 				printf("   ");
799 			printf("   ");
800 			for (i = 0; i < llen; i++) {
801 				if (isprint(pos[i]))
802 					printf("%c", pos[i]);
803 				else
804 					printf("_");
805 			}
806 			for (i = llen; i < line_len; i++)
807 				printf(" ");
808 			printf("\n");
809 			pos += llen;
810 			len -= llen;
811 		}
812 	}
813 #endif /* CONFIG_ANDROID_LOG */
814 #endif /* CONFIG_WPA_NO_LOG */
815 }
816 
817 
wpa_hexdump_ascii(int level,const char * title,const void * buf,size_t len)818 void wpa_hexdump_ascii(int level, const char *title, const void *buf,
819 		       size_t len)
820 {
821 	_wpa_hexdump_ascii(level, title, buf, len, 1);
822 }
823 
824 
wpa_hexdump_ascii_key(int level,const char * title,const void * buf,size_t len)825 void wpa_hexdump_ascii_key(int level, const char *title, const void *buf,
826 			   size_t len)
827 {
828 	_wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
829 }
830 
831 
832 #ifdef CONFIG_DEBUG_FILE
833 static char *last_path = NULL;
834 #endif /* CONFIG_DEBUG_FILE */
835 
wpa_debug_reopen_file(void)836 int wpa_debug_reopen_file(void)
837 {
838 #ifdef CONFIG_DEBUG_FILE
839 	int rv;
840 	char *tmp;
841 
842 	if (!last_path)
843 		return 0; /* logfile not used */
844 
845 	tmp = os_strdup(last_path);
846 	if (!tmp)
847 		return -1;
848 
849 	wpa_debug_close_file();
850 	rv = wpa_debug_open_file(tmp);
851 	os_free(tmp);
852 	return rv;
853 #else /* CONFIG_DEBUG_FILE */
854 	return 0;
855 #endif /* CONFIG_DEBUG_FILE */
856 }
857 
858 
wpa_debug_open_file(const char * path)859 int wpa_debug_open_file(const char *path)
860 {
861 #ifdef CONFIG_DEBUG_FILE
862 	int out_fd;
863 
864 	if (!path)
865 		return 0;
866 
867 	if (last_path == NULL || os_strcmp(last_path, path) != 0) {
868 		/* Save our path to enable re-open */
869 		os_free(last_path);
870 		last_path = os_strdup(path);
871 	}
872 
873 	out_fd = open(path, O_CREAT | O_APPEND | O_WRONLY,
874 		      S_IRUSR | S_IWUSR | S_IRGRP);
875 	if (out_fd < 0) {
876 		wpa_printf(MSG_ERROR,
877 			   "%s: Failed to open output file descriptor, using standard output",
878 			   __func__);
879 		return -1;
880 	}
881 
882 #ifdef __linux__
883 	if (fcntl(out_fd, F_SETFD, FD_CLOEXEC) < 0) {
884 		wpa_printf(MSG_DEBUG,
885 			   "%s: Failed to set FD_CLOEXEC - continue without: %s",
886 			   __func__, strerror(errno));
887 	}
888 #endif /* __linux__ */
889 
890 	out_file = fdopen(out_fd, "a");
891 	if (out_file == NULL) {
892 		wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open "
893 			   "output file, using standard output");
894 		close(out_fd);
895 		return -1;
896 	}
897 #ifndef _WIN32
898 	setvbuf(out_file, NULL, _IOLBF, 0);
899 #endif /* _WIN32 */
900 #else /* CONFIG_DEBUG_FILE */
901 	(void)path;
902 #endif /* CONFIG_DEBUG_FILE */
903 	return 0;
904 }
905 
906 
wpa_debug_close_file(void)907 void wpa_debug_close_file(void)
908 {
909 #ifdef CONFIG_DEBUG_FILE
910 	if (!out_file)
911 		return;
912 	fclose(out_file);
913 	out_file = NULL;
914 	os_free(last_path);
915 	last_path = NULL;
916 #endif /* CONFIG_DEBUG_FILE */
917 }
918 
919 
wpa_debug_setup_stdout(void)920 void wpa_debug_setup_stdout(void) __attribute__((no_sanitize("cfi")))
921 {
922 #ifndef _WIN32
923 	setvbuf(stdout, NULL, _IOLBF, 0);
924 #endif /* _WIN32 */
925 }
926 
927 #endif /* CONFIG_NO_STDOUT_DEBUG */
928 
929 
930 #ifndef CONFIG_NO_WPA_MSG
931 static wpa_msg_cb_func wpa_msg_cb = NULL;
932 
wpa_msg_register_cb(wpa_msg_cb_func func)933 void wpa_msg_register_cb(wpa_msg_cb_func func)
934 {
935 	wpa_msg_cb = func;
936 }
937 
938 
939 static wpa_msg_get_ifname_func wpa_msg_ifname_cb = NULL;
940 
wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func)941 void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func)
942 {
943 	wpa_msg_ifname_cb = func;
944 }
945 
946 
wpa_msg(void * ctx,int level,const char * fmt,...)947 void wpa_msg(void *ctx, int level, const char *fmt, ...) __attribute__((no_sanitize("cfi")))
948 {
949 	va_list ap;
950 	char *buf;
951 	int buflen;
952 	int len;
953 	char prefix[130];
954 
955 	va_start(ap, fmt);
956 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
957 	va_end(ap);
958 
959 	buf = os_malloc(buflen);
960 	if (buf == NULL) {
961 		wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
962 			   "buffer");
963 		return;
964 	}
965 	va_start(ap, fmt);
966 	prefix[0] = '\0';
967 	if (wpa_msg_ifname_cb) {
968 		const char *ifname = wpa_msg_ifname_cb(ctx);
969 		if (ifname) {
970 			int res = os_snprintf(prefix, sizeof(prefix), "%s: ",
971 					      ifname);
972 			if (os_snprintf_error(sizeof(prefix), res))
973 				prefix[0] = '\0';
974 		}
975 	}
976 	len = vsnprintf(buf, buflen, fmt, ap);
977 	va_end(ap);
978 	wpa_printf(level, "%s%s", prefix, get_anonymized_result_setnetwork_for_bssid(buf));
979 	if (wpa_msg_cb)
980 		wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
981 	bin_clear_free(buf, buflen);
982 }
983 
wpa_msg_only_for_cb(void * ctx,int level,const char * fmt,...)984 void wpa_msg_only_for_cb(void *ctx, int level, const char *fmt, ...) __attribute__((no_sanitize("cfi")))
985 {
986 	va_list ap;
987 	char *buf;
988 	int buflen;
989 	int len;
990 	char prefix[130];
991 
992 	va_start(ap, fmt);
993 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
994 	va_end(ap);
995 
996 	buf = os_malloc(buflen);
997 	if (buf == NULL) {
998 		wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
999 			"buffer");
1000 		return;
1001 	}
1002 	va_start(ap, fmt);
1003 	prefix[0] = '\0';
1004 	if (wpa_msg_ifname_cb) {
1005 		const char *ifname = wpa_msg_ifname_cb(ctx);
1006 		if (ifname) {
1007 			int res = os_snprintf(prefix, sizeof(prefix), "%s: ",
1008 				ifname);
1009 			if (os_snprintf_error(sizeof(prefix), res))
1010 				prefix[0] = '\0';
1011 		}
1012 	}
1013 	len = vsnprintf(buf, buflen, fmt, ap);
1014 	va_end(ap);
1015 	if (wpa_msg_cb)
1016 		wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
1017 	bin_clear_free(buf, buflen);
1018 }
1019 
1020 
wpa_msg_ctrl(void * ctx,int level,const char * fmt,...)1021 void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...) __attribute__((no_sanitize("cfi")))
1022 {
1023 	va_list ap;
1024 	char *buf;
1025 	int buflen;
1026 	int len;
1027 
1028 	if (!wpa_msg_cb)
1029 		return;
1030 
1031 	va_start(ap, fmt);
1032 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
1033 	va_end(ap);
1034 
1035 	buf = os_malloc(buflen);
1036 	if (buf == NULL) {
1037 		wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate "
1038 			   "message buffer");
1039 		return;
1040 	}
1041 	va_start(ap, fmt);
1042 	len = vsnprintf(buf, buflen, fmt, ap);
1043 	va_end(ap);
1044 	wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
1045 	bin_clear_free(buf, buflen);
1046 }
1047 
1048 
wpa_msg_global(void * ctx,int level,const char * fmt,...)1049 void wpa_msg_global(void *ctx, int level, const char *fmt, ...) __attribute__((no_sanitize("cfi")))
1050 {
1051 	va_list ap;
1052 	char *buf;
1053 	int buflen;
1054 	int len;
1055 
1056 	va_start(ap, fmt);
1057 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
1058 	va_end(ap);
1059 
1060 	buf = os_malloc(buflen);
1061 	if (buf == NULL) {
1062 		wpa_printf(MSG_ERROR, "wpa_msg_global: Failed to allocate "
1063 			   "message buffer");
1064 		return;
1065 	}
1066 	va_start(ap, fmt);
1067 	len = vsnprintf(buf, buflen, fmt, ap);
1068 	va_end(ap);
1069 	if (wpa_msg_cb)
1070 		wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
1071 	bin_clear_free(buf, buflen);
1072 }
1073 
1074 
wpa_msg_global_ctrl(void * ctx,int level,const char * fmt,...)1075 void wpa_msg_global_ctrl(void *ctx, int level, const char *fmt, ...) __attribute__((no_sanitize("cfi")))
1076 {
1077 	va_list ap;
1078 	char *buf;
1079 	int buflen;
1080 	int len;
1081 
1082 	if (!wpa_msg_cb)
1083 		return;
1084 
1085 	va_start(ap, fmt);
1086 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
1087 	va_end(ap);
1088 
1089 	buf = os_malloc(buflen);
1090 	if (buf == NULL) {
1091 		wpa_printf(MSG_ERROR,
1092 			   "wpa_msg_global_ctrl: Failed to allocate message buffer");
1093 		return;
1094 	}
1095 	va_start(ap, fmt);
1096 	len = vsnprintf(buf, buflen, fmt, ap);
1097 	va_end(ap);
1098 	wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
1099 	bin_clear_free(buf, buflen);
1100 }
1101 
1102 
wpa_msg_no_global(void * ctx,int level,const char * fmt,...)1103 void wpa_msg_no_global(void *ctx, int level, const char *fmt, ...) __attribute__((no_sanitize("cfi")))
1104 {
1105 	va_list ap;
1106 	char *buf;
1107 	int buflen;
1108 	int len;
1109 
1110 	va_start(ap, fmt);
1111 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
1112 	va_end(ap);
1113 
1114 	buf = os_malloc(buflen);
1115 	if (buf == NULL) {
1116 		wpa_printf(MSG_ERROR, "wpa_msg_no_global: Failed to allocate "
1117 			   "message buffer");
1118 		return;
1119 	}
1120 	va_start(ap, fmt);
1121 	len = vsnprintf(buf, buflen, fmt, ap);
1122 	va_end(ap);
1123 	if (wpa_msg_cb)
1124 		wpa_msg_cb(ctx, level, WPA_MSG_NO_GLOBAL, buf, len);
1125 	bin_clear_free(buf, buflen);
1126 }
1127 
1128 
wpa_msg_global_only(void * ctx,int level,const char * fmt,...)1129 void wpa_msg_global_only(void *ctx, int level, const char *fmt, ...)
1130 {
1131 	va_list ap;
1132 	char *buf;
1133 	int buflen;
1134 	int len;
1135 
1136 	va_start(ap, fmt);
1137 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
1138 	va_end(ap);
1139 
1140 	buf = os_malloc(buflen);
1141 	if (buf == NULL) {
1142 		wpa_printf(MSG_ERROR, "%s: Failed to allocate message buffer",
1143 			   __func__);
1144 		return;
1145 	}
1146 	va_start(ap, fmt);
1147 	len = vsnprintf(buf, buflen, fmt, ap);
1148 	va_end(ap);
1149 	wpa_printf(level, "%s", get_anonymized_result_setnetwork_for_bssid(buf));
1150 	if (wpa_msg_cb)
1151 		wpa_msg_cb(ctx, level, WPA_MSG_ONLY_GLOBAL, buf, len);
1152 	os_free(buf);
1153 }
1154 
1155 #endif /* CONFIG_NO_WPA_MSG */
1156 
1157 
1158 #ifndef CONFIG_NO_HOSTAPD_LOGGER
1159 static hostapd_logger_cb_func hostapd_logger_cb = NULL;
1160 
hostapd_logger_register_cb(hostapd_logger_cb_func func)1161 void hostapd_logger_register_cb(hostapd_logger_cb_func func)
1162 {
1163 	hostapd_logger_cb = func;
1164 }
1165 
1166 
hostapd_logger(void * ctx,const u8 * addr,unsigned int module,int level,const char * fmt,...)1167 void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level,
1168 		    const char *fmt, ...)
1169 {
1170 	va_list ap;
1171 	char *buf;
1172 	int buflen;
1173 	int len;
1174 
1175 	va_start(ap, fmt);
1176 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
1177 	va_end(ap);
1178 
1179 	buf = os_malloc(buflen);
1180 	if (buf == NULL) {
1181 		wpa_printf(MSG_ERROR, "hostapd_logger: Failed to allocate "
1182 			   "message buffer");
1183 		return;
1184 	}
1185 	va_start(ap, fmt);
1186 	len = vsnprintf(buf, buflen, fmt, ap);
1187 	va_end(ap);
1188 	if (hostapd_logger_cb)
1189 		hostapd_logger_cb(ctx, addr, module, level, buf, len);
1190 	else if (addr)
1191 		wpa_printf(MSG_DEBUG, "hostapd_logger: STA " MACSTR_SEC " - %s",
1192 		MAC2STR_SEC(addr), get_anonymized_result_setnetwork_for_bssid(buf));
1193 	else
1194 		wpa_printf(MSG_DEBUG, "hostapd_logger: %s", get_anonymized_result_setnetwork_for_bssid(buf));
1195 	bin_clear_free(buf, buflen);
1196 }
1197 
hostapd_logger_only_for_cb(void * ctx,const u8 * addr,unsigned int module,int level,const char * fmt,...)1198 void hostapd_logger_only_for_cb(void *ctx, const u8 *addr, unsigned int module, int level,
1199 			const char *fmt, ...)
1200 {
1201 	va_list ap;
1202 	char *buf;
1203 	int buflen;
1204 	int len;
1205 
1206 	va_start(ap, fmt);
1207 	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
1208 	va_end(ap);
1209 
1210 	buf = os_malloc(buflen);
1211 	if (buf == NULL) {
1212 		wpa_printf(MSG_ERROR, "hostapd_logger: Failed to allocate "
1213 			"message buffer");
1214 		return;
1215 	}
1216 	va_start(ap, fmt);
1217 	len = vsnprintf(buf, buflen, fmt, ap);
1218 	va_end(ap);
1219 	if (hostapd_logger_cb) {
1220 		hostapd_logger_cb(ctx, addr, module, level, buf, len);
1221 	}
1222 	bin_clear_free(buf, buflen);
1223 }
1224 
1225 #endif /* CONFIG_NO_HOSTAPD_LOGGER */
1226 
1227 
debug_level_str(int level)1228 const char * debug_level_str(int level)
1229 {
1230 	switch (level) {
1231 	case MSG_EXCESSIVE:
1232 		return "EXCESSIVE";
1233 	case MSG_MSGDUMP:
1234 		return "MSGDUMP";
1235 	case MSG_DEBUG:
1236 		return "DEBUG";
1237 	case MSG_INFO:
1238 		return "INFO";
1239 	case MSG_WARNING:
1240 		return "WARNING";
1241 	case MSG_ERROR:
1242 		return "ERROR";
1243 	default:
1244 		return "?";
1245 	}
1246 }
1247 
1248 
str_to_debug_level(const char * s)1249 int str_to_debug_level(const char *s)
1250 {
1251 	if (os_strcasecmp(s, "EXCESSIVE") == 0)
1252 		return MSG_EXCESSIVE;
1253 	if (os_strcasecmp(s, "MSGDUMP") == 0)
1254 		return MSG_MSGDUMP;
1255 	if (os_strcasecmp(s, "DEBUG") == 0)
1256 		return MSG_DEBUG;
1257 	if (os_strcasecmp(s, "INFO") == 0)
1258 		return MSG_INFO;
1259 	if (os_strcasecmp(s, "WARNING") == 0)
1260 		return MSG_WARNING;
1261 	if (os_strcasecmp(s, "ERROR") == 0)
1262 		return MSG_ERROR;
1263 	return -1;
1264 }
1265