mirror of
https://github.com/clearlinux/systemd-stable.git
synced 2026-09-01 11:16:00 +00:00
microhttp-util: rework gnutls logging
This commit is contained in:
@@ -989,7 +989,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
gnutls_global_set_log_function(log_func_gnutls);
|
||||
gnutls_global_set_log_level(GNUTLS_LOG_LEVEL);
|
||||
log_reset_gnutls_level();
|
||||
#endif
|
||||
|
||||
n = sd_listen_fds(1);
|
||||
|
||||
@@ -63,6 +63,7 @@ static char** arg_files = NULL;
|
||||
static int arg_compress = true;
|
||||
static int arg_seal = false;
|
||||
static int http_socket = -1, https_socket = -1;
|
||||
static char** arg_gnutls_log = NULL;
|
||||
|
||||
static char *key_pem = NULL;
|
||||
static char *cert_pem = NULL;
|
||||
@@ -969,6 +970,11 @@ static int help(void) {
|
||||
" -o --output=FILE|DIR Write output to FILE or DIR/external-*.journal\n"
|
||||
" --[no-]compress Use XZ-compression in the output journal (default: yes)\n"
|
||||
" --[no-]seal Use Event sealing in the output journal (default: no)\n"
|
||||
" --key=FILENAME Specify key in PEM format\n"
|
||||
" --cert=FILENAME Specify certificate in PEM format\n"
|
||||
" --trust=FILENAME Specify CA certificate in PEM format\n"
|
||||
" --gnutls-log=CATEGORY...\n"
|
||||
" Specify a list of gnutls logging categories\n"
|
||||
" -h --help Show this help and exit\n"
|
||||
" --version Print version string and exit\n"
|
||||
"\n"
|
||||
@@ -993,6 +999,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_KEY,
|
||||
ARG_CERT,
|
||||
ARG_TRUST,
|
||||
ARG_GNUTLS_LOG,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
@@ -1011,6 +1018,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "key", required_argument, NULL, ARG_KEY },
|
||||
{ "cert", required_argument, NULL, ARG_CERT },
|
||||
{ "trust", required_argument, NULL, ARG_TRUST },
|
||||
{ "gnutls-log", required_argument, NULL, ARG_GNUTLS_LOG },
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -1136,6 +1144,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
#else
|
||||
log_error("Option --trust is not available.");
|
||||
return -EINVAL;
|
||||
#endif
|
||||
|
||||
case 'o':
|
||||
@@ -1160,6 +1169,28 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_seal = false;
|
||||
break;
|
||||
|
||||
case ARG_GNUTLS_LOG: {
|
||||
#ifdef HAVE_GNUTLS
|
||||
char *word, *state;
|
||||
size_t size;
|
||||
|
||||
FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
|
||||
char *cat;
|
||||
|
||||
cat = strndup(word, size);
|
||||
if (!cat)
|
||||
return log_oom();
|
||||
|
||||
if (strv_consume(&arg_gnutls_log, cat) < 0)
|
||||
return log_oom();
|
||||
}
|
||||
break;
|
||||
#else
|
||||
log_error("Option --gnutls-log is not available.");
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
@@ -1179,13 +1210,26 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return 1 /* work to do */;
|
||||
}
|
||||
|
||||
static int setup_gnutls_logger(void) {
|
||||
static int setup_gnutls_logger(char **categories) {
|
||||
if (!arg_listen_http && !arg_listen_https)
|
||||
return 0;
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
gnutls_global_set_log_function(log_func_gnutls);
|
||||
gnutls_global_set_log_level(GNUTLS_LOG_LEVEL);
|
||||
{
|
||||
char **cat;
|
||||
int r;
|
||||
|
||||
gnutls_global_set_log_function(log_func_gnutls);
|
||||
|
||||
if (categories)
|
||||
STRV_FOREACH(cat, categories) {
|
||||
r = log_enable_gnutls_category(*cat);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
else
|
||||
log_reset_gnutls_level();
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@@ -1203,7 +1247,7 @@ int main(int argc, char **argv) {
|
||||
if (r <= 0)
|
||||
return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
|
||||
r = setup_gnutls_logger();
|
||||
r = setup_gnutls_logger(arg_gnutls_log);
|
||||
if (r < 0)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
#include "util.h"
|
||||
#include "strv.h"
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
#include <gnutls/gnutls.h>
|
||||
@@ -103,35 +104,64 @@ int mhd_respondf(struct MHD_Connection *connection,
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
|
||||
static int log_level_map[] = {
|
||||
LOG_DEBUG,
|
||||
LOG_WARNING, /* gnutls session audit */
|
||||
LOG_DEBUG, /* gnutls debug log */
|
||||
LOG_WARNING, /* gnutls assert log */
|
||||
LOG_INFO, /* gnutls handshake log */
|
||||
LOG_DEBUG, /* gnutls record log */
|
||||
LOG_DEBUG, /* gnutls dtls log */
|
||||
LOG_DEBUG,
|
||||
LOG_DEBUG,
|
||||
LOG_DEBUG,
|
||||
LOG_DEBUG, /* gnutls hard log */
|
||||
LOG_DEBUG, /* gnutls read log */
|
||||
LOG_DEBUG, /* gnutls write log */
|
||||
LOG_DEBUG, /* gnutls io log */
|
||||
LOG_DEBUG, /* gnutls buffers log */
|
||||
static struct {
|
||||
const char *const names[4];
|
||||
int level;
|
||||
bool enabled;
|
||||
} gnutls_log_map[] = {
|
||||
{ {"0"}, LOG_DEBUG },
|
||||
{ {"1", "audit"}, LOG_WARNING, true}, /* gnutls session audit */
|
||||
{ {"2", "assert"}, LOG_DEBUG }, /* gnutls assert log */
|
||||
{ {"3", "hsk", "ext"}, LOG_DEBUG }, /* gnutls handshake log */
|
||||
{ {"4", "rec"}, LOG_DEBUG }, /* gnutls record log */
|
||||
{ {"5", "dtls"}, LOG_DEBUG }, /* gnutls DTLS log */
|
||||
{ {"6", "buf"}, LOG_DEBUG },
|
||||
{ {"7", "write", "read"}, LOG_DEBUG },
|
||||
{ {"8"}, LOG_DEBUG },
|
||||
{ {"9", "enc", "int"}, LOG_DEBUG },
|
||||
};
|
||||
|
||||
void log_func_gnutls(int level, const char *message) {
|
||||
int ourlevel;
|
||||
|
||||
assert_se(message);
|
||||
|
||||
if (0 <= level && level < (int) ELEMENTSOF(log_level_map))
|
||||
ourlevel = log_level_map[level];
|
||||
else
|
||||
ourlevel = LOG_DEBUG;
|
||||
if (0 <= level && level < (int) ELEMENTSOF(gnutls_log_map)) {
|
||||
if (gnutls_log_map[level].enabled)
|
||||
log_meta(gnutls_log_map[level].level, NULL, 0, NULL,
|
||||
"gnutls %d/%s: %s", level, gnutls_log_map[level].names[1], message);
|
||||
} else {
|
||||
log_debug("Received GNUTLS message with unknown level %d.", level);
|
||||
log_meta(LOG_DEBUG, NULL, 0, NULL, "gnutls: %s", message);
|
||||
}
|
||||
}
|
||||
|
||||
log_meta(ourlevel, NULL, 0, NULL, "gnutls: %s", message);
|
||||
int log_enable_gnutls_category(const char *cat) {
|
||||
unsigned i;
|
||||
|
||||
if (streq(cat, "all")) {
|
||||
for (i = 0; i < ELEMENTSOF(gnutls_log_map); i++)
|
||||
gnutls_log_map[i].enabled = true;
|
||||
log_reset_gnutls_level();
|
||||
return 0;
|
||||
} else
|
||||
for (i = 0; i < ELEMENTSOF(gnutls_log_map); i++)
|
||||
if (strv_contains((char**)gnutls_log_map[i].names, cat)) {
|
||||
gnutls_log_map[i].enabled = true;
|
||||
log_reset_gnutls_level();
|
||||
return 0;
|
||||
}
|
||||
log_error("No such log category: %s", cat);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
void log_reset_gnutls_level(void) {
|
||||
int i;
|
||||
|
||||
for (i = ELEMENTSOF(gnutls_log_map) - 1; i >= 0; i--)
|
||||
if (gnutls_log_map[i].enabled) {
|
||||
log_debug("Setting gnutls log level to %d", i);
|
||||
gnutls_global_set_log_level(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int verify_cert_authorized(gnutls_session_t session) {
|
||||
|
||||
@@ -45,10 +45,11 @@ int check_permissions(struct MHD_Connection *connection, int *code);
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
void log_func_gnutls(int level, const char *message);
|
||||
int log_enable_gnutls_category(const char *cat);
|
||||
void log_reset_gnutls_level(void);
|
||||
|
||||
/* This is additionally filtered by our internal log level, so it
|
||||
* should be set fairly high to capture all potentially interesting
|
||||
* events without overwhelming detail.
|
||||
*/
|
||||
#define GNUTLS_LOG_LEVEL 6
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user