xref: /freebsd-src/contrib/libfido2/src/log.c (revision 2ccfa855b2fc331819953e3de1b1c15ce5b95a7e)
10afa8e06SEd Maste /*
20afa8e06SEd Maste  * Copyright (c) 2018-2021 Yubico AB. All rights reserved.
30afa8e06SEd Maste  * Use of this source code is governed by a BSD-style
40afa8e06SEd Maste  * license that can be found in the LICENSE file.
5*2ccfa855SEd Maste  * SPDX-License-Identifier: BSD-2-Clause
60afa8e06SEd Maste  */
70afa8e06SEd Maste 
80afa8e06SEd Maste #undef _GNU_SOURCE /* XSI strerror_r() */
90afa8e06SEd Maste 
100afa8e06SEd Maste #include <stdarg.h>
110afa8e06SEd Maste #include <stdio.h>
120afa8e06SEd Maste 
130afa8e06SEd Maste #include "fido.h"
140afa8e06SEd Maste 
150afa8e06SEd Maste #ifndef FIDO_NO_DIAGNOSTIC
160afa8e06SEd Maste 
170afa8e06SEd Maste #define XXDLEN	32
180afa8e06SEd Maste #define XXDROW	128
190afa8e06SEd Maste #define LINELEN	256
200afa8e06SEd Maste 
210afa8e06SEd Maste #ifndef TLS
220afa8e06SEd Maste #define TLS
230afa8e06SEd Maste #endif
240afa8e06SEd Maste 
250afa8e06SEd Maste static TLS int logging;
260afa8e06SEd Maste static TLS fido_log_handler_t *log_handler;
270afa8e06SEd Maste 
280afa8e06SEd Maste static void
log_on_stderr(const char * str)290afa8e06SEd Maste log_on_stderr(const char *str)
300afa8e06SEd Maste {
310afa8e06SEd Maste 	fprintf(stderr, "%s", str);
320afa8e06SEd Maste }
330afa8e06SEd Maste 
340afa8e06SEd Maste static void
do_log(const char * suffix,const char * fmt,va_list args)350afa8e06SEd Maste do_log(const char *suffix, const char *fmt, va_list args)
360afa8e06SEd Maste {
370afa8e06SEd Maste 	char line[LINELEN], body[LINELEN];
380afa8e06SEd Maste 
390afa8e06SEd Maste 	vsnprintf(body, sizeof(body), fmt, args);
400afa8e06SEd Maste 
410afa8e06SEd Maste 	if (suffix != NULL)
420afa8e06SEd Maste 		snprintf(line, sizeof(line), "%.180s: %.70s\n", body, suffix);
430afa8e06SEd Maste 	else
440afa8e06SEd Maste 		snprintf(line, sizeof(line), "%.180s\n", body);
450afa8e06SEd Maste 
460afa8e06SEd Maste 	log_handler(line);
470afa8e06SEd Maste }
480afa8e06SEd Maste 
490afa8e06SEd Maste void
fido_log_init(void)500afa8e06SEd Maste fido_log_init(void)
510afa8e06SEd Maste {
520afa8e06SEd Maste 	logging = 1;
530afa8e06SEd Maste 	log_handler = log_on_stderr;
540afa8e06SEd Maste }
550afa8e06SEd Maste 
560afa8e06SEd Maste void
fido_log_debug(const char * fmt,...)570afa8e06SEd Maste fido_log_debug(const char *fmt, ...)
580afa8e06SEd Maste {
590afa8e06SEd Maste 	va_list args;
600afa8e06SEd Maste 
610afa8e06SEd Maste 	if (!logging || log_handler == NULL)
620afa8e06SEd Maste 		return;
630afa8e06SEd Maste 
640afa8e06SEd Maste 	va_start(args, fmt);
650afa8e06SEd Maste 	do_log(NULL, fmt, args);
660afa8e06SEd Maste 	va_end(args);
670afa8e06SEd Maste }
680afa8e06SEd Maste 
690afa8e06SEd Maste void
fido_log_xxd(const void * buf,size_t count,const char * fmt,...)700afa8e06SEd Maste fido_log_xxd(const void *buf, size_t count, const char *fmt, ...)
710afa8e06SEd Maste {
720afa8e06SEd Maste 	const uint8_t *ptr = buf;
730afa8e06SEd Maste 	char row[XXDROW], xxd[XXDLEN];
740afa8e06SEd Maste 	va_list args;
750afa8e06SEd Maste 
760afa8e06SEd Maste 	if (!logging || log_handler == NULL)
770afa8e06SEd Maste 		return;
780afa8e06SEd Maste 
790afa8e06SEd Maste 	snprintf(row, sizeof(row), "buf=%p, len=%zu", buf, count);
800afa8e06SEd Maste 	va_start(args, fmt);
810afa8e06SEd Maste 	do_log(row, fmt, args);
820afa8e06SEd Maste 	va_end(args);
830afa8e06SEd Maste 	*row = '\0';
840afa8e06SEd Maste 
850afa8e06SEd Maste 	for (size_t i = 0; i < count; i++) {
860afa8e06SEd Maste 		*xxd = '\0';
870afa8e06SEd Maste 		if (i % 16 == 0)
880afa8e06SEd Maste 			snprintf(xxd, sizeof(xxd), "%04zu: %02x", i, *ptr++);
890afa8e06SEd Maste 		else
900afa8e06SEd Maste 			snprintf(xxd, sizeof(xxd), " %02x", *ptr++);
910afa8e06SEd Maste 		strlcat(row, xxd, sizeof(row));
920afa8e06SEd Maste 		if (i % 16 == 15 || i == count - 1) {
930afa8e06SEd Maste 			fido_log_debug("%s", row);
940afa8e06SEd Maste 			*row = '\0';
950afa8e06SEd Maste 		}
960afa8e06SEd Maste 	}
970afa8e06SEd Maste }
980afa8e06SEd Maste 
990afa8e06SEd Maste void
fido_log_error(int errnum,const char * fmt,...)1000afa8e06SEd Maste fido_log_error(int errnum, const char *fmt, ...)
1010afa8e06SEd Maste {
1020afa8e06SEd Maste 	char errstr[LINELEN];
1030afa8e06SEd Maste 	va_list args;
1040afa8e06SEd Maste 
1050afa8e06SEd Maste 	if (!logging || log_handler == NULL)
1060afa8e06SEd Maste 		return;
1070afa8e06SEd Maste 	if (strerror_r(errnum, errstr, sizeof(errstr)) != 0)
1080afa8e06SEd Maste 		snprintf(errstr, sizeof(errstr), "error %d", errnum);
1090afa8e06SEd Maste 
1100afa8e06SEd Maste 	va_start(args, fmt);
1110afa8e06SEd Maste 	do_log(errstr, fmt, args);
1120afa8e06SEd Maste 	va_end(args);
1130afa8e06SEd Maste }
1140afa8e06SEd Maste 
1150afa8e06SEd Maste void
fido_set_log_handler(fido_log_handler_t * handler)1160afa8e06SEd Maste fido_set_log_handler(fido_log_handler_t *handler)
1170afa8e06SEd Maste {
1180afa8e06SEd Maste 	if (handler != NULL)
1190afa8e06SEd Maste 		log_handler = handler;
1200afa8e06SEd Maste }
1210afa8e06SEd Maste 
1220afa8e06SEd Maste #endif /* !FIDO_NO_DIAGNOSTIC */
123