diff --git a/ChangeLog b/ChangeLog index 76477b3..afab9eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,6 +34,11 @@ vNEXT: transparent socket. Transparent now uses CAP_NET_RAW instead of CAP_NET_ADMIN. + Removed compile-time option to use POSIX regex. Now + regex must be PCRE2 (Perl-Compatible). This was in + fact the case since v1.21, as PCRE are used to parse + the config file. + v1.21: 11JUL2020 WARNING: Moved configuration and command-line management to diff --git a/Makefile b/Makefile index 15631da..454fbd0 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,6 @@ VERSION=$(shell ./genver.sh -r) # change any of these ENABLE_REGEX=1 # Enable regex probes USELIBCONFIG=1 # Use libconfig? (necessary to use configuration files) -USELIBPCRE=1 # Use libpcre? (needed for regex on musl) USELIBWRAP?= # Use libwrap? USELIBCAP= # Use libcap? USESYSTEMD= # Make use of systemd socket activation @@ -25,9 +24,9 @@ ifneq ($(strip $(COV_TEST)),) endif CC ?= gcc -CFLAGS ?=-Wall -g $(CFLAGS_COV) +CFLAGS ?=-Wall -DLIBPCRE -g $(CFLAGS_COV) -LIBS=-lm +LIBS=-lm -lpcre2-8 OBJS=sslh-conf.o common.o sslh-main.o probe.o tls.o argtable3.o udp-listener.o collection.o gap.o CONDITIONAL_TARGETS= @@ -41,11 +40,6 @@ ifneq ($(strip $(ENABLE_REGEX)),) CPPFLAGS+=-DENABLE_REGEX endif -ifneq ($(strip $(USELIBPCRE)),) - CPPFLAGS+=-DLIBPCRE - LIBS:=$(LIBS) -lpcreposix -lpcre -endif - ifneq ($(strip $(USELIBCONFIG)),) LIBS:=$(LIBS) -lconfig CPPFLAGS+=-DLIBCONFIG diff --git a/echosrv-conf.c b/echosrv-conf.c index ce22d03..d7c0877 100644 --- a/echosrv-conf.c +++ b/echosrv-conf.c @@ -1,5 +1,5 @@ /* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README) - * on Thu Jul 8 13:25:39 2021. + * on Fri Jul 23 22:34:02 2021. # conf2struct: generate libconf parsers that read to structs # Copyright (C) 2018-2019 Yves Rutschle @@ -39,7 +39,12 @@ #include "echosrv-conf.h" #include "argtable3.h" #ifdef LIBPCRE -#include +#define PCRE2_CODE_UNIT_WIDTH 8 +#include +typedef struct { + PCRE2_SIZE rm_so; + PCRE2_SIZE rm_eo; +} regmatch_t; #else #include #endif @@ -961,11 +966,8 @@ static int add_arg_to_list(struct compound_cl_arg* arg, int arg_index, regmatch_ /* TODO: pass pmatch size as parameter or something */ #define MAX_MATCH 10 -/* Regex fiddling: uses info in arg to fill pmatch -* arg: description of the command line argument -* arg_index: occurence of this argument on the command line -*/ -static int regcompmatch(regmatch_t* pmatch, +#ifndef LIBPCRE +static int regcompmatch_posix( regmatch_t* pmatch, struct compound_cl_arg* arg, int arg_index, char** errmsg) @@ -991,6 +993,70 @@ static int regcompmatch(regmatch_t* pmatch, } return 1; } +#endif + + +#ifdef LIBPCRE +static int regcompmatch_pcre2( regmatch_t* pmatch, + struct compound_cl_arg* arg, + int arg_index, + char** errmsg) +{ + int i, error; + pcre2_code* pcre; + PCRE2_UCHAR8 err_str[120]; /* ample, according to pcre2api(3) */ + pcre2_match_data* matches; + PCRE2_SIZE error_offset; + struct arg_str* arg_cl = *arg->arg_cl; + + pcre = pcre2_compile((PCRE2_SPTR8)arg->regex, PCRE2_ZERO_TERMINATED, 0, &error, &error_offset, NULL); + if (!pcre) { + pcre2_get_error_message(error, err_str, sizeof(err_str)); + asprintf(errmsg, "compiling pattern /%s/:%d: %s at offset %ld\n", + arg->regex, error, err_str, error_offset); + return 0; + } + + matches = pcre2_match_data_create(MAX_MATCH, NULL); + int res = pcre2_match(pcre, (PCRE2_SPTR8)arg_cl->sval[arg_index], PCRE2_ZERO_TERMINATED, + 0, 0, matches, NULL); + if (res < 0) { + pcre2_get_error_message(res, err_str, sizeof(err_str)); + asprintf(errmsg, "matching %s =~ /%s/:%d: %s\n", + arg_cl->sval[arg_index], arg->regex, res, err_str); + return 0; + } + + PCRE2_SIZE *ovec = pcre2_get_ovector_pointer(matches); + if (res > MAX_MATCH) res = MAX_MATCH; + /* From pcre2posix.c */ + for (i = 0; i < res; i++) { + pmatch[i].rm_so = (ovec[i*2] == PCRE2_UNSET) ? -1 : ovec[i*2]; + pmatch[i].rm_eo = (ovec[i*2+1] == PCRE2_UNSET) ? -1 : ovec[i*2+1]; + } + for (; i < MAX_MATCH; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1; + + pcre2_match_data_free(matches); + return 1; +} +#endif + + +/* Regex fiddling: uses info in arg to fill pmatch +* arg: description of the command line argument +* arg_index: occurence of this argument on the command line +*/ +static int regcompmatch(regmatch_t* pmatch, + struct compound_cl_arg* arg, + int arg_index, + char** errmsg) +{ +#if LIBPCRE + return regcompmatch_pcre2(pmatch, arg, arg_index, errmsg); +#else + return regcompmatch_posix(pmatch, arg, arg_index, errmsg); +#endif +} /* Read compound options described in `arg`, from `cfg`, to `setting` */ static int read_compounds(config_setting_t* cfg, diff --git a/echosrv-conf.h b/echosrv-conf.h index e0d3576..21fd453 100644 --- a/echosrv-conf.h +++ b/echosrv-conf.h @@ -1,5 +1,5 @@ /* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README) - * on Thu Jul 8 13:25:39 2021. + * on Fri Jul 23 22:34:02 2021. # conf2struct: generate libconf parsers that read to structs # Copyright (C) 2018-2019 Yves Rutschle diff --git a/probe.c b/probe.c index 69cd03e..a08cfa4 100644 --- a/probe.c +++ b/probe.c @@ -22,12 +22,10 @@ #define _GNU_SOURCE #include #ifdef ENABLE_REGEX -#ifdef LIBPCRE -#include -#else +#define PCRE2_CODE_UNIT_WIDTH 8 +#include #include #endif -#endif #include #include "probe.h" diff --git a/sslh-conf.c b/sslh-conf.c index 3a0235a..0ad1ded 100644 --- a/sslh-conf.c +++ b/sslh-conf.c @@ -1,5 +1,5 @@ /* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README) - * on Thu Jul 8 13:25:38 2021. + * on Fri Jul 23 22:34:01 2021. # conf2struct: generate libconf parsers that read to structs # Copyright (C) 2018-2019 Yves Rutschle @@ -39,7 +39,12 @@ #include "sslh-conf.h" #include "argtable3.h" #ifdef LIBPCRE -#include +#define PCRE2_CODE_UNIT_WIDTH 8 +#include +typedef struct { + PCRE2_SIZE rm_so; + PCRE2_SIZE rm_eo; +} regmatch_t; #else #include #endif @@ -1616,11 +1621,8 @@ static int add_arg_to_list(struct compound_cl_arg* arg, int arg_index, regmatch_ /* TODO: pass pmatch size as parameter or something */ #define MAX_MATCH 10 -/* Regex fiddling: uses info in arg to fill pmatch -* arg: description of the command line argument -* arg_index: occurence of this argument on the command line -*/ -static int regcompmatch(regmatch_t* pmatch, +#ifndef LIBPCRE +static int regcompmatch_posix( regmatch_t* pmatch, struct compound_cl_arg* arg, int arg_index, char** errmsg) @@ -1646,6 +1648,70 @@ static int regcompmatch(regmatch_t* pmatch, } return 1; } +#endif + + +#ifdef LIBPCRE +static int regcompmatch_pcre2( regmatch_t* pmatch, + struct compound_cl_arg* arg, + int arg_index, + char** errmsg) +{ + int i, error; + pcre2_code* pcre; + PCRE2_UCHAR8 err_str[120]; /* ample, according to pcre2api(3) */ + pcre2_match_data* matches; + PCRE2_SIZE error_offset; + struct arg_str* arg_cl = *arg->arg_cl; + + pcre = pcre2_compile((PCRE2_SPTR8)arg->regex, PCRE2_ZERO_TERMINATED, 0, &error, &error_offset, NULL); + if (!pcre) { + pcre2_get_error_message(error, err_str, sizeof(err_str)); + asprintf(errmsg, "compiling pattern /%s/:%d: %s at offset %ld\n", + arg->regex, error, err_str, error_offset); + return 0; + } + + matches = pcre2_match_data_create(MAX_MATCH, NULL); + int res = pcre2_match(pcre, (PCRE2_SPTR8)arg_cl->sval[arg_index], PCRE2_ZERO_TERMINATED, + 0, 0, matches, NULL); + if (res < 0) { + pcre2_get_error_message(res, err_str, sizeof(err_str)); + asprintf(errmsg, "matching %s =~ /%s/:%d: %s\n", + arg_cl->sval[arg_index], arg->regex, res, err_str); + return 0; + } + + PCRE2_SIZE *ovec = pcre2_get_ovector_pointer(matches); + if (res > MAX_MATCH) res = MAX_MATCH; + /* From pcre2posix.c */ + for (i = 0; i < res; i++) { + pmatch[i].rm_so = (ovec[i*2] == PCRE2_UNSET) ? -1 : ovec[i*2]; + pmatch[i].rm_eo = (ovec[i*2+1] == PCRE2_UNSET) ? -1 : ovec[i*2+1]; + } + for (; i < MAX_MATCH; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1; + + pcre2_match_data_free(matches); + return 1; +} +#endif + + +/* Regex fiddling: uses info in arg to fill pmatch +* arg: description of the command line argument +* arg_index: occurence of this argument on the command line +*/ +static int regcompmatch(regmatch_t* pmatch, + struct compound_cl_arg* arg, + int arg_index, + char** errmsg) +{ +#if LIBPCRE + return regcompmatch_pcre2(pmatch, arg, arg_index, errmsg); +#else + return regcompmatch_posix(pmatch, arg, arg_index, errmsg); +#endif +} /* Read compound options described in `arg`, from `cfg`, to `setting` */ static int read_compounds(config_setting_t* cfg, diff --git a/sslh-conf.h b/sslh-conf.h index aafebda..4b4a191 100644 --- a/sslh-conf.h +++ b/sslh-conf.h @@ -1,5 +1,5 @@ /* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README) - * on Thu Jul 8 13:25:38 2021. + * on Fri Jul 23 22:34:01 2021. # conf2struct: generate libconf parsers that read to structs # Copyright (C) 2018-2019 Yves Rutschle diff --git a/sslh-main.c b/sslh-main.c index 5f8a566..abedcfd 100644 --- a/sslh-main.c +++ b/sslh-main.c @@ -27,7 +27,7 @@ #endif #ifdef ENABLE_REGEX #ifdef LIBPCRE -#include +#include #else #include #endif