Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/heimdal/lib/hx509/sel.c
34889 views
1
/*
2
* Copyright (c) 2008 Kungliga Tekniska Högskolan
3
* (Royal Institute of Technology, Stockholm, Sweden).
4
* All rights reserved.
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
*
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
*
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
*
17
* 3. Neither the name of the Institute nor the names of its contributors
18
* may be used to endorse or promote products derived from this software
19
* without specific prior written permission.
20
*
21
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
* SUCH DAMAGE.
32
*/
33
34
#include "hx_locl.h"
35
36
struct hx_expr *
37
_hx509_make_expr(enum hx_expr_op op, void *arg1, void *arg2)
38
{
39
struct hx_expr *expr;
40
41
expr = malloc(sizeof(*expr));
42
if (expr == NULL)
43
return NULL;
44
expr->op = op;
45
expr->arg1 = arg1;
46
expr->arg2 = arg2;
47
48
return expr;
49
}
50
51
static const char *
52
eval_word(hx509_context context, hx509_env env, struct hx_expr *word)
53
{
54
switch (word->op) {
55
case expr_STRING:
56
return word->arg1;
57
case expr_VAR:
58
if (word->arg2 == NULL)
59
return hx509_env_find(context, env, word->arg1);
60
61
env = hx509_env_find_binding(context, env, word->arg1);
62
if (env == NULL)
63
return NULL;
64
65
return eval_word(context, env, word->arg2);
66
default:
67
return NULL;
68
}
69
}
70
71
static hx509_env
72
find_variable(hx509_context context, hx509_env env, struct hx_expr *word)
73
{
74
assert(word->op == expr_VAR);
75
76
if (word->arg2 == NULL)
77
return hx509_env_find_binding(context, env, word->arg1);
78
79
env = hx509_env_find_binding(context, env, word->arg1);
80
if (env == NULL)
81
return NULL;
82
return find_variable(context, env, word->arg2);
83
}
84
85
static int
86
eval_comp(hx509_context context, hx509_env env, struct hx_expr *expr)
87
{
88
switch (expr->op) {
89
case comp_NE:
90
case comp_EQ:
91
case comp_TAILEQ: {
92
const char *s1, *s2;
93
int ret;
94
95
s1 = eval_word(context, env, expr->arg1);
96
s2 = eval_word(context, env, expr->arg2);
97
98
if (s1 == NULL || s2 == NULL)
99
return FALSE;
100
101
if (expr->op == comp_TAILEQ) {
102
size_t len1 = strlen(s1);
103
size_t len2 = strlen(s2);
104
105
if (len1 < len2)
106
return 0;
107
ret = strcmp(s1 + (len1 - len2), s2) == 0;
108
} else {
109
ret = strcmp(s1, s2) == 0;
110
if (expr->op == comp_NE)
111
ret = !ret;
112
}
113
return ret;
114
}
115
case comp_IN: {
116
struct hx_expr *subexpr;
117
const char *w, *s1;
118
119
w = eval_word(context, env, expr->arg1);
120
121
subexpr = expr->arg2;
122
123
if (subexpr->op == expr_WORDS) {
124
while (subexpr) {
125
s1 = eval_word(context, env, subexpr->arg1);
126
if (strcmp(w, s1) == 0)
127
return TRUE;
128
subexpr = subexpr->arg2;
129
}
130
} else if (subexpr->op == expr_VAR) {
131
hx509_env subenv;
132
133
subenv = find_variable(context, env, subexpr);
134
if (subenv == NULL)
135
return FALSE;
136
137
while (subenv) {
138
if (subenv->type != env_string)
139
continue;
140
if (strcmp(w, subenv->name) == 0)
141
return TRUE;
142
if (strcmp(w, subenv->u.string) == 0)
143
return TRUE;
144
subenv = subenv->next;
145
}
146
147
} else
148
_hx509_abort("hx509 eval IN unknown op: %d", (int)subexpr->op);
149
150
return FALSE;
151
}
152
default:
153
_hx509_abort("hx509 eval expr with unknown op: %d", (int)expr->op);
154
}
155
return FALSE;
156
}
157
158
int
159
_hx509_expr_eval(hx509_context context, hx509_env env, struct hx_expr *expr)
160
{
161
switch (expr->op) {
162
case op_TRUE:
163
return 1;
164
case op_FALSE:
165
return 0;
166
case op_NOT:
167
return ! _hx509_expr_eval(context, env, expr->arg1);
168
case op_AND:
169
return _hx509_expr_eval(context, env, expr->arg1) &&
170
_hx509_expr_eval(context, env, expr->arg2);
171
case op_OR:
172
return _hx509_expr_eval(context, env, expr->arg1) ||
173
_hx509_expr_eval(context, env, expr->arg2);
174
case op_COMP:
175
return eval_comp(context, env, expr->arg1);
176
default:
177
_hx509_abort("hx509 eval expr with unknown op: %d", (int)expr->op);
178
UNREACHABLE(return 0);
179
}
180
}
181
182
void
183
_hx509_expr_free(struct hx_expr *expr)
184
{
185
switch (expr->op) {
186
case expr_STRING:
187
case expr_NUMBER:
188
free(expr->arg1);
189
break;
190
case expr_WORDS:
191
case expr_FUNCTION:
192
case expr_VAR:
193
free(expr->arg1);
194
if (expr->arg2)
195
_hx509_expr_free(expr->arg2);
196
break;
197
default:
198
if (expr->arg1)
199
_hx509_expr_free(expr->arg1);
200
if (expr->arg2)
201
_hx509_expr_free(expr->arg2);
202
break;
203
}
204
free(expr);
205
}
206
207
struct hx_expr *
208
_hx509_expr_parse(const char *buf)
209
{
210
_hx509_expr_input.buf = buf;
211
_hx509_expr_input.length = strlen(buf);
212
_hx509_expr_input.offset = 0;
213
_hx509_expr_input.expr = NULL;
214
215
if (_hx509_expr_input.error) {
216
free(_hx509_expr_input.error);
217
_hx509_expr_input.error = NULL;
218
}
219
220
yyparse();
221
222
return _hx509_expr_input.expr;
223
}
224
225
void
226
_hx509_sel_yyerror (const char *s)
227
{
228
if (_hx509_expr_input.error)
229
free(_hx509_expr_input.error);
230
231
_hx509_expr_input.error = strdup(s);
232
}
233
234
235