xref: /openbsd/lib/libfido2/src/log.c (revision 3cab2bb3)
1 /*
2  * Copyright (c) 2018 Yubico AB. All rights reserved.
3  * Use of this source code is governed by a BSD-style
4  * license that can be found in the LICENSE file.
5  */
6 
7 #include <stdarg.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #include "fido.h"
13 
14 #ifndef FIDO_NO_DIAGNOSTIC
15 
16 #define XXDLEN	32
17 #define XXDROW	128
18 #define LINELEN	256
19 
20 #ifndef TLS
21 #define TLS
22 #endif
23 
24 static TLS int logging;
25 static TLS fido_log_handler_t *log_handler;
26 
27 static void
28 log_on_stderr(const char *str)
29 {
30 	fprintf(stderr, "%s", str);
31 }
32 
33 void
34 fido_log_init(void)
35 {
36 	logging = 1;
37 	log_handler = log_on_stderr;
38 }
39 
40 void
41 fido_log_debug(const char *fmt, ...)
42 {
43 	char line[LINELEN];
44 	va_list ap;
45 	int r;
46 
47 	if (!logging || log_handler == NULL)
48 		return;
49 
50 	va_start(ap, fmt);
51 	r = vsnprintf(line, sizeof(line) - 1, fmt, ap);
52 	va_end(ap);
53 	if (r < 0 || (size_t)r >= sizeof(line) - 1)
54 		return;
55 	strlcat(line, "\n", sizeof(line));
56 	log_handler(line);
57 }
58 
59 void
60 fido_log_xxd(const void *buf, size_t count)
61 {
62 	const uint8_t *ptr = buf;
63 	char row[XXDROW];
64 	char xxd[XXDLEN];
65 
66 	if (!logging || log_handler == NULL || count == 0)
67 		return;
68 
69 	*row = '\0';
70 
71 	for (size_t i = 0; i < count; i++) {
72 		*xxd = '\0';
73 		if (i % 16 == 0)
74 			snprintf(xxd, sizeof(xxd), "%04zu: %02x", i, *ptr++);
75 		else
76 			snprintf(xxd, sizeof(xxd), " %02x", *ptr++);
77 		strlcat(row, xxd, sizeof(row));
78 		if (i % 16 == 15 || i == count - 1) {
79 			fido_log_debug("%s", row);
80 			*row = '\0';
81 		}
82 	}
83 }
84 
85 void
86 fido_set_log_handler(fido_log_handler_t *handler)
87 {
88 	if (handler != NULL)
89 		log_handler = handler;
90 }
91 
92 #endif /* !FIDO_NO_DIAGNOSTIC */
93