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