Skip to content

Commit 3817074

Browse files
committed
add support for regular expressions in Require statements with pcre2
- see OpenIDC/mod_oauth2#39 - depend on libpcre2 - fix memory leak in _oauth2_jose_options_jwk_set_rsa_key when using OpenSSL 3.x - bump to 1.5.0dev Signed-off-by: Hans Zandbelt <[email protected]>
1 parent 8d47a3d commit 3817074

File tree

11 files changed

+415
-411
lines changed

11 files changed

+415
-411
lines changed

.cproject

Lines changed: 195 additions & 374 deletions
Large diffs are not rendered by default.

.project

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
<projects>
66
</projects>
77
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.cdt.autotools.core.genmakebuilderV2</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
813
<buildCommand>
914
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
1015
<triggers>clean,full,incremental,</triggers>
@@ -20,8 +25,9 @@
2025
</buildSpec>
2126
<natures>
2227
<nature>org.eclipse.cdt.core.cnature</nature>
23-
<nature>org.eclipse.cdt.core.ccnature</nature>
2428
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
2529
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
30+
<nature>org.eclipse.cdt.autotools.core.autotoolsNatureV2</nature>
31+
<nature>org.eclipse.cdt.core.ccnature</nature>
2632
</natures>
2733
</projectDescription>

ChangeLog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
03/03/2023
2+
- add support for regular expressions in Require statements; see https://github.com/zmartzone/mod_oauth2/discussions/39
3+
- depend on libpcre2
4+
- fix memory leak in _oauth2_jose_options_jwk_set_rsa_key when using OpenSSL 3.x
5+
- bump to 1.5.0dev
6+
17
03/01/2023
28
- add support for introspect.params; see https://github.com/zmartzone/mod_oauth2/discussions/44
39
- release 1.4.5.5

Makefile.am

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ lib_LTLIBRARIES = liboauth2.la
4343
liboauth2_la_pkgconfigdir = $(libdir)/pkgconfig
4444
liboauth2_la_pkgconfig_DATA = liboauth2.pc
4545

46-
liboauth2_la_CFLAGS = @CURL_CFLAGS@ @CJOSE_CFLAGS@
47-
liboauth2_la_LIBADD = @CURL_LIBS@ @CJOSE_LIBS@
46+
liboauth2_la_CFLAGS = @CURL_CFLAGS@ @CJOSE_CFLAGS@ @PCRE2_CFLAGS@
47+
liboauth2_la_LIBADD = @CURL_LIBS@ @CJOSE_LIBS@ @PCRE2_LIBS@
4848

4949
liboauth2_la_SOURCES = \
5050
src/version.c \
@@ -161,7 +161,7 @@ TESTS = check_liboauth2
161161
check_PROGRAMS = $(TESTS)
162162

163163
check_liboauth2_CPPFLAGS = $(liboauth2_cache_la_CPPFLAGS)
164-
check_liboauth2_CFLAGS = @OPENSSL_CFLAGS@ @CURL_CFLAGS@ @CJOSE_CFLAGS@ @CHECK_CFLAGS@
164+
check_liboauth2_CFLAGS = @OPENSSL_CFLAGS@ @CURL_CFLAGS@ @CJOSE_CFLAGS@ @PCRE2_CFLAGS@ @CHECK_CFLAGS@
165165
check_liboauth2_LDADD = liboauth2.la
166166
if HAVE_APACHE
167167
check_liboauth2_CPPFLAGS += $(liboauth2_apache_la_CPPFLAGS)
@@ -173,7 +173,7 @@ check_liboauth2_CPPFLAGS += $(liboauth2_nginx_la_CPPFLAGS)
173173
check_liboauth2_CFLAGS += $(liboauth2_nginx_la_CFLAGS)
174174
check_liboauth2_LDADD += liboauth2_nginx.la
175175
endif
176-
check_liboauth2_LDADD += @OPENSSL_LIBS@ @CURL_LIBS@ @CJOSE_LIBS@ @CHECK_LIBS@
176+
check_liboauth2_LDADD += @OPENSSL_LIBS@ @CURL_LIBS@ @CJOSE_LIBS@ @PCRE2_LIBS@ @CHECK_LIBS@
177177

