mirror of
https://github.com/yrutschle/sslh.git
synced 2025-04-12 23:27:15 +03:00
Added support for logging to a file.
* Added ASAN/LSAN/UBSAN support via Makefile * Fixed a memory leak Signed-off-by: lns <matzeton@googlemail.com>
This commit is contained in:
parent
43bd660df2
commit
f9831df8bc
7
Makefile
7
Makefile
@ -3,6 +3,7 @@ VERSION=$(shell ./genver.sh -r)
|
|||||||
|
|
||||||
# Configuration -- you probably need to `make clean` if you
|
# Configuration -- you probably need to `make clean` if you
|
||||||
# change any of these
|
# change any of these
|
||||||
|
ENABLE_SANITIZER= # Enable ASAN/LSAN/UBSAN
|
||||||
ENABLE_REGEX=1 # Enable regex probes
|
ENABLE_REGEX=1 # Enable regex probes
|
||||||
USELIBCONFIG=1 # Use libconfig? (necessary to use configuration files)
|
USELIBCONFIG=1 # Use libconfig? (necessary to use configuration files)
|
||||||
USELIBWRAP?= # Use libwrap?
|
USELIBWRAP?= # Use libwrap?
|
||||||
@ -19,12 +20,16 @@ MAN=sslh.8.gz # man page name
|
|||||||
# End of configuration -- the rest should take care of
|
# End of configuration -- the rest should take care of
|
||||||
# itself
|
# itself
|
||||||
|
|
||||||
|
ifneq ($(strip $(ENABLE_SANITIZER)),)
|
||||||
|
CFLAGS_SAN=-fsanitize=address -fsanitize=leak -fsanitize=undefined
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq ($(strip $(COV_TEST)),)
|
ifneq ($(strip $(COV_TEST)),)
|
||||||
CFLAGS_COV=-fprofile-arcs -ftest-coverage
|
CFLAGS_COV=-fprofile-arcs -ftest-coverage
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
CFLAGS ?=-Wall -DLIBPCRE -g $(CFLAGS_COV)
|
CFLAGS ?=-Wall -DLIBPCRE -g $(CFLAGS_COV) $(CFLAGS_SAN)
|
||||||
|
|
||||||
LIBS=-lm -lpcre2-8
|
LIBS=-lm -lpcre2-8
|
||||||
OBJS=sslh-conf.o common.o log.o sslh-main.o probe.o tls.o argtable3.o collection.o gap.o
|
OBJS=sslh-conf.o common.o log.o sslh-main.o probe.o tls.o argtable3.o collection.o gap.o
|
||||||
|
@ -13,7 +13,7 @@ pidfile: "/var/run/sslh.pid";
|
|||||||
chroot: "/var/empty";
|
chroot: "/var/empty";
|
||||||
|
|
||||||
# Logging configuration
|
# Logging configuration
|
||||||
# Value: 1: stdout; 2: syslog; 3: both
|
# Value: 1: stdout; 2: syslog; 3: stdout+syslog; 4: logfile; ...; 7: all
|
||||||
# Defaults are indicated here, and should be sensible. Generally, you want *-error
|
# Defaults are indicated here, and should be sensible. Generally, you want *-error
|
||||||
# to be always enabled, to know if something is going wrong.
|
# to be always enabled, to know if something is going wrong.
|
||||||
verbose-config: 0; # print configuration at startup
|
verbose-config: 0; # print configuration at startup
|
||||||
@ -29,6 +29,10 @@ verbose-system-error: 3; # system call problem, i.e. malloc, fork, failing
|
|||||||
verbose-int-error: 3; # internal errors, the kind that should never happen
|
verbose-int-error: 3; # internal errors, the kind that should never happen
|
||||||
|
|
||||||
|
|
||||||
|
# Specify a path to the logfile.
|
||||||
|
#logfile: "/var/log/sslh.log"
|
||||||
|
|
||||||
|
|
||||||
# Specify which syslog facility to use (names for your
|
# Specify which syslog facility to use (names for your
|
||||||
# system are usually defined in /usr/include/*/sys/syslog.h
|
# system are usually defined in /usr/include/*/sys/syslog.h
|
||||||
# or equivalent)
|
# or equivalent)
|
||||||
|
34
log.c
34
log.c
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#define SYSLOG_NAMES
|
#define SYSLOG_NAMES
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
#include <errno.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "sslh-conf.h"
|
#include "sslh-conf.h"
|
||||||
@ -97,6 +98,9 @@ msg_info msg_probe_error = {
|
|||||||
/* Bitmasks in verbose-* values */
|
/* Bitmasks in verbose-* values */
|
||||||
#define MSG_STDOUT 1
|
#define MSG_STDOUT 1
|
||||||
#define MSG_SYSLOG 2
|
#define MSG_SYSLOG 2
|
||||||
|
#define MSG_FILE 4
|
||||||
|
|
||||||
|
static FILE* logfile_fp = NULL;
|
||||||
|
|
||||||
/* Prints a message to stderr and/or syslog if appropriate */
|
/* Prints a message to stderr and/or syslog if appropriate */
|
||||||
void print_message(msg_info info, const char* str, ...)
|
void print_message(msg_info info, const char* str, ...)
|
||||||
@ -113,6 +117,13 @@ void print_message(msg_info info, const char* str, ...)
|
|||||||
vsyslog(info.log_level, str, ap);
|
vsyslog(info.log_level, str, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*info.verbose & MSG_FILE && logfile_fp != NULL) {
|
||||||
|
va_start(ap, str);
|
||||||
|
vfprintf(logfile_fp, str, ap);
|
||||||
|
fflush(logfile_fp);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_syslog = 1; /* Should we syslog? controled by syslog_facility = "none" */
|
static int do_syslog = 1; /* Should we syslog? controled by syslog_facility = "none" */
|
||||||
@ -145,6 +156,29 @@ void setup_syslog(const char* bin_name) {
|
|||||||
/* Don't free name2, as openlog(3) uses it (at least in glibc) */
|
/* Don't free name2, as openlog(3) uses it (at least in glibc) */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setup_logfile()
|
||||||
|
{
|
||||||
|
if (cfg.logfile == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logfile_fp = fopen(cfg.logfile, "a");
|
||||||
|
if (logfile_fp == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not open logfile %s for writing: %s\n", cfg.logfile, strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void close_logfile()
|
||||||
|
{
|
||||||
|
if (logfile_fp != NULL)
|
||||||
|
{
|
||||||
|
fclose(logfile_fp);
|
||||||
|
logfile_fp = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* syslogs who connected to where
|
/* syslogs who connected to where
|
||||||
* desc: string description of the connection. if NULL, log_connection will
|
* desc: string description of the connection. if NULL, log_connection will
|
||||||
|
4
log.h
4
log.h
@ -5,6 +5,10 @@
|
|||||||
|
|
||||||
void setup_syslog(const char* bin_name);
|
void setup_syslog(const char* bin_name);
|
||||||
|
|
||||||
|
void setup_logfile();
|
||||||
|
|
||||||
|
void close_logfile();
|
||||||
|
|
||||||
void log_connection(struct connection_desc* desc, const struct connection *cnx);
|
void log_connection(struct connection_desc* desc, const struct connection *cnx);
|
||||||
|
|
||||||
typedef struct s_msg_info{
|
typedef struct s_msg_info{
|
||||||
|
47
sslh-conf.c
47
sslh-conf.c
@ -1,5 +1,5 @@
|
|||||||
/* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README)
|
/* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README)
|
||||||
* on Sun Apr 10 08:52:30 2022.
|
* on Thu Apr 28 14:54:03 2022.
|
||||||
|
|
||||||
# conf2struct: generate libconf parsers that read to structs
|
# conf2struct: generate libconf parsers that read to structs
|
||||||
# Copyright (C) 2018-2021 Yves Rutschle
|
# Copyright (C) 2018-2021 Yves Rutschle
|
||||||
@ -465,6 +465,7 @@ struct arg_file* sslhcfg_conffile;
|
|||||||
struct arg_str* sslhcfg_pidfile;
|
struct arg_str* sslhcfg_pidfile;
|
||||||
struct arg_str* sslhcfg_chroot;
|
struct arg_str* sslhcfg_chroot;
|
||||||
struct arg_str* sslhcfg_syslog_facility;
|
struct arg_str* sslhcfg_syslog_facility;
|
||||||
|
struct arg_str* sslhcfg_logfile;
|
||||||
struct arg_str* sslhcfg_on_timeout;
|
struct arg_str* sslhcfg_on_timeout;
|
||||||
struct arg_str* sslhcfg_prefix;
|
struct arg_str* sslhcfg_prefix;
|
||||||
struct arg_str* sslhcfg_listen;
|
struct arg_str* sslhcfg_listen;
|
||||||
@ -1166,6 +1167,22 @@ static struct config_desc table_sslhcfg[] = {
|
|||||||
/* default_val*/ .default_val.def_string = "auth"
|
/* default_val*/ .default_val.def_string = "auth"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
/* name */ "logfile",
|
||||||
|
/* type */ CFG_STRING,
|
||||||
|
/* sub_group*/ NULL,
|
||||||
|
/* arg_cl */ & sslhcfg_logfile,
|
||||||
|
/* base_addr */ NULL,
|
||||||
|
/* offset */ offsetof(struct sslhcfg_item, logfile),
|
||||||
|
/* offset_len */ 0,
|
||||||
|
/* offset_present */ offsetof(struct sslhcfg_item, logfile_is_present),
|
||||||
|
/* size */ sizeof(char*),
|
||||||
|
/* array_type */ -1,
|
||||||
|
/* mandatory */ 0,
|
||||||
|
/* optional */ 1,
|
||||||
|
/* default_val*/ .default_val.def_string = NULL
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
/* name */ "on_timeout",
|
/* name */ "on_timeout",
|
||||||
/* type */ CFG_STRING,
|
/* type */ CFG_STRING,
|
||||||
@ -1326,7 +1343,7 @@ static struct compound_cl_arg compound_cl_args[] = {
|
|||||||
{ /* arg: listen */
|
{ /* arg: listen */
|
||||||
.regex = "(.+):(\\w+)",
|
.regex = "(.+):(\\w+)",
|
||||||
.arg_cl = & sslhcfg_listen,
|
.arg_cl = & sslhcfg_listen,
|
||||||
.base_entry = & table_sslhcfg [24],
|
.base_entry = & table_sslhcfg [25],
|
||||||
.targets = sslhcfg_listen_targets,
|
.targets = sslhcfg_listen_targets,
|
||||||
|
|
||||||
|
|
||||||
@ -1338,7 +1355,7 @@ static struct compound_cl_arg compound_cl_args[] = {
|
|||||||
{ /* arg: ssh */
|
{ /* arg: ssh */
|
||||||
.regex = "(.+):(\\w+)",
|
.regex = "(.+):(\\w+)",
|
||||||
.arg_cl = & sslhcfg_ssh,
|
.arg_cl = & sslhcfg_ssh,
|
||||||
.base_entry = & table_sslhcfg [25],
|
.base_entry = & table_sslhcfg [26],
|
||||||
.targets = sslhcfg_ssh_targets,
|
.targets = sslhcfg_ssh_targets,
|
||||||
|
|
||||||
|
|
||||||
@ -1350,7 +1367,7 @@ static struct compound_cl_arg compound_cl_args[] = {
|
|||||||
{ /* arg: tls */
|
{ /* arg: tls */
|
||||||
.regex = "(.+):(\\w+)",
|
.regex = "(.+):(\\w+)",
|
||||||
.arg_cl = & sslhcfg_tls,
|
.arg_cl = & sslhcfg_tls,
|
||||||
.base_entry = & table_sslhcfg [25],
|
.base_entry = & table_sslhcfg [26],
|
||||||
.targets = sslhcfg_tls_targets,
|
.targets = sslhcfg_tls_targets,
|
||||||
|
|
||||||
|
|
||||||
@ -1362,7 +1379,7 @@ static struct compound_cl_arg compound_cl_args[] = {
|
|||||||
{ /* arg: openvpn */
|
{ /* arg: openvpn */
|
||||||
.regex = "(.+):(\\w+)",
|
.regex = "(.+):(\\w+)",
|
||||||
.arg_cl = & sslhcfg_openvpn,
|
.arg_cl = & sslhcfg_openvpn,
|
||||||
.base_entry = & table_sslhcfg [25],
|
.base_entry = & table_sslhcfg [26],
|
||||||
.targets = sslhcfg_openvpn_targets,
|
.targets = sslhcfg_openvpn_targets,
|
||||||
|
|
||||||
|
|
||||||
@ -1374,7 +1391,7 @@ static struct compound_cl_arg compound_cl_args[] = {
|
|||||||
{ /* arg: tinc */
|
{ /* arg: tinc */
|
||||||
.regex = "(.+):(\\w+)",
|
.regex = "(.+):(\\w+)",
|
||||||
.arg_cl = & sslhcfg_tinc,
|
.arg_cl = & sslhcfg_tinc,
|
||||||
.base_entry = & table_sslhcfg [25],
|
.base_entry = & table_sslhcfg [26],
|
||||||
.targets = sslhcfg_tinc_targets,
|
.targets = sslhcfg_tinc_targets,
|
||||||
|
|
||||||
|
|
||||||
@ -1386,7 +1403,7 @@ static struct compound_cl_arg compound_cl_args[] = {
|
|||||||
{ /* arg: xmpp */
|
{ /* arg: xmpp */
|
||||||
.regex = "(.+):(\\w+)",
|
.regex = "(.+):(\\w+)",
|
||||||
.arg_cl = & sslhcfg_xmpp,
|
.arg_cl = & sslhcfg_xmpp,
|
||||||
.base_entry = & table_sslhcfg [25],
|
.base_entry = & table_sslhcfg [26],
|
||||||
.targets = sslhcfg_xmpp_targets,
|
.targets = sslhcfg_xmpp_targets,
|
||||||
|
|
||||||
|
|
||||||
@ -1398,7 +1415,7 @@ static struct compound_cl_arg compound_cl_args[] = {
|
|||||||
{ /* arg: http */
|
{ /* arg: http */
|
||||||
.regex = "(.+):(\\w+)",
|
.regex = "(.+):(\\w+)",
|
||||||
.arg_cl = & sslhcfg_http,
|
.arg_cl = & sslhcfg_http,
|
||||||
.base_entry = & table_sslhcfg [25],
|
.base_entry = & table_sslhcfg [26],
|
||||||
.targets = sslhcfg_http_targets,
|
.targets = sslhcfg_http_targets,
|
||||||
|
|
||||||
|
|
||||||
@ -1410,7 +1427,7 @@ static struct compound_cl_arg compound_cl_args[] = {
|
|||||||
{ /* arg: adb */
|
{ /* arg: adb */
|
||||||
.regex = "(.+):(\\w+)",
|
.regex = "(.+):(\\w+)",
|
||||||
.arg_cl = & sslhcfg_adb,
|
.arg_cl = & sslhcfg_adb,
|
||||||
.base_entry = & table_sslhcfg [25],
|
.base_entry = & table_sslhcfg [26],
|
||||||
.targets = sslhcfg_adb_targets,
|
.targets = sslhcfg_adb_targets,
|
||||||
|
|
||||||
|
|
||||||
@ -1422,7 +1439,7 @@ static struct compound_cl_arg compound_cl_args[] = {
|
|||||||
{ /* arg: socks5 */
|
{ /* arg: socks5 */
|
||||||
.regex = "(.+):(\\w+)",
|
.regex = "(.+):(\\w+)",
|
||||||
.arg_cl = & sslhcfg_socks5,
|
.arg_cl = & sslhcfg_socks5,
|
||||||
.base_entry = & table_sslhcfg [25],
|
.base_entry = & table_sslhcfg [26],
|
||||||
.targets = sslhcfg_socks5_targets,
|
.targets = sslhcfg_socks5_targets,
|
||||||
|
|
||||||
|
|
||||||
@ -1434,7 +1451,7 @@ static struct compound_cl_arg compound_cl_args[] = {
|
|||||||
{ /* arg: syslog */
|
{ /* arg: syslog */
|
||||||
.regex = "(.+):(\\w+)",
|
.regex = "(.+):(\\w+)",
|
||||||
.arg_cl = & sslhcfg_syslog,
|
.arg_cl = & sslhcfg_syslog,
|
||||||
.base_entry = & table_sslhcfg [25],
|
.base_entry = & table_sslhcfg [26],
|
||||||
.targets = sslhcfg_syslog_targets,
|
.targets = sslhcfg_syslog_targets,
|
||||||
|
|
||||||
|
|
||||||
@ -1446,7 +1463,7 @@ static struct compound_cl_arg compound_cl_args[] = {
|
|||||||
{ /* arg: anyprot */
|
{ /* arg: anyprot */
|
||||||
.regex = "(.+):(\\w+)",
|
.regex = "(.+):(\\w+)",
|
||||||
.arg_cl = & sslhcfg_anyprot,
|
.arg_cl = & sslhcfg_anyprot,
|
||||||
.base_entry = & table_sslhcfg [25],
|
.base_entry = & table_sslhcfg [26],
|
||||||
.targets = sslhcfg_anyprot_targets,
|
.targets = sslhcfg_anyprot_targets,
|
||||||
|
|
||||||
|
|
||||||
@ -2133,6 +2150,7 @@ int sslhcfg_cl_parse(int argc, char* argv[], struct sslhcfg_item* cfg)
|
|||||||
sslhcfg_pidfile = arg_strn("P", "pidfile", "<file>", 0, 1, "Path to file to store PID of current instance"),
|
sslhcfg_pidfile = arg_strn("P", "pidfile", "<file>", 0, 1, "Path to file to store PID of current instance"),
|
||||||
sslhcfg_chroot = arg_strn("C", "chroot", "<path>", 0, 1, "Root to change to after set-up"),
|
sslhcfg_chroot = arg_strn("C", "chroot", "<path>", 0, 1, "Root to change to after set-up"),
|
||||||
sslhcfg_syslog_facility = arg_strn(NULL, "syslog-facility", "<str>", 0, 1, "Facility to syslog to"),
|
sslhcfg_syslog_facility = arg_strn(NULL, "syslog-facility", "<str>", 0, 1, "Facility to syslog to"),
|
||||||
|
sslhcfg_logfile = arg_strn(NULL, "logfile", "<str>", 0, 1, "Log messages to a file"),
|
||||||
sslhcfg_on_timeout = arg_strn(NULL, "on-timeout", "<str>", 0, 1, "Target to connect to when timing out"),
|
sslhcfg_on_timeout = arg_strn(NULL, "on-timeout", "<str>", 0, 1, "Target to connect to when timing out"),
|
||||||
sslhcfg_prefix = arg_strn(NULL, "prefix", "<str>", 0, 1, "Reserved for testing"),
|
sslhcfg_prefix = arg_strn(NULL, "prefix", "<str>", 0, 1, "Reserved for testing"),
|
||||||
sslhcfg_listen = arg_strn("p", "listen", "<host:port>", 0, 10, "Listen on host:port"),
|
sslhcfg_listen = arg_strn("p", "listen", "<host:port>", 0, 10, "Listen on host:port"),
|
||||||
@ -2366,6 +2384,11 @@ void sslhcfg_fprint(
|
|||||||
fprintf(out, "syslog_facility: %s", sslhcfg->syslog_facility);
|
fprintf(out, "syslog_facility: %s", sslhcfg->syslog_facility);
|
||||||
fprintf(out, "\n");
|
fprintf(out, "\n");
|
||||||
indent(out, depth);
|
indent(out, depth);
|
||||||
|
fprintf(out, "logfile: %s", sslhcfg->logfile);
|
||||||
|
if (! sslhcfg->logfile_is_present)
|
||||||
|
fprintf(out, " <unset>");
|
||||||
|
fprintf(out, "\n");
|
||||||
|
indent(out, depth);
|
||||||
fprintf(out, "on_timeout: %s", sslhcfg->on_timeout);
|
fprintf(out, "on_timeout: %s", sslhcfg->on_timeout);
|
||||||
fprintf(out, "\n");
|
fprintf(out, "\n");
|
||||||
indent(out, depth);
|
indent(out, depth);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README)
|
/* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README)
|
||||||
* on Sun Apr 10 08:52:30 2022.
|
* on Thu Apr 28 14:54:03 2022.
|
||||||
|
|
||||||
# conf2struct: generate libconf parsers that read to structs
|
# conf2struct: generate libconf parsers that read to structs
|
||||||
# Copyright (C) 2018-2021 Yves Rutschle
|
# Copyright (C) 2018-2021 Yves Rutschle
|
||||||
@ -100,6 +100,8 @@ struct sslhcfg_item {
|
|||||||
int chroot_is_present;
|
int chroot_is_present;
|
||||||
char* chroot;
|
char* chroot;
|
||||||
char* syslog_facility;
|
char* syslog_facility;
|
||||||
|
int logfile_is_present;
|
||||||
|
char* logfile;
|
||||||
char* on_timeout;
|
char* on_timeout;
|
||||||
char* prefix;
|
char* prefix;
|
||||||
size_t listen_len;
|
size_t listen_len;
|
||||||
|
@ -240,6 +240,9 @@ int main(int argc, char *argv[], char* envp[])
|
|||||||
/* Open syslog connection before we drop privs/chroot */
|
/* Open syslog connection before we drop privs/chroot */
|
||||||
setup_syslog(argv[0]);
|
setup_syslog(argv[0]);
|
||||||
|
|
||||||
|
/* Open log file for writing */
|
||||||
|
setup_logfile();
|
||||||
|
|
||||||
if (cfg.user || cfg.chroot)
|
if (cfg.user || cfg.chroot)
|
||||||
drop_privileges(cfg.user, cfg.chroot);
|
drop_privileges(cfg.user, cfg.chroot);
|
||||||
|
|
||||||
@ -249,5 +252,9 @@ int main(int argc, char *argv[], char* envp[])
|
|||||||
|
|
||||||
main_loop(listen_sockets, num_addr_listen);
|
main_loop(listen_sockets, num_addr_listen);
|
||||||
|
|
||||||
|
close_logfile();
|
||||||
|
|
||||||
|
free(listen_sockets);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,8 @@ config: {
|
|||||||
description: "Root to change to after set-up"; },
|
description: "Root to change to after set-up"; },
|
||||||
{ name: "syslog_facility"; type: "string"; default: "auth";
|
{ name: "syslog_facility"; type: "string"; default: "auth";
|
||||||
description: "Facility to syslog to"; },
|
description: "Facility to syslog to"; },
|
||||||
|
{ name: "logfile"; type: "string"; optional: true;
|
||||||
|
description: "Log messages to a file" },
|
||||||
|
|
||||||
{ name: "on-timeout"; type: "string"; default: "ssh";
|
{ name: "on-timeout"; type: "string"; default: "ssh";
|
||||||
description: "Target to connect to when timing out"; },
|
description: "Target to connect to when timing out"; },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user