/src/mod_auth_openidc/src/util/expr.c
Line | Count | Source |
1 | | /* |
2 | | * Licensed to the Apache Software Foundation (ASF) under one |
3 | | * or more contributor license agreements. See the NOTICE file |
4 | | * distributed with this work for additional information |
5 | | * regarding copyright ownership. The ASF licenses this file |
6 | | * to you under the Apache License, Version 2.0 (the |
7 | | * "License"); you may not use this file except in compliance |
8 | | * with the License. You may obtain a copy of the License at |
9 | | * |
10 | | * http://www.apache.org/licenses/LICENSE-2.0 |
11 | | * |
12 | | * Unless required by applicable law or agreed to in writing, |
13 | | * software distributed under the License is distributed on an |
14 | | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
15 | | * KIND, either express or implied. See the License for the |
16 | | * specific language governing permissions and limitations |
17 | | * under the License. |
18 | | */ |
19 | | |
20 | | /*************************************************************************** |
21 | | * Copyright (C) 2017-2026 ZmartZone Holding BV |
22 | | * All rights reserved. |
23 | | * |
24 | | * DISCLAIMER OF WARRANTIES: |
25 | | * |
26 | | * THE SOFTWARE PROVIDED HEREUNDER IS PROVIDED ON AN "AS IS" BASIS, WITHOUT |
27 | | * ANY WARRANTIES OR REPRESENTATIONS EXPRESS, IMPLIED OR STATUTORY; INCLUDING, |
28 | | * WITHOUT LIMITATION, WARRANTIES OF QUALITY, PERFORMANCE, NONINFRINGEMENT, |
29 | | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. NOR ARE THERE ANY |
30 | | * WARRANTIES CREATED BY A COURSE OR DEALING, COURSE OF PERFORMANCE OR TRADE |
31 | | * USAGE. FURTHERMORE, THERE ARE NO WARRANTIES THAT THE SOFTWARE WILL MEET |
32 | | * YOUR NEEDS OR BE FREE FROM ERRORS, OR THAT THE OPERATION OF THE SOFTWARE |
33 | | * WILL BE UNINTERRUPTED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR |
34 | | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
35 | | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES HOWEVER CAUSED AND ON ANY THEORY OF |
36 | | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
37 | | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
38 | | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
39 | | * |
40 | | * @Author: Hans Zandbelt - hans.zandbelt@openidc.com |
41 | | */ |
42 | | |
43 | | #include "util/pcre_subst.h" |
44 | | #include "util/util.h" |
45 | | #include "util/util_cfg.h" |
46 | | |
47 | | /* |
48 | | * regexp substitute |
49 | | * Example: |
50 | | * regex: "^.*([0-9]+).*$" |
51 | | * replace: "$1" |
52 | | * text_original: "match 292 numbers" |
53 | | * text_replaced: "292" |
54 | | */ |
55 | | apr_byte_t oidc_util_regexp_substitute(apr_pool_t *pool, const char *input, const char *regexp, const char *replace, |
56 | 0 | char **output, char **error_str) { |
57 | |
|
58 | 0 | const char *substituted = NULL; |
59 | 0 | apr_byte_t rc = FALSE; |
60 | |
|
61 | 0 | struct oidc_pcre *preg = oidc_pcre_compile(pool, regexp, error_str); |
62 | 0 | if (preg == NULL) { |
63 | 0 | *error_str = |
64 | 0 | apr_psprintf(pool, "pattern [%s] is not a valid regular expression: %s", regexp, *error_str); |
65 | 0 | goto out; |
66 | 0 | } |
67 | | |
68 | 0 | if (_oidc_strlen(input) > OIDC_PCRE_SUBST_MAX_INPUT_LEN) { |
69 | 0 | *error_str = apr_psprintf(pool, "string length (%d) is larger than the maximum allowed (%d)", |
70 | 0 | (int)_oidc_strlen(input), OIDC_PCRE_SUBST_MAX_INPUT_LEN); |
71 | 0 | goto out; |
72 | 0 | } |
73 | | |
74 | 0 | substituted = oidc_pcre_subst(pool, preg, input, (int)_oidc_strlen(input), replace); |
75 | 0 | if (substituted == NULL) { |
76 | 0 | *error_str = apr_psprintf( |
77 | 0 | pool, "unknown error could not match string [%s] using pattern [%s] and replace matches in [%s]", |
78 | 0 | input, regexp, replace); |
79 | 0 | goto out; |
80 | 0 | } |
81 | | |
82 | 0 | *output = apr_pstrdup(pool, substituted); |
83 | 0 | rc = TRUE; |
84 | |
|
85 | 0 | out: |
86 | |
|
87 | 0 | if (preg) |
88 | 0 | oidc_pcre_free(preg); |
89 | |
|
90 | 0 | return rc; |
91 | 0 | } |
92 | | |
93 | | /* |
94 | | * regexp match |
95 | | */ |
96 | | apr_byte_t oidc_util_regexp_first_match(apr_pool_t *pool, const char *input, const char *regexp, char **output, |
97 | 333 | char **error_str) { |
98 | 333 | apr_byte_t rv = FALSE; |
99 | 333 | int rc = 0; |
100 | | |
101 | 333 | struct oidc_pcre *preg = oidc_pcre_compile(pool, regexp, error_str); |
102 | 333 | if (preg == NULL) { |
103 | 0 | *error_str = |
104 | 0 | apr_psprintf(pool, "pattern [%s] is not a valid regular expression: %s", regexp, *error_str); |
105 | 0 | goto out; |
106 | 0 | } |
107 | | |
108 | 333 | if ((rc = oidc_pcre_exec(pool, preg, input, (int)_oidc_strlen(input), error_str)) < 0) |
109 | 322 | goto out; |
110 | | |
111 | 11 | if (output && (oidc_pcre_get_substring(pool, preg, input, rc, output, error_str) <= 0)) { |
112 | 0 | *error_str = apr_psprintf(pool, "pcre_get_substring failed: %s", *error_str); |
113 | 0 | goto out; |
114 | 0 | } |
115 | | |
116 | 11 | rv = TRUE; |
117 | | |
118 | 333 | out: |
119 | | |
120 | 333 | if (preg) |
121 | 333 | oidc_pcre_free(preg); |
122 | | |
123 | 333 | return rv; |
124 | 11 | } |
125 | | |
126 | | /* |
127 | | * parse an Apache expression |
128 | | */ |
129 | | char *oidc_util_apr_expr_parse(cmd_parms *cmd, const char *str, oidc_apr_expr_t **expr, |
130 | 0 | oidc_apr_expr_result_t result_type) { |
131 | 0 | char *rv = NULL; |
132 | 0 | if ((str == NULL) || (expr == NULL)) |
133 | 0 | return NULL; |
134 | 0 | *expr = apr_pcalloc(cmd->pool, sizeof(oidc_apr_expr_t)); |
135 | 0 | (*expr)->str = apr_pstrdup(cmd->pool, str); |
136 | 0 | const char *expr_err = NULL; |
137 | | /* combine the flags with bitwise-OR; "&" left flags at 0, dropping AP_EXPR_FLAG_RESTRICTED (and |
138 | | * AP_EXPR_FLAG_DONT_VARY) so the expression was parsed unrestricted even though these directives |
139 | | * are valid in .htaccess (OR_AUTHCFG) */ |
140 | 0 | unsigned int flags = AP_EXPR_FLAG_DONT_VARY | AP_EXPR_FLAG_RESTRICTED; |
141 | 0 | if (result_type) |
142 | 0 | flags |= AP_EXPR_FLAG_STRING_RESULT; |
143 | 0 | (*expr)->expr = ap_expr_parse_cmd(cmd, str, flags, &expr_err, NULL); |
144 | 0 | if (expr_err != NULL) { |
145 | 0 | rv = apr_pstrcat(cmd->temp_pool, "cannot parse expression: ", expr_err, NULL); |
146 | 0 | *expr = NULL; |
147 | 0 | } |
148 | 0 | return rv; |
149 | 0 | } |
150 | | |
151 | | /* |
152 | | * execute an Apache expression |
153 | | */ |
154 | 24 | const char *oidc_util_apr_expr_exec(request_rec *r, const oidc_apr_expr_t *expr, oidc_apr_expr_result_t result_type) { |
155 | 24 | const char *expr_result = NULL; |
156 | 24 | if (expr == NULL) |
157 | 24 | return NULL; |
158 | 0 | const char *expr_err = NULL; |
159 | 0 | if (result_type) { |
160 | 0 | expr_result = ap_expr_str_exec(r, expr->expr, &expr_err); |
161 | 0 | } else { |
162 | 0 | expr_result = ap_expr_exec(r, expr->expr, &expr_err) ? "" : NULL; |
163 | 0 | } |
164 | 0 | if (expr_err) { |
165 | 0 | oidc_error(r, "executing expression \"%s\" failed: %s", expr->str, expr_err); |
166 | | expr_result = NULL; |
167 | 0 | } |
168 | 0 | return expr_result; |
169 | 24 | } |