xref: /openbsd-src/lib/libfido2/src/log.c (revision c4a807ed13283181a6a84fdf571f4571a1b25eac)
1d75efeb7Sdjm /*
2*c4a807edSdjm  * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
3d75efeb7Sdjm  * Use of this source code is governed by a BSD-style
4d75efeb7Sdjm  * license that can be found in the LICENSE file.
5d75efeb7Sdjm  */
6d75efeb7Sdjm 
7*c4a807edSdjm #undef _GNU_SOURCE /* XSI strerror_r() */
8*c4a807edSdjm 
9d75efeb7Sdjm #include <stdarg.h>
10d75efeb7Sdjm #include <stdio.h>
1132a20e26Sdjm 
12d75efeb7Sdjm #include "fido.h"
13d75efeb7Sdjm 
14d75efeb7Sdjm #ifndef FIDO_NO_DIAGNOSTIC
15d75efeb7Sdjm 
1632a20e26Sdjm #define XXDLEN	32
1732a20e26Sdjm #define XXDROW	128
1832a20e26Sdjm #define LINELEN	256
1932a20e26Sdjm 
20d75efeb7Sdjm #ifndef TLS
21d75efeb7Sdjm #define TLS
22d75efeb7Sdjm #endif
23d75efeb7Sdjm 
24d75efeb7Sdjm static TLS int logging;
2532a20e26Sdjm static TLS fido_log_handler_t *log_handler;
2632a20e26Sdjm 
2732a20e26Sdjm static void
log_on_stderr(const char * str)2832a20e26Sdjm log_on_stderr(const char *str)
2932a20e26Sdjm {
3032a20e26Sdjm 	fprintf(stderr, "%s", str);
3132a20e26Sdjm }
32d75efeb7Sdjm 
33*c4a807edSdjm static void
do_log(const char * suffix,const char * fmt,va_list args)34*c4a807edSdjm do_log(const char *suffix, const char *fmt, va_list args)
35*c4a807edSdjm {
36*c4a807edSdjm 	char line[LINELEN], body[LINELEN];
37*c4a807edSdjm 
38*c4a807edSdjm 	vsnprintf(body, sizeof(body), fmt, args);
39*c4a807edSdjm 
40*c4a807edSdjm 	if (suffix != NULL)
41*c4a807edSdjm 		snprintf(line, sizeof(line), "%.180s: %.70s\n", body, suffix);
42*c4a807edSdjm 	else
43*c4a807edSdjm 		snprintf(line, sizeof(line), "%.180s\n", body);
44*c4a807edSdjm 
45*c4a807edSdjm 	log_handler(line);
46*c4a807edSdjm }
47*c4a807edSdjm 
48d75efeb7Sdjm void
fido_log_init(void)4932a20e26Sdjm fido_log_init(void)
50d75efeb7Sdjm {
51d75efeb7Sdjm 	logging = 1;
5232a20e26Sdjm 	log_handler = log_on_stderr;
53d75efeb7Sdjm }
54d75efeb7Sdjm 
55d75efeb7Sdjm void
fido_log_debug(const char * fmt,...)5632a20e26Sdjm fido_log_debug(const char *fmt, ...)
57d75efeb7Sdjm {
58*c4a807edSdjm 	va_list args;
59d75efeb7Sdjm 
6032a20e26Sdjm 	if (!logging || log_handler == NULL)
61d75efeb7Sdjm 		return;
62d75efeb7Sdjm 
63*c4a807edSdjm 	va_start(args, fmt);
64*c4a807edSdjm 	do_log(NULL, fmt, args);
65*c4a807edSdjm 	va_end(args);
6632a20e26Sdjm }
67d75efeb7Sdjm 
6832a20e26Sdjm void
fido_log_xxd(const void * buf,size_t count,const char * fmt,...)69*c4a807edSdjm fido_log_xxd(const void *buf, size_t count, const char *fmt, ...)
7032a20e26Sdjm {
7132a20e26Sdjm 	const uint8_t *ptr = buf;
72*c4a807edSdjm 	char row[XXDROW], xxd[XXDLEN];
73*c4a807edSdjm 	va_list args;
7432a20e26Sdjm 
75*c4a807edSdjm 	if (!logging || log_handler == NULL)
7632a20e26Sdjm 		return;
7732a20e26Sdjm 
78*c4a807edSdjm 	snprintf(row, sizeof(row), "buf=%p, len=%zu", buf, count);
79*c4a807edSdjm 	va_start(args, fmt);
80*c4a807edSdjm 	do_log(row, fmt, args);
81*c4a807edSdjm 	va_end(args);
8232a20e26Sdjm 	*row = '\0';
8332a20e26Sdjm 
8432a20e26Sdjm 	for (size_t i = 0; i < count; i++) {
8532a20e26Sdjm 		*xxd = '\0';
8632a20e26Sdjm 		if (i % 16 == 0)
8732a20e26Sdjm 			snprintf(xxd, sizeof(xxd), "%04zu: %02x", i, *ptr++);
8832a20e26Sdjm 		else
8932a20e26Sdjm 			snprintf(xxd, sizeof(xxd), " %02x", *ptr++);
9032a20e26Sdjm 		strlcat(row, xxd, sizeof(row));
9132a20e26Sdjm 		if (i % 16 == 15 || i == count - 1) {
9232a20e26Sdjm 			fido_log_debug("%s", row);
9332a20e26Sdjm 			*row = '\0';
9432a20e26Sdjm 		}
9532a20e26Sdjm 	}
9632a20e26Sdjm }
9732a20e26Sdjm 
9832a20e26Sdjm void
fido_log_error(int errnum,const char * fmt,...)99*c4a807edSdjm fido_log_error(int errnum, const char *fmt, ...)
100*c4a807edSdjm {
101*c4a807edSdjm 	char errstr[LINELEN];
102*c4a807edSdjm 	va_list args;
103*c4a807edSdjm 
104*c4a807edSdjm 	if (!logging || log_handler == NULL)
105*c4a807edSdjm 		return;
106*c4a807edSdjm 	if (strerror_r(errnum, errstr, sizeof(errstr)) != 0)
107*c4a807edSdjm 		snprintf(errstr, sizeof(errstr), "error %d", errnum);
108*c4a807edSdjm 
109*c4a807edSdjm 	va_start(args, fmt);
110*c4a807edSdjm 	do_log(errstr, fmt, args);
111*c4a807edSdjm 	va_end(args);
112*c4a807edSdjm }
113*c4a807edSdjm 
114*c4a807edSdjm void
fido_set_log_handler(fido_log_handler_t * handler)11532a20e26Sdjm fido_set_log_handler(fido_log_handler_t *handler)
11632a20e26Sdjm {
11732a20e26Sdjm 	if (handler != NULL)
11832a20e26Sdjm 		log_handler = handler;
119d75efeb7Sdjm }
120d75efeb7Sdjm 
121d75efeb7Sdjm #endif /* !FIDO_NO_DIAGNOSTIC */
122