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