178178
check_liboauth2_SOURCES = \
179179
test/check_liboauth2.h \
@@ -226,10 +226,10 @@ docker-coverage: clean
226226
docker run -it --rm $(TAG):latest /bin/bash -c "./start.sh && make check-code-coverage"
227227

228228
docker-valgrind: docker
229-
docker run -it --rm -e CK_FORK=no $(TAG):latest /bin/bash -c "./start.sh && /usr/bin/valgrind --leak-check=full --show-leak-kinds=all .libs/check_liboauth2"
229+
docker run -it --rm -e CK_FORK=no $(TAG):latest /bin/bash -c "./start.sh && /usr/bin/valgrind --leak-check=full --show-leak-kinds=definite --read-inline-info=yes --keep-debuginfo=yes .libs/check_liboauth2"
230230

231231
docker-valgrind-%: docker
232-
docker run -it --rm -e CK_FORK=no -e CK_RUN_SUITE=${subst docker-valgrind-,,$@} $(TAG):latest /bin/bash -c "./start.sh && /usr/bin/valgrind --leak-check=full --show-leak-kinds=all .libs/check_liboauth2"
232+
docker run -it --rm -e CK_FORK=no -e CK_RUN_SUITE=${subst docker-valgrind-,,$@} $(TAG):latest /bin/bash -c "./start.sh && /usr/bin/valgrind --leak-check=full --show-leak-kinds=definite --read-inline-info=yes --keep-debuginfo=yes .libs/check_liboauth2"
233233

234234
docker-gdb: docker
235235
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -it --rm -e CK_FORK=no $(TAG):latest /bin/bash -c "./start.sh && /usr/bin/gdb .libs/check_liboauth2"

configure.ac

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
AC_INIT([liboauth2],[1.4.5.5],[[email protected]])
1+
AC_INIT([liboauth2],[1.5.0dev],[[email protected]])
22

33
AM_INIT_AUTOMAKE([foreign no-define subdir-objects])
44
AC_CONFIG_MACRO_DIR([m4])
@@ -25,6 +25,10 @@ PKG_CHECK_MODULES(CJOSE, cjose)
2525
AC_SUBST(CJOSE_CFLAGS)
2626
AC_SUBST(CJOSE_LIBS)
2727

28+
PKG_CHECK_MODULES(PCRE2, libpcre2-8)
29+
AC_SUBST(PCRE2_CFLAGS)
30+
AC_SUBST(PCRE2_LIBS)
31+
2832
AC_ARG_WITH([memcache], AS_HELP_STRING([--with-memcache], [build with Memcache cache support [default=autodetect]]),)
2933
if test "x$with_memcache" != "xno"; then
3034
PKG_CHECK_MODULES([MEMCACHE], [libmemcached >= 1.0], [have_memcache="yes"], [have_memcache="no"])

