diff --git a/include/tss2/tss2_common.h b/include/tss2/tss2_common.h index 082883f52a..d2e98458ad 100644 --- a/include/tss2/tss2_common.h +++ b/include/tss2/tss2_common.h @@ -39,6 +39,31 @@ struct TSS2_ABI_VERSION { #define TSS2_ABI_VERSION_CURRENT {1, 2, 1, 108} +/* TODO: Maybe this is better in tss2_log.h? */ +#include +#define LOGL_NONE 0 +#define LOGL_ERROR 2 +#define LOGL_WARNING 3 +#define LOGL_INFO 4 +#define LOGL_DEBUG 5 +#define LOGL_TRACE 6 +#define LOGL_UNDEF 0xFF + +typedef enum { + LOGLEVEL_NONE = LOGL_NONE, + LOGLEVEL_ERROR = LOGL_ERROR, + LOGLEVEL_WARNING = LOGL_WARNING, + LOGLEVEL_INFO = LOGL_INFO, + LOGLEVEL_DEBUG = LOGL_DEBUG, + LOGLEVEL_TRACE = LOGL_TRACE, + LOGLEVEL_UNDEFINED = LOGL_UNDEF +} log_level; + +/* TODO ENUMs can change size based on compiler settings, so just use int or unisgned here */ +typedef void (*TSS2_LOG_HANDLER)(log_level loglevel, const char *module, + const char *file, const char *func, int line, + const char *msg); + /* * Return Codes */ diff --git a/include/tss2/tss2_esys.h b/include/tss2/tss2_esys.h index b3fa9ca717..09a1bf68ed 100644 --- a/include/tss2/tss2_esys.h +++ b/include/tss2/tss2_esys.h @@ -3302,6 +3302,10 @@ Esys_GetSysContext( ESYS_CONTEXT *esys_context, TSS2_SYS_CONTEXT **sys_context); +TSS2_LOG_HANDLER +Esys_SetLogHandler( + TSS2_LOG_HANDLER new_handler); + #ifdef __cplusplus } #endif diff --git a/include/tss2/tss2_sys.h b/include/tss2/tss2_sys.h index c73df5fc29..b9b732d849 100644 --- a/include/tss2/tss2_sys.h +++ b/include/tss2/tss2_sys.h @@ -2281,6 +2281,10 @@ TSS2_RC Tss2_Sys_PolicyAuthorizeNV( TSS2L_SYS_AUTH_COMMAND const *cmdAuthsArray, TSS2L_SYS_AUTH_RESPONSE *rspAuthsArray); +TSS2_LOG_HANDLER +Tss2_Sys_SetLogHandler( + TSS2_LOG_HANDLER new_handler); + #ifdef __cplusplus } #endif diff --git a/lib/tss2-esys.def b/lib/tss2-esys.def index ffdadebfb3..847439ed7d 100644 --- a/lib/tss2-esys.def +++ b/lib/tss2-esys.def @@ -362,3 +362,4 @@ EXPORTS Esys_ZGen_2Phase Esys_ZGen_2Phase_Async Esys_ZGen_2Phase_Finish + Esys_SetLogHandler diff --git a/lib/tss2-esys.map b/lib/tss2-esys.map index ce6fd2e0ee..2599e53f40 100644 --- a/lib/tss2-esys.map +++ b/lib/tss2-esys.map @@ -365,6 +365,7 @@ Esys_Initialize; Esys_GetPollHandles; Esys_Finalize; + Esys_SetLogHandler; local: *; }; diff --git a/lib/tss2-sys.def b/lib/tss2-sys.def index 1f7fd6747f..9f22b4aae8 100644 --- a/lib/tss2-sys.def +++ b/lib/tss2-sys.def @@ -366,3 +366,4 @@ EXPORTS Tss2_Sys_ZGen_2Phase_Prepare Tss2_Sys_ZGen_2Phase_Complete Tss2_Sys_ZGen_2Phase + Tss2_Sys_SetLogHandler diff --git a/lib/tss2-sys.map b/lib/tss2-sys.map index d55602ec73..a9f268d4b9 100644 --- a/lib/tss2-sys.map +++ b/lib/tss2-sys.map @@ -370,6 +370,7 @@ Tss2_Sys_ZGen_2Phase_Prepare; Tss2_Sys_ZGen_2Phase_Complete; Tss2_Sys_ZGen_2Phase; + Tss2_Sys_SetLogHandler; local: *; }; diff --git a/src/tss2-esys/api/Esys_SetLogHandler.c b/src/tss2-esys/api/Esys_SetLogHandler.c new file mode 100644 index 0000000000..9e5dc64380 --- /dev/null +++ b/src/tss2-esys/api/Esys_SetLogHandler.c @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "tss2_esys.h" +#define LOGMODULE esys +#include "util/log.h" + +TSS2_LOG_HANDLER +Esys_SetLogHandler( + TSS2_LOG_HANDLER new_handler) +{ + return set_log_handler(new_handler); +} diff --git a/src/tss2-sys/api/Tss2_Sys_SetLogHandler.c b/src/tss2-sys/api/Tss2_Sys_SetLogHandler.c new file mode 100644 index 0000000000..ff02b99660 --- /dev/null +++ b/src/tss2-sys/api/Tss2_Sys_SetLogHandler.c @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/***********************************************************************; + * Copyright (c) 2015 - 2018, Intel Corporation + * All rights reserved. + ***********************************************************************/ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "tss2_sys.h" +#define LOGMODULE sys +#include "util/log.h" + +TSS2_LOG_HANDLER +Tss2_Sys_SetLogHandler( + TSS2_LOG_HANDLER new_handler) +{ + return set_log_handler(new_handler); +} diff --git a/src/util/log.c b/src/util/log.c index 76899eb19d..7897c2aee2 100644 --- a/src/util/log.c +++ b/src/util/log.c @@ -106,6 +106,28 @@ getLogFile(void) #endif } +static void do_default_log(log_level loglevel, const char *module, + const char *file, const char *func, int line, + const char *msg) { + + char buf[4096]; + int size = snprintf(buf, sizeof(buf), "%s:%s:%s:%d:%s() %s \n", + log_strings[loglevel], module, file, line, func, msg); + + FILE *logfile = getLogFile(); + fwrite (buf, size, 1, logfile); + fflush(logfile); +} + +static TSS2_LOG_HANDLER log_handler = do_default_log; + +TSS2_LOG_HANDLER set_log_handler(TSS2_LOG_HANDLER new_handler) { + TSS2_LOG_HANDLER old = log_handler; + log_handler = new_handler; + return old; +} + +/* TODO update logblob */ void doLogBlob(log_level loglevel, const char *module, log_level logdefault, log_level *status, @@ -188,27 +210,27 @@ doLog(log_level loglevel, const char *module, log_level logdefault, const char *file, const char *func, int line, const char *msg, ...) { - FILE *logfile; - if (unlikely(*status == LOGLEVEL_UNDEFINED)) - *status = getLogLevel(module, logdefault); - - if (loglevel > *status) + /* No log handler, skip message */ + if (!log_handler) { return; + /* If the default is registered, short circuit if loglevel is not high enough */ + } else if (log_handler == do_default_log) { + if (unlikely(*status == LOGLEVEL_UNDEFINED)) + *status = getLogLevel(module, logdefault); - int size = snprintf(NULL, 0, "%s:%s:%s:%d:%s() %s \n", - log_strings[loglevel], module, file, line, func, msg); - char fmt[size+1]; - snprintf(fmt, sizeof(fmt), "%s:%s:%s:%d:%s() %s \n", - log_strings[loglevel], module, file, line, func, msg); + if (loglevel > *status) + return; + } + + /* Either the message needs to be logged or needs to defer to registered handler */ + char usermsgbuf[1024]; va_list vaargs; va_start(vaargs, msg); - logfile = getLogFile(); - vfprintf (logfile, fmt, - /* log_strings[loglevel], module, file, func, line, */ - vaargs); - fflush(logfile); + vsnprintf(usermsgbuf, sizeof(usermsgbuf), msg, vaargs); va_end(vaargs); + + log_handler(loglevel, module, file, func, line, usermsgbuf); } static log_level diff --git a/src/util/log.h b/src/util/log.h index 75ed7191ad..925d6d2d1a 100644 --- a/src/util/log.h +++ b/src/util/log.h @@ -13,24 +13,6 @@ #define LOGDEFAULT LOGLEVEL_WARNING #endif -#define LOGL_NONE 0 -#define LOGL_ERROR 2 -#define LOGL_WARNING 3 -#define LOGL_INFO 4 -#define LOGL_DEBUG 5 -#define LOGL_TRACE 6 -#define LOGL_UNDEF 0xFF - -typedef enum { - LOGLEVEL_NONE = LOGL_NONE, - LOGLEVEL_ERROR = LOGL_ERROR, - LOGLEVEL_WARNING = LOGL_WARNING, - LOGLEVEL_INFO = LOGL_INFO, - LOGLEVEL_DEBUG = LOGL_DEBUG, - LOGLEVEL_TRACE = LOGL_TRACE, - LOGLEVEL_UNDEFINED = LOGL_UNDEF -} log_level; - static const char *log_strings[] COMPILER_ATTR(unused) = { "none", "(unused)", @@ -146,6 +128,8 @@ static log_level LOGMODULE_status COMPILER_ATTR(unused) = LOGLEVEL_UNDEFINED; #define LOGBLOB_TRACE(FORMAT, ...) {} #endif +TSS2_LOG_HANDLER set_log_handler(TSS2_LOG_HANDLER new_handler); + void doLog(log_level loglevel, const char *module, log_level logdefault, log_level *status,