src/jose.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1649,7 +1649,10 @@ _oauth2_jose_options_jwk_set_rsa_key(oauth2_log_t *log, EVP_PKEY *pkey,
16491649
rv = _oauth2_jose_verify_options_jwk_add_jwk(log, jwk, params, verify);
16501650

16511651
end:
1652-
1652+
if (rsa_n)
1653+
BN_clear_free(rsa_n);
1654+
if (rsa_e)
1655+
BN_clear_free(rsa_e);
16531656
if (key_spec.n)
16541657
oauth2_mem_free(key_spec.n);
16551658
if (key_spec.e)

src/server/apache.c

Lines changed: 95 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <oauth2/mem.h>
2525
#include <oauth2/oauth2.h>
2626

27+
#include "util_int.h"
28+
2729
#include <http_core.h>
2830
#include <http_log.h>
2931
#include <http_protocol.h>
@@ -907,6 +909,90 @@ static bool oauth2_apache_authz_match_value(oauth2_apache_request_ctx_t *ctx,
907909
return false;
908910
}
909911

912+
static bool oauth2_apache_authz_match_expr(oauth2_apache_request_ctx_t *ctx,
913+
const char *spec_c, json_t *val)
914+
{
915+
bool rc = false;
916+
pcre2_code *preg = NULL;
917+
char *error_str = NULL;
918+
int i = 0;
919+
920+
/* setup the regex; spec_c points to the NULL-terminated value pattern
921+
*/
922+
preg = oauth2_pcre2_compile(spec_c);
923+
924+
if (preg == NULL) {
925+
oauth2_error(ctx->log,
926+
"pattern [%s] is not a valid regular expression",
927+
spec_c);
928+
goto end;
929+
}
930+
931+
/* see if the claim is a literal string */
932+
if (json_is_string(val)) {
933+
934+
error_str = NULL;
935+
/* PCRE-compare the string value against the expression */
936+
if (oauth2_pcre2_exec(preg, json_string_value(val),
937+
(int)strlen(json_string_value(val)),
938+
&error_str) > 0) {
939+
oauth2_debug(ctx->log,
940+
"value \"%s\" matched regex \"%s\"",
941+
json_string_value(val), spec_c);
942+
rc = true;
943+
goto end;
944+
} else if (error_str) {
945+
oauth2_debug(ctx->log, "pcre error (string): %s",
946+
error_str);
947+
}
948+
949+
/* see if the claim value is an array */
950+
} else if (json_is_array(val)) {
951+
952+
/* compare the claim values in the array against the expression
953+
*/
954+
for (i = 0; i < json_array_size(val); i++) {
955+
956+
json_t *elem = json_array_get(val, i);
957+
if (json_is_string(elem)) {
958+
959+
error_str = NULL;
960+
/* PCRE-compare the string value against the
961+
* expression */
962+
if (oauth2_pcre2_exec(
963+
preg, json_string_value(elem),
964+
(int)strlen(json_string_value(elem)),
965+
&error_str) > 0) {
966+
oauth2_debug(ctx->log,
967+
"array value \"%s\" "
968+
"matched regex \"%s\"",
969+
json_string_value(elem),
970+
spec_c);
971+
rc = true;
972+
goto end;
973+
} else if (error_str) {
974+
oauth2_debug(ctx->log,
975+
"pcre error (array): %s",
976+
error_str);
977+
}
978+
if (error_str) {
979+
oauth2_mem_free(error_str);
980+
error_str = NULL;
981+
}
982+
}
983+
}
984+
}
985+
986+
end:
987+
988+
if (error_str)
989+
oauth2_mem_free(error_str);
990+
if (preg)
991+
pcre2_code_free(preg);
992+
993+
return rc;
994+
}
995+
910996
bool oauth2_apache_authz_match_claim(oauth2_apache_request_ctx_t *ctx,
911997
const char *const attr_spec,
912998
const json_t *const claims)
@@ -949,17 +1035,15 @@ bool oauth2_apache_authz_match_claim(oauth2_apache_request_ctx_t *ctx,
9491035
return true;
9501036

9511037
/* a tilde denotes a string PCRE match */
952-
// } else if (!(*attr_c) &&
953-
//(*spec_c)
954-
//== '~') {
955-
//
956-
// /* skip the tilde */
957-
// spec_c++;
958-
//
959-
// if
960-
//(oauth2_authz_match_expression(r, spec_c, val) ==
961-
// TRUE) return
962-
// true;
1038+
} else if (!(*attr_c) && (*spec_c) == '~') {
1039+
1040+
/* skip the tilde */
1041+
spec_c++;
1042+
1043+
if (oauth2_apache_authz_match_expr(ctx, spec_c, val) ==
1044+
true)
1045+
return true;
1046+
9631047
/* dot means child nodes must be evaluated */
9641048
} else if (!(*attr_c) && (*spec_c) == '.') {
9651049

src/util.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,3 +1449,49 @@ char *oauth_read_file(oauth2_log_t *log, const char *filename)
14491449

14501450
return rv;
14511451
}
1452+
1453+
pcre2_code *oauth2_pcre2_compile(const char *regexp)
1454+
{
1455+
int errorcode;
1456+
PCRE2_SIZE erroroffset;
1457+
pcre2_code *preg =
1458+
pcre2_compile((PCRE2_SPTR)regexp, (PCRE2_SIZE)strlen(regexp), 0,
1459+
&errorcode, &erroroffset, NULL);
1460+
return preg;
1461+
}
1462+
1463+
int oauth2_pcre2_exec(pcre2_code *preg, const char *input, int len,
1464+
char **error_str)
1465+
{
1466+
int rc = 0;
1467+
pcre2_match_data *match_data = NULL;
1468+
1469+
match_data = pcre2_match_data_create_from_pattern(preg, NULL);
1470+
1471+
if (match_data == NULL) {
1472+
*error_str = oauth2_strdup(
1473+
"pcre2_match_data_create_from_pattern failed");
1474+
goto end;
1475+
}
1476+
1477+
rc = pcre2_match(preg, (PCRE2_SPTR)input, (PCRE2_SIZE)len, 0, 0,
1478+
match_data, NULL);
1479+
1480+
if (rc < 0) {
1481+
switch (rc) {
1482+
case PCRE2_ERROR_NOMATCH:
1483+
*error_str =
1484+
oauth2_strdup("string did not match the pattern");
1485+
break;
1486+
default:
1487+
*error_str = oauth2_strdup("unknown error");
1488+
break;
1489+
}
1490+
}
1491+
1492+
end:
1493+
if (match_data)
1494+
pcre2_match_data_free(match_data);
1495+
1496+
return rc;
1497+
}

src/util_int.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
#include <stddef.h>
3939
#include <stdio.h>
4040

41+
#define PCRE2_CODE_UNIT_WIDTH 8
42+
#include <pcre2.h>
43+
4144
#include "oauth2/log.h"
4245
#include "oauth2/util.h"
4346

@@ -173,4 +176,8 @@ char *_oauth2_bytes2str(oauth2_log_t *log, uint8_t *buf, size_t len);
173176
_OAUTH2_MEMBER_LIST_IMPLEMENT_UNSET_GET(module, type, list) \
174177
_OAUTH2_MEMBER_LIST_IMPLEMENT_ADD(module, type, list)
175178

179+
pcre2_code *oauth2_pcre2_compile(const char *regexp);
180+
int oauth2_pcre2_exec(pcre2_code *preg, const char *input, int len,
181+
char **error_str);
182+
176183
#endif /* _OAUTH2_UTIL_INT_H_ */

test/Dockerfile

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,20 @@
1-
#FROM ubuntu:trusty
2-
FROM ubuntu:bionic
3-
1+
FROM ubuntu:jammy
42

53
RUN apt-get update && apt-get install -y pkg-config make gcc gdb lcov valgrind vim curl wget
64
RUN apt-get update && apt-get install -y autoconf automake libtool
75
RUN apt-get update && apt-get install -y libssl-dev libjansson-dev libcurl4-openssl-dev check
86
RUN apt-get update && apt-get install -y apache2-dev
9-
#RUN apt-get update && apt-get install -y libcjose-dev
107
RUN apt-get update && apt-get install -y libpcre3-dev zlib1g-dev
118

12-
ENV NGINX_VERSION 1.16.1
9+
ENV NGINX_VERSION 1.18.0
1310
WORKDIR /root
1411
RUN wget https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz
1512
RUN tar zxvf nginx-${NGINX_VERSION}.tar.gz
1613
RUN ln -s nginx-${NGINX_VERSION} nginx
1714
RUN cd /root/nginx && ./configure --with-debug
1815

19-
#ENV FLAVOR trusty
20-
ENV FLAVOR bionic
21-
ENV CJOSE_VERSION 0.6.1.5
22-
23-
ENV CJOSE_PKG libcjose0_${CJOSE_VERSION}-1~${FLAVOR}+1_arm64.deb
24-
RUN curl -s -L -o ~/${CJOSE_PKG} https://mod-auth-openidc.org/download/${CJOSE_PKG}
25-
RUN dpkg -i ~/${CJOSE_PKG}
26-
ENV CJOSE_PKG libcjose-dev_${CJOSE_VERSION}-1~${FLAVOR}+1_arm64.deb
27-
RUN curl -s -L -o ~/${CJOSE_PKG} https://mod-auth-openidc.org/download/${CJOSE_PKG}
28-
RUN dpkg -i ~/${CJOSE_PKG}
29-
RUN apt-get update && apt-get install -y -f
30-
16+
RUN apt-get update && apt-get install -y libpcre2-dev libpcre2-8-0
17+
RUN apt-get update && apt-get install -y libcjose-dev libcjose0
3118
RUN apt-get update && apt-get install -y libmemcached-dev memcached
3219
RUN apt-get update && apt-get install -y libhiredis-dev redis-server
3320

0 commit comments

Comments
 (0)