1 /*
2  * Sample management functions.
3  *
4  * Copyright 2009-2010 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
5  * Copyright (C) 2012 Willy Tarreau <w@1wt.eu>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version
10  * 2 of the License, or (at your option) any later version.
11  *
12  */
13 
14 #include <ctype.h>
15 #include <string.h>
16 #include <arpa/inet.h>
17 #include <stdio.h>
18 
19 #include <import/sha1.h>
20 #include <import/xxhash.h>
21 
22 #include <haproxy/api.h>
23 #include <haproxy/arg.h>
24 #include <haproxy/auth.h>
25 #include <haproxy/base64.h>
26 #include <haproxy/buf.h>
27 #include <haproxy/chunk.h>
28 #include <haproxy/errors.h>
29 #include <haproxy/global.h>
30 #include <haproxy/hash.h>
31 #include <haproxy/http.h>
32 #include <haproxy/net_helper.h>
33 #include <haproxy/protobuf.h>
34 #include <haproxy/proxy.h>
35 #include <haproxy/regex.h>
36 #include <haproxy/sample.h>
37 #include <haproxy/sink.h>
38 #include <haproxy/stick_table.h>
39 #include <haproxy/tools.h>
40 #include <haproxy/uri_auth-t.h>
41 #include <haproxy/vars.h>
42 
43 /* sample type names */
44 const char *smp_to_type[SMP_TYPES] = {
45 	[SMP_T_ANY]  = "any",
46 	[SMP_T_BOOL] = "bool",
47 	[SMP_T_SINT] = "sint",
48 	[SMP_T_ADDR] = "addr",
49 	[SMP_T_IPV4] = "ipv4",
50 	[SMP_T_IPV6] = "ipv6",
51 	[SMP_T_STR]  = "str",
52 	[SMP_T_BIN]  = "bin",
53 	[SMP_T_METH] = "meth",
54 };
55 
56 /* static sample used in sample_process() when <p> is NULL */
57 static THREAD_LOCAL struct sample temp_smp;
58 
59 /* list head of all known sample fetch keywords */
60 static struct sample_fetch_kw_list sample_fetches = {
61 	.list = LIST_HEAD_INIT(sample_fetches.list)
62 };
63 
64 /* list head of all known sample format conversion keywords */
65 static struct sample_conv_kw_list sample_convs = {
66 	.list = LIST_HEAD_INIT(sample_convs.list)
67 };
68 
69 const unsigned int fetch_cap[SMP_SRC_ENTRIES] = {
70 	[SMP_SRC_INTRN] = (SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT |
71 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
72 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
73 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
74 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
75 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
76 	                   SMP_VAL_FE_LOG_END | SMP_VAL_BE_CHK_RUL),
77 
78 	[SMP_SRC_LISTN] = (SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT |
79 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
80 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
81 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
82 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
83 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
84 	                   SMP_VAL_FE_LOG_END | SMP_VAL___________),
85 
86 	[SMP_SRC_FTEND] = (SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT |
87 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
88 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
89 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
90 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
91 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
92 	                   SMP_VAL_FE_LOG_END | SMP_VAL___________),
93 
94 	[SMP_SRC_L4CLI] = (SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT |
95 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
96 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
97 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
98 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
99 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
100 	                   SMP_VAL_FE_LOG_END | SMP_VAL_BE_CHK_RUL),
101 
102 	[SMP_SRC_L5CLI] = (SMP_VAL___________ | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT |
103 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
104 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
105 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
106 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
107 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
108 	                   SMP_VAL_FE_LOG_END | SMP_VAL___________),
109 
110 	[SMP_SRC_TRACK] = (SMP_VAL_FE_CON_ACC | SMP_VAL_FE_SES_ACC | SMP_VAL_FE_REQ_CNT |
111 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
112 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
113 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
114 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
115 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
116 	                   SMP_VAL_FE_LOG_END | SMP_VAL___________),
117 
118 	[SMP_SRC_L6REQ] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_FE_REQ_CNT |
119 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
120 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
121 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL___________ |
122 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
123 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
124 	                   SMP_VAL___________ | SMP_VAL___________),
125 
126 	[SMP_SRC_HRQHV] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_FE_REQ_CNT |
127 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
128 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
129 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL___________ |
130 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
131 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
132 	                   SMP_VAL___________ | SMP_VAL___________),
133 
134 	[SMP_SRC_HRQHP] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_FE_REQ_CNT |
135 	                   SMP_VAL_FE_HRQ_HDR | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
136 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
137 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
138 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
139 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
140 	                   SMP_VAL_FE_LOG_END | SMP_VAL___________),
141 
142 	[SMP_SRC_HRQBO] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
143 	                   SMP_VAL___________ | SMP_VAL_FE_HRQ_BDY | SMP_VAL_FE_SET_BCK |
144 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
145 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL___________ |
146 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
147 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
148 	                   SMP_VAL___________ | SMP_VAL___________),
149 
150 	[SMP_SRC_BKEND] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
151 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
152 	                   SMP_VAL_BE_REQ_CNT | SMP_VAL_BE_HRQ_HDR | SMP_VAL_BE_HRQ_BDY |
153 	                   SMP_VAL_BE_SET_SRV | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
154 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
155 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
156 	                   SMP_VAL_FE_LOG_END | SMP_VAL_BE_CHK_RUL),
157 
158 	[SMP_SRC_SERVR] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
159 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
160 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
161 	                   SMP_VAL___________ | SMP_VAL_BE_SRV_CON | SMP_VAL_BE_RES_CNT |
162 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
163 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
164 	                   SMP_VAL_FE_LOG_END | SMP_VAL_BE_CHK_RUL),
165 
166 	[SMP_SRC_L4SRV] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
167 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
168 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
169 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT |
170 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
171 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
172 	                   SMP_VAL_FE_LOG_END | SMP_VAL_BE_CHK_RUL),
173 
174 	[SMP_SRC_L5SRV] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
175 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
176 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
177 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT |
178 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
179 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
180 	                   SMP_VAL_FE_LOG_END | SMP_VAL_BE_CHK_RUL),
181 
182 	[SMP_SRC_L6RES] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
183 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
184 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
185 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT |
186 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
187 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
188 	                   SMP_VAL___________ | SMP_VAL_BE_CHK_RUL),
189 
190 	[SMP_SRC_HRSHV] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
191 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
192 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
193 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT |
194 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
195 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
196 	                   SMP_VAL___________ | SMP_VAL_BE_CHK_RUL),
197 
198 	[SMP_SRC_HRSHP] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
199 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
200 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
201 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL_BE_RES_CNT |
202 	                   SMP_VAL_BE_HRS_HDR | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
203 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
204 	                   SMP_VAL_FE_LOG_END | SMP_VAL_BE_CHK_RUL),
205 
206 	[SMP_SRC_HRSBO] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
207 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
208 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
209 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
210 	                   SMP_VAL___________ | SMP_VAL_BE_HRS_BDY | SMP_VAL_BE_STO_RUL |
211 	                   SMP_VAL_FE_RES_CNT | SMP_VAL_FE_HRS_HDR | SMP_VAL_FE_HRS_BDY |
212 	                   SMP_VAL___________ | SMP_VAL_BE_CHK_RUL),
213 
214 	[SMP_SRC_RQFIN] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
215 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
216 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
217 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
218 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
219 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
220 	                   SMP_VAL_FE_LOG_END | SMP_VAL___________),
221 
222 	[SMP_SRC_RSFIN] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
223 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
224 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
225 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
226 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
227 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
228 	                   SMP_VAL_FE_LOG_END | SMP_VAL___________),
229 
230 	[SMP_SRC_TXFIN] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
231 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
232 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
233 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
234 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
235 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
236 	                   SMP_VAL_FE_LOG_END | SMP_VAL___________),
237 
238 	[SMP_SRC_SSFIN] = (SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
239 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
240 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
241 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
242 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
243 	                   SMP_VAL___________ | SMP_VAL___________ | SMP_VAL___________ |
244 	                   SMP_VAL_FE_LOG_END | SMP_VAL___________),
245 };
246 
247 static const char *fetch_src_names[SMP_SRC_ENTRIES] = {
248 	[SMP_SRC_INTRN] = "internal state",
249 	[SMP_SRC_LISTN] = "listener",
250 	[SMP_SRC_FTEND] = "frontend",
251 	[SMP_SRC_L4CLI] = "client address",
252 	[SMP_SRC_L5CLI] = "client-side connection",
253 	[SMP_SRC_TRACK] = "track counters",
254 	[SMP_SRC_L6REQ] = "request buffer",
255 	[SMP_SRC_HRQHV] = "HTTP request headers",
256 	[SMP_SRC_HRQHP] = "HTTP request",
257 	[SMP_SRC_HRQBO] = "HTTP request body",
258 	[SMP_SRC_BKEND] = "backend",
259 	[SMP_SRC_SERVR] = "server",
260 	[SMP_SRC_L4SRV] = "server address",
261 	[SMP_SRC_L5SRV] = "server-side connection",
262 	[SMP_SRC_L6RES] = "response buffer",
263 	[SMP_SRC_HRSHV] = "HTTP response headers",
264 	[SMP_SRC_HRSHP] = "HTTP response",
265 	[SMP_SRC_HRSBO] = "HTTP response body",
266 	[SMP_SRC_RQFIN] = "request buffer statistics",
267 	[SMP_SRC_RSFIN] = "response buffer statistics",
268 	[SMP_SRC_TXFIN] = "transaction statistics",
269 	[SMP_SRC_SSFIN] = "session statistics",
270 };
271 
272 static const char *fetch_ckp_names[SMP_CKP_ENTRIES] = {
273 	[SMP_CKP_FE_CON_ACC] = "frontend tcp-request connection rule",
274 	[SMP_CKP_FE_SES_ACC] = "frontend tcp-request session rule",
275 	[SMP_CKP_FE_REQ_CNT] = "frontend tcp-request content rule",
276 	[SMP_CKP_FE_HRQ_HDR] = "frontend http-request header rule",
277 	[SMP_CKP_FE_HRQ_BDY] = "frontend http-request body rule",
278 	[SMP_CKP_FE_SET_BCK] = "frontend use-backend rule",
279 	[SMP_CKP_BE_REQ_CNT] = "backend tcp-request content rule",
280 	[SMP_CKP_BE_HRQ_HDR] = "backend http-request header rule",
281 	[SMP_CKP_BE_HRQ_BDY] = "backend http-request body rule",
282 	[SMP_CKP_BE_SET_SRV] = "backend use-server, balance or stick-match rule",
283 	[SMP_CKP_BE_SRV_CON] = "server source selection",
284 	[SMP_CKP_BE_RES_CNT] = "backend tcp-response content rule",
285 	[SMP_CKP_BE_HRS_HDR] = "backend http-response header rule",
286 	[SMP_CKP_BE_HRS_BDY] = "backend http-response body rule",
287 	[SMP_CKP_BE_STO_RUL] = "backend stick-store rule",
288 	[SMP_CKP_FE_RES_CNT] = "frontend tcp-response content rule",
289 	[SMP_CKP_FE_HRS_HDR] = "frontend http-response header rule",
290 	[SMP_CKP_FE_HRS_BDY] = "frontend http-response body rule",
291 	[SMP_CKP_FE_LOG_END] = "logs",
292 	[SMP_CKP_BE_CHK_RUL] = "backend tcp-check rule",
293 };
294 
295 /* This function returns the type of the data returned by the sample_expr.
296  * It assumes that the <expr> and all of its converters are properly
297  * initialized.
298  */
299 inline
smp_expr_output_type(struct sample_expr * expr)300 int smp_expr_output_type(struct sample_expr *expr)
301 {
302 	struct sample_conv_expr *smp_expr;
303 
304 	if (!LIST_ISEMPTY(&expr->conv_exprs)) {
305 		smp_expr = LIST_PREV(&expr->conv_exprs, struct sample_conv_expr *, list);
306 		return smp_expr->conv->out_type;
307 	}
308 	return expr->fetch->out_type;
309 }
310 
311 
312 /* fill the trash with a comma-delimited list of source names for the <use> bit
313  * field which must be composed of a non-null set of SMP_USE_* flags. The return
314  * value is the pointer to the string in the trash buffer.
315  */
sample_src_names(unsigned int use)316 const char *sample_src_names(unsigned int use)
317 {
318 	int bit;
319 
320 	trash.data = 0;
321 	trash.area[0] = '\0';
322 	for (bit = 0; bit < SMP_SRC_ENTRIES; bit++) {
323 		if (!(use & ~((1 << bit) - 1)))
324 			break; /* no more bits */
325 
326 		if (!(use & (1 << bit)))
327 			continue; /* bit not set */
328 
329 		trash.data += snprintf(trash.area + trash.data,
330 				       trash.size - trash.data, "%s%s",
331 				       (use & ((1 << bit) - 1)) ? "," : "",
332 				       fetch_src_names[bit]);
333 	}
334 	return trash.area;
335 }
336 
337 /* return a pointer to the correct sample checkpoint name, or "unknown" when
338  * the flags are invalid. Only the lowest bit is used, higher bits are ignored
339  * if set.
340  */
sample_ckp_names(unsigned int use)341 const char *sample_ckp_names(unsigned int use)
342 {
343 	int bit;
344 
345 	for (bit = 0; bit < SMP_CKP_ENTRIES; bit++)
346 		if (use & (1 << bit))
347 			return fetch_ckp_names[bit];
348 	return "unknown sample check place, please report this bug";
349 }
350 
351 /*
352  * Registers the sample fetch keyword list <kwl> as a list of valid keywords
353  * for next parsing sessions. The fetch keywords capabilities are also computed
354  * from their ->use field.
355  */
sample_register_fetches(struct sample_fetch_kw_list * kwl)356 void sample_register_fetches(struct sample_fetch_kw_list *kwl)
357 {
358 	struct sample_fetch *sf;
359 	int bit;
360 
361 	for (sf = kwl->kw; sf->kw != NULL; sf++) {
362 		for (bit = 0; bit < SMP_SRC_ENTRIES; bit++)
363 			if (sf->use & (1 << bit))
364 				sf->val |= fetch_cap[bit];
365 	}
366 	LIST_ADDQ(&sample_fetches.list, &kwl->list);
367 }
368 
369 /*
370  * Registers the sample format coverstion keyword list <pckl> as a list of valid keywords for next
371  * parsing sessions.
372  */
sample_register_convs(struct sample_conv_kw_list * pckl)373 void sample_register_convs(struct sample_conv_kw_list *pckl)
374 {
375 	LIST_ADDQ(&sample_convs.list, &pckl->list);
376 }
377 
378 /*
379  * Returns the pointer on sample fetch keyword structure identified by
380  * string of <len> in buffer <kw>.
381  *
382  */
find_sample_fetch(const char * kw,int len)383 struct sample_fetch *find_sample_fetch(const char *kw, int len)
384 {
385 	int index;
386 	struct sample_fetch_kw_list *kwl;
387 
388 	list_for_each_entry(kwl, &sample_fetches.list, list) {
389 		for (index = 0; kwl->kw[index].kw != NULL; index++) {
390 			if (strncmp(kwl->kw[index].kw, kw, len) == 0 &&
391 			    kwl->kw[index].kw[len] == '\0')
392 				return &kwl->kw[index];
393 		}
394 	}
395 	return NULL;
396 }
397 
398 /* This function browses the list of available sample fetches. <current> is
399  * the last used sample fetch. If it is the first call, it must set to NULL.
400  * <idx> is the index of the next sample fetch entry. It is used as private
401  * value. It is useless to initiate it.
402  *
403  * It returns always the new fetch_sample entry, and NULL when the end of
404  * the list is reached.
405  */
sample_fetch_getnext(struct sample_fetch * current,int * idx)406 struct sample_fetch *sample_fetch_getnext(struct sample_fetch *current, int *idx)
407 {
408 	struct sample_fetch_kw_list *kwl;
409 	struct sample_fetch *base;
410 
411 	if (!current) {
412 		/* Get first kwl entry. */
413 		kwl = LIST_NEXT(&sample_fetches.list, struct sample_fetch_kw_list *, list);
414 		(*idx) = 0;
415 	} else {
416 		/* Get kwl corresponding to the curret entry. */
417 		base = current + 1 - (*idx);
418 		kwl = container_of(base, struct sample_fetch_kw_list, kw);
419 	}
420 
421 	while (1) {
422 
423 		/* Check if kwl is the last entry. */
424 		if (&kwl->list == &sample_fetches.list)
425 			return NULL;
426 
427 		/* idx contain the next keyword. If it is available, return it. */
428 		if (kwl->kw[*idx].kw) {
429 			(*idx)++;
430 			return &kwl->kw[(*idx)-1];
431 		}
432 
433 		/* get next entry in the main list, and return NULL if the end is reached. */
434 		kwl = LIST_NEXT(&kwl->list, struct sample_fetch_kw_list *, list);
435 
436 		/* Set index to 0, ans do one other loop. */
437 		(*idx) = 0;
438 	}
439 }
440 
441 /* This function browses the list of available converters. <current> is
442  * the last used converter. If it is the first call, it must set to NULL.
443  * <idx> is the index of the next converter entry. It is used as private
444  * value. It is useless to initiate it.
445  *
446  * It returns always the next sample_conv entry, and NULL when the end of
447  * the list is reached.
448  */
sample_conv_getnext(struct sample_conv * current,int * idx)449 struct sample_conv *sample_conv_getnext(struct sample_conv *current, int *idx)
450 {
451 	struct sample_conv_kw_list *kwl;
452 	struct sample_conv *base;
453 
454 	if (!current) {
455 		/* Get first kwl entry. */
456 		kwl = LIST_NEXT(&sample_convs.list, struct sample_conv_kw_list *, list);
457 		(*idx) = 0;
458 	} else {
459 		/* Get kwl corresponding to the curret entry. */
460 		base = current + 1 - (*idx);
461 		kwl = container_of(base, struct sample_conv_kw_list, kw);
462 	}
463 
464 	while (1) {
465 		/* Check if kwl is the last entry. */
466 		if (&kwl->list == &sample_convs.list)
467 			return NULL;
468 
469 		/* idx contain the next keyword. If it is available, return it. */
470 		if (kwl->kw[*idx].kw) {
471 			(*idx)++;
472 			return &kwl->kw[(*idx)-1];
473 		}
474 
475 		/* get next entry in the main list, and return NULL if the end is reached. */
476 		kwl = LIST_NEXT(&kwl->list, struct sample_conv_kw_list *, list);
477 
478 		/* Set index to 0, ans do one other loop. */
479 		(*idx) = 0;
480 	}
481 }
482 
483 /*
484  * Returns the pointer on sample format conversion keyword structure identified by
485  * string of <len> in buffer <kw>.
486  *
487  */
find_sample_conv(const char * kw,int len)488 struct sample_conv *find_sample_conv(const char *kw, int len)
489 {
490 	int index;
491 	struct sample_conv_kw_list *kwl;
492 
493 	list_for_each_entry(kwl, &sample_convs.list, list) {
494 		for (index = 0; kwl->kw[index].kw != NULL; index++) {
495 			if (strncmp(kwl->kw[index].kw, kw, len) == 0 &&
496 			    kwl->kw[index].kw[len] == '\0')
497 				return &kwl->kw[index];
498 		}
499 	}
500 	return NULL;
501 }
502 
503 /******************************************************************/
504 /*          Sample casts functions                                */
505 /******************************************************************/
506 
c_ip2int(struct sample * smp)507 static int c_ip2int(struct sample *smp)
508 {
509 	smp->data.u.sint = ntohl(smp->data.u.ipv4.s_addr);
510 	smp->data.type = SMP_T_SINT;
511 	return 1;
512 }
513 
c_ip2str(struct sample * smp)514 static int c_ip2str(struct sample *smp)
515 {
516 	struct buffer *trash = get_trash_chunk();
517 
518 	if (!inet_ntop(AF_INET, (void *)&smp->data.u.ipv4, trash->area, trash->size))
519 		return 0;
520 
521 	trash->data = strlen(trash->area);
522 	smp->data.u.str = *trash;
523 	smp->data.type = SMP_T_STR;
524 	smp->flags &= ~SMP_F_CONST;
525 
526 	return 1;
527 }
528 
c_ip2ipv6(struct sample * smp)529 static int c_ip2ipv6(struct sample *smp)
530 {
531 	v4tov6(&smp->data.u.ipv6, &smp->data.u.ipv4);
532 	smp->data.type = SMP_T_IPV6;
533 	return 1;
534 }
535 
c_ipv62ip(struct sample * smp)536 static int c_ipv62ip(struct sample *smp)
537 {
538 	if (!v6tov4(&smp->data.u.ipv4, &smp->data.u.ipv6))
539 		return 0;
540 	smp->data.type = SMP_T_IPV4;
541 	return 1;
542 }
543 
c_ipv62str(struct sample * smp)544 static int c_ipv62str(struct sample *smp)
545 {
546 	struct buffer *trash = get_trash_chunk();
547 
548 	if (!inet_ntop(AF_INET6, (void *)&smp->data.u.ipv6, trash->area, trash->size))
549 		return 0;
550 
551 	trash->data = strlen(trash->area);
552 	smp->data.u.str = *trash;
553 	smp->data.type = SMP_T_STR;
554 	smp->flags &= ~SMP_F_CONST;
555 	return 1;
556 }
557 
558 /*
559 static int c_ipv62ip(struct sample *smp)
560 {
561 	return v6tov4(&smp->data.u.ipv4, &smp->data.u.ipv6);
562 }
563 */
564 
c_int2ip(struct sample * smp)565 static int c_int2ip(struct sample *smp)
566 {
567 	smp->data.u.ipv4.s_addr = htonl((unsigned int)smp->data.u.sint);
568 	smp->data.type = SMP_T_IPV4;
569 	return 1;
570 }
571 
c_int2ipv6(struct sample * smp)572 static int c_int2ipv6(struct sample *smp)
573 {
574 	smp->data.u.ipv4.s_addr = htonl((unsigned int)smp->data.u.sint);
575 	v4tov6(&smp->data.u.ipv6, &smp->data.u.ipv4);
576 	smp->data.type = SMP_T_IPV6;
577 	return 1;
578 }
579 
c_str2addr(struct sample * smp)580 static int c_str2addr(struct sample *smp)
581 {
582 	if (!buf2ip(smp->data.u.str.area, smp->data.u.str.data, &smp->data.u.ipv4)) {
583 		if (!buf2ip6(smp->data.u.str.area, smp->data.u.str.data, &smp->data.u.ipv6))
584 			return 0;
585 		smp->data.type = SMP_T_IPV6;
586 		smp->flags &= ~SMP_F_CONST;
587 		return 1;
588 	}
589 	smp->data.type = SMP_T_IPV4;
590 	smp->flags &= ~SMP_F_CONST;
591 	return 1;
592 }
593 
c_str2ip(struct sample * smp)594 static int c_str2ip(struct sample *smp)
595 {
596 	if (!buf2ip(smp->data.u.str.area, smp->data.u.str.data, &smp->data.u.ipv4))
597 		return 0;
598 	smp->data.type = SMP_T_IPV4;
599 	smp->flags &= ~SMP_F_CONST;
600 	return 1;
601 }
602 
c_str2ipv6(struct sample * smp)603 static int c_str2ipv6(struct sample *smp)
604 {
605 	if (!buf2ip6(smp->data.u.str.area, smp->data.u.str.data, &smp->data.u.ipv6))
606 		return 0;
607 	smp->data.type = SMP_T_IPV6;
608 	smp->flags &= ~SMP_F_CONST;
609 	return 1;
610 }
611 
612 /*
613  * The NULL char always enforces the end of string if it is met.
614  * Data is never changed, so we can ignore the CONST case
615  */
c_bin2str(struct sample * smp)616 static int c_bin2str(struct sample *smp)
617 {
618 	int i;
619 
620 	for (i = 0; i < smp->data.u.str.data; i++) {
621 		if (!smp->data.u.str.area[i]) {
622 			smp->data.u.str.data = i;
623 			break;
624 		}
625 	}
626 	smp->data.type = SMP_T_STR;
627 	return 1;
628 }
629 
c_int2str(struct sample * smp)630 static int c_int2str(struct sample *smp)
631 {
632 	struct buffer *trash = get_trash_chunk();
633 	char *pos;
634 
635 	pos = lltoa_r(smp->data.u.sint, trash->area, trash->size);
636 	if (!pos)
637 		return 0;
638 
639 	trash->size = trash->size - (pos - trash->area);
640 	trash->area = pos;
641 	trash->data = strlen(pos);
642 	smp->data.u.str = *trash;
643 	smp->data.type = SMP_T_STR;
644 	smp->flags &= ~SMP_F_CONST;
645 	return 1;
646 }
647 
648 /* This function unconditionally duplicates data and removes the "const" flag.
649  * For strings and binary blocks, it also provides a known allocated size with
650  * a length that is capped to the size, and ensures a trailing zero is always
651  * appended for strings. This is necessary for some operations which may
652  * require to extend the length. It returns 0 if it fails, 1 on success.
653  */
smp_dup(struct sample * smp)654 int smp_dup(struct sample *smp)
655 {
656 	struct buffer *trash;
657 
658 	switch (smp->data.type) {
659 	case SMP_T_BOOL:
660 	case SMP_T_SINT:
661 	case SMP_T_ADDR:
662 	case SMP_T_IPV4:
663 	case SMP_T_IPV6:
664 		/* These type are not const. */
665 		break;
666 
667 	case SMP_T_METH:
668 		if (smp->data.u.meth.meth != HTTP_METH_OTHER)
669 			break;
670 		/* Fall through */
671 
672 	case SMP_T_STR:
673 		trash = get_trash_chunk();
674 		trash->data = smp->data.type == SMP_T_STR ?
675 		    smp->data.u.str.data : smp->data.u.meth.str.data;
676 		if (trash->data > trash->size - 1)
677 			trash->data = trash->size - 1;
678 
679 		memcpy(trash->area, smp->data.type == SMP_T_STR ?
680 		    smp->data.u.str.area : smp->data.u.meth.str.area,
681 		    trash->data);
682 		trash->area[trash->data] = 0;
683 		smp->data.u.str = *trash;
684 		break;
685 
686 	case SMP_T_BIN:
687 		trash = get_trash_chunk();
688 		trash->data = smp->data.u.str.data;
689 		if (trash->data > trash->size)
690 			trash->data = trash->size;
691 
692 		memcpy(trash->area, smp->data.u.str.area, trash->data);
693 		smp->data.u.str = *trash;
694 		break;
695 
696 	default:
697 		/* Other cases are unexpected. */
698 		return 0;
699 	}
700 
701 	/* remove const flag */
702 	smp->flags &= ~SMP_F_CONST;
703 	return 1;
704 }
705 
c_none(struct sample * smp)706 int c_none(struct sample *smp)
707 {
708 	return 1;
709 }
710 
c_str2int(struct sample * smp)711 static int c_str2int(struct sample *smp)
712 {
713 	const char *str;
714 	const char *end;
715 
716 	if (smp->data.u.str.data == 0)
717 		return 0;
718 
719 	str = smp->data.u.str.area;
720 	end = smp->data.u.str.area + smp->data.u.str.data;
721 
722 	smp->data.u.sint = read_int64(&str, end);
723 	smp->data.type = SMP_T_SINT;
724 	smp->flags &= ~SMP_F_CONST;
725 	return 1;
726 }
727 
c_str2meth(struct sample * smp)728 static int c_str2meth(struct sample *smp)
729 {
730 	enum http_meth_t meth;
731 	int len;
732 
733 	meth = find_http_meth(smp->data.u.str.area, smp->data.u.str.data);
734 	if (meth == HTTP_METH_OTHER) {
735 		len = smp->data.u.str.data;
736 		smp->data.u.meth.str.area = smp->data.u.str.area;
737 		smp->data.u.meth.str.data = len;
738 	}
739 	else
740 		smp->flags &= ~SMP_F_CONST;
741 	smp->data.u.meth.meth = meth;
742 	smp->data.type = SMP_T_METH;
743 	return 1;
744 }
745 
c_meth2str(struct sample * smp)746 static int c_meth2str(struct sample *smp)
747 {
748 	int len;
749 	enum http_meth_t meth;
750 
751 	if (smp->data.u.meth.meth == HTTP_METH_OTHER) {
752 		/* The method is unknown. Copy the original pointer. */
753 		len = smp->data.u.meth.str.data;
754 		smp->data.u.str.area = smp->data.u.meth.str.area;
755 		smp->data.u.str.data = len;
756 		smp->data.type = SMP_T_STR;
757 	}
758 	else if (smp->data.u.meth.meth < HTTP_METH_OTHER) {
759 		/* The method is known, copy the pointer containing the string. */
760 		meth = smp->data.u.meth.meth;
761 		smp->data.u.str.area = http_known_methods[meth].ptr;
762 		smp->data.u.str.data = http_known_methods[meth].len;
763 		smp->flags |= SMP_F_CONST;
764 		smp->data.type = SMP_T_STR;
765 	}
766 	else {
767 		/* Unknown method */
768 		return 0;
769 	}
770 	return 1;
771 }
772 
c_addr2bin(struct sample * smp)773 static int c_addr2bin(struct sample *smp)
774 {
775 	struct buffer *chk = get_trash_chunk();
776 
777 	if (smp->data.type == SMP_T_IPV4) {
778 		chk->data = 4;
779 		memcpy(chk->area, &smp->data.u.ipv4, chk->data);
780 	}
781 	else if (smp->data.type == SMP_T_IPV6) {
782 		chk->data = 16;
783 		memcpy(chk->area, &smp->data.u.ipv6, chk->data);
784 	}
785 	else
786 		return 0;
787 
788 	smp->data.u.str = *chk;
789 	smp->data.type = SMP_T_BIN;
790 	return 1;
791 }
792 
c_int2bin(struct sample * smp)793 static int c_int2bin(struct sample *smp)
794 {
795 	struct buffer *chk = get_trash_chunk();
796 
797 	*(unsigned long long int *) chk->area = my_htonll(smp->data.u.sint);
798 	chk->data = 8;
799 
800 	smp->data.u.str = *chk;
801 	smp->data.type = SMP_T_BIN;
802 	return 1;
803 }
804 
805 
806 /*****************************************************************/
807 /*      Sample casts matrix:                                     */
808 /*           sample_casts[from type][to type]                    */
809 /*           NULL pointer used for impossible sample casts       */
810 /*****************************************************************/
811 
812 sample_cast_fct sample_casts[SMP_TYPES][SMP_TYPES] = {
813 /*            to:  ANY     BOOL       SINT       ADDR        IPV4      IPV6        STR         BIN         METH */
814 /* from:  ANY */ { c_none, c_none,    c_none,    c_none,     c_none,   c_none,     c_none,     c_none,     c_none,     },
815 /*       BOOL */ { c_none, c_none,    c_none,    NULL,       NULL,     NULL,       c_int2str,  NULL,       NULL,       },
816 /*       SINT */ { c_none, c_none,    c_none,    c_int2ip,   c_int2ip, c_int2ipv6, c_int2str,  c_int2bin,  NULL,       },
817 /*       ADDR */ { c_none, NULL,      NULL,      NULL,       NULL,     NULL,       NULL,       NULL,       NULL,       },
818 /*       IPV4 */ { c_none, NULL,      c_ip2int,  c_none,     c_none,   c_ip2ipv6,  c_ip2str,   c_addr2bin, NULL,       },
819 /*       IPV6 */ { c_none, NULL,      NULL,      c_none,     c_ipv62ip,c_none,     c_ipv62str, c_addr2bin, NULL,       },
820 /*        STR */ { c_none, c_str2int, c_str2int, c_str2addr, c_str2ip, c_str2ipv6, c_none,     c_none,     c_str2meth, },
821 /*        BIN */ { c_none, NULL,      NULL,      NULL,       NULL,     NULL,       c_bin2str,  c_none,     c_str2meth, },
822 /*       METH */ { c_none, NULL,      NULL,      NULL,       NULL,     NULL,       c_meth2str, c_meth2str, c_none,     }
823 };
824 
825 /*
826  * Parse a sample expression configuration:
827  *        fetch keyword followed by format conversion keywords.
828  * Returns a pointer on allocated sample expression structure.
829  * <al> is an arg_list serving as a list head to report missing dependencies.
830  * It may be NULL if such dependencies are not allowed. Otherwise, the caller
831  * must have set al->ctx if al is set.
832  * If <endptr> is non-nul, it will be set to the first unparsed character
833  * (which may be the final '\0') on success. If it is nul, the expression
834  * must be properly terminated by a '\0' otherwise an error is reported.
835  */
sample_parse_expr(char ** str,int * idx,const char * file,int line,char ** err_msg,struct arg_list * al,char ** endptr)836 struct sample_expr *sample_parse_expr(char **str, int *idx, const char *file, int line, char **err_msg, struct arg_list *al, char **endptr)
837 {
838 	const char *begw; /* beginning of word */
839 	const char *endw; /* end of word */
840 	const char *endt; /* end of term */
841 	struct sample_expr *expr = NULL;
842 	struct sample_fetch *fetch;
843 	struct sample_conv *conv;
844 	unsigned long prev_type;
845 	char *fkw = NULL;
846 	char *ckw = NULL;
847 	int err_arg;
848 
849 	begw = str[*idx];
850 	for (endw = begw; is_idchar(*endw); endw++)
851 		;
852 
853 	if (endw == begw) {
854 		memprintf(err_msg, "missing fetch method");
855 		goto out_error;
856 	}
857 
858 	/* keep a copy of the current fetch keyword for error reporting */
859 	fkw = my_strndup(begw, endw - begw);
860 
861 	fetch = find_sample_fetch(begw, endw - begw);
862 	if (!fetch) {
863 		memprintf(err_msg, "unknown fetch method '%s'", fkw);
864 		goto out_error;
865 	}
866 
867 	/* At this point, we have :
868 	 *   - begw : beginning of the keyword
869 	 *   - endw : end of the keyword, first character not part of keyword
870 	 */
871 
872 	if (fetch->out_type >= SMP_TYPES) {
873 		memprintf(err_msg, "returns type of fetch method '%s' is unknown", fkw);
874 		goto out_error;
875 	}
876 	prev_type = fetch->out_type;
877 
878 	expr = calloc(1, sizeof(*expr));
879 	if (!expr)
880 		goto out_error;
881 
882 	LIST_INIT(&(expr->conv_exprs));
883 	expr->fetch = fetch;
884 	expr->arg_p = empty_arg_list;
885 
886 	/* Note that we call the argument parser even with an empty string,
887 	 * this allows it to automatically create entries for mandatory
888 	 * implicit arguments (eg: local proxy name).
889 	 */
890 	if (al) {
891 		al->kw = expr->fetch->kw;
892 		al->conv = NULL;
893 	}
894 	if (make_arg_list(endw, -1, fetch->arg_mask, &expr->arg_p, err_msg, &endt, &err_arg, al) < 0) {
895 		memprintf(err_msg, "fetch method '%s' : %s", fkw, *err_msg);
896 		goto out_error;
897 	}
898 
899 	/* now endt is our first char not part of the arg list, typically the
900 	 * comma after the sample fetch name or after the closing parenthesis,
901 	 * or the NUL char.
902 	 */
903 
904 	if (!expr->arg_p) {
905 		expr->arg_p = empty_arg_list;
906 	}
907 	else if (fetch->val_args && !fetch->val_args(expr->arg_p, err_msg)) {
908 		memprintf(err_msg, "invalid args in fetch method '%s' : %s", fkw, *err_msg);
909 		goto out_error;
910 	}
911 
912 	/* Now process the converters if any. We have two supported syntaxes
913 	 * for the converters, which can be combined :
914 	 *  - comma-delimited list of converters just after the keyword and args ;
915 	 *  - one converter per keyword
916 	 * The combination allows to have each keyword being a comma-delimited
917 	 * series of converters.
918 	 *
919 	 * We want to process the former first, then the latter. For this we start
920 	 * from the beginning of the supposed place in the exiting conv chain, which
921 	 * starts at the last comma (endt).
922 	 */
923 
924 	while (1) {
925 		struct sample_conv_expr *conv_expr;
926 		int err_arg;
927 		int argcnt;
928 
929 		if (*endt && *endt != ',') {
930 			if (endptr) {
931 				/* end found, let's stop here */
932 				break;
933 			}
934 			if (ckw)
935 				memprintf(err_msg, "missing comma after converter '%s'", ckw);
936 			else
937 				memprintf(err_msg, "missing comma after fetch keyword '%s'", fkw);
938 			goto out_error;
939 		}
940 
941 		/* FIXME: how long should we support such idiocies ? Maybe we
942 		 * should already warn ?
943 		 */
944 		while (*endt == ',') /* then trailing commas */
945 			endt++;
946 
947 		begw = endt; /* start of converter */
948 
949 		if (!*begw) {
950 			/* none ? skip to next string */
951 			(*idx)++;
952 			begw = str[*idx];
953 			if (!begw || !*begw)
954 				break;
955 		}
956 
957 		for (endw = begw; is_idchar(*endw); endw++)
958 			;
959 
960 		free(ckw);
961 		ckw = my_strndup(begw, endw - begw);
962 
963 		conv = find_sample_conv(begw, endw - begw);
964 		if (!conv) {
965 			/* we found an isolated keyword that we don't know, it's not ours */
966 			if (begw == str[*idx]) {
967 				endt = begw;
968 				break;
969 			}
970 			memprintf(err_msg, "unknown converter '%s'", ckw);
971 			goto out_error;
972 		}
973 
974 		if (conv->in_type >= SMP_TYPES || conv->out_type >= SMP_TYPES) {
975 			memprintf(err_msg, "returns type of converter '%s' is unknown", ckw);
976 			goto out_error;
977 		}
978 
979 		/* If impossible type conversion */
980 		if (!sample_casts[prev_type][conv->in_type]) {
981 			memprintf(err_msg, "converter '%s' cannot be applied", ckw);
982 			goto out_error;
983 		}
984 
985 		prev_type = conv->out_type;
986 		conv_expr = calloc(1, sizeof(*conv_expr));
987 		if (!conv_expr)
988 			goto out_error;
989 
990 		LIST_ADDQ(&(expr->conv_exprs), &(conv_expr->list));
991 		conv_expr->conv = conv;
992 
993 		if (al) {
994 			al->kw = expr->fetch->kw;
995 			al->conv = conv_expr->conv->kw;
996 		}
997 		argcnt = make_arg_list(endw, -1, conv->arg_mask, &conv_expr->arg_p, err_msg, &endt, &err_arg, al);
998 		if (argcnt < 0) {
999 			memprintf(err_msg, "invalid arg %d in converter '%s' : %s", err_arg+1, ckw, *err_msg);
1000 			goto out_error;
1001 		}
1002 
1003 		if (argcnt && !conv->arg_mask) {
1004 			memprintf(err_msg, "converter '%s' does not support any args", ckw);
1005 			goto out_error;
1006 		}
1007 
1008 		if (!conv_expr->arg_p)
1009 			conv_expr->arg_p = empty_arg_list;
1010 
1011 		if (conv->val_args && !conv->val_args(conv_expr->arg_p, conv, file, line, err_msg)) {
1012 			memprintf(err_msg, "invalid args in converter '%s' : %s", ckw, *err_msg);
1013 			goto out_error;
1014 		}
1015 	}
1016 
1017 	if (endptr) {
1018 		/* end found, let's stop here */
1019 		*endptr = (char *)endt;
1020 	}
1021 
1022  out:
1023 	free(fkw);
1024 	free(ckw);
1025 	return expr;
1026 
1027 out_error:
1028 	release_sample_expr(expr);
1029 	expr = NULL;
1030 	goto out;
1031 }
1032 
1033 /*
1034  * Process a fetch + format conversion of defined by the sample expression <expr>
1035  * on request or response considering the <opt> parameter.
1036  * Returns a pointer on a typed sample structure containing the result or NULL if
1037  * sample is not found or when format conversion failed.
1038  *  If <p> is not null, function returns results in structure pointed by <p>.
1039  *  If <p> is null, functions returns a pointer on a static sample structure.
1040  *
1041  * Note: the fetch functions are required to properly set the return type. The
1042  * conversion functions must do so too. However the cast functions do not need
1043  * to since they're made to cast multiple types according to what is required.
1044  *
1045  * The caller may indicate in <opt> if it considers the result final or not.
1046  * The caller needs to check the SMP_F_MAY_CHANGE flag in p->flags to verify
1047  * if the result is stable or not, according to the following table :
1048  *
1049  * return MAY_CHANGE FINAL   Meaning for the sample
1050  *  NULL      0        *     Not present and will never be (eg: header)
1051  *  NULL      1        0     Not present yet, could change (eg: POST param)
1052  *  NULL      1        1     Not present yet, will not change anymore
1053  *   smp      0        *     Present and will not change (eg: header)
1054  *   smp      1        0     Present, may change (eg: request length)
1055  *   smp      1        1     Present, last known value (eg: request length)
1056  */
sample_process(struct proxy * px,struct session * sess,struct stream * strm,unsigned int opt,struct sample_expr * expr,struct sample * p)1057 struct sample *sample_process(struct proxy *px, struct session *sess,
1058                               struct stream *strm, unsigned int opt,
1059                               struct sample_expr *expr, struct sample *p)
1060 {
1061 	struct sample_conv_expr *conv_expr;
1062 
1063 	if (p == NULL) {
1064 		p = &temp_smp;
1065 		memset(p, 0, sizeof(*p));
1066 	}
1067 
1068 	smp_set_owner(p, px, sess, strm, opt);
1069 	if (!expr->fetch->process(expr->arg_p, p, expr->fetch->kw, expr->fetch->private))
1070 		return NULL;
1071 
1072 	list_for_each_entry(conv_expr, &expr->conv_exprs, list) {
1073 		/* we want to ensure that p->type can be casted into
1074 		 * conv_expr->conv->in_type. We have 3 possibilities :
1075 		 *  - NULL   => not castable.
1076 		 *  - c_none => nothing to do (let's optimize it)
1077 		 *  - other  => apply cast and prepare to fail
1078 		 */
1079 		if (!sample_casts[p->data.type][conv_expr->conv->in_type])
1080 			return NULL;
1081 
1082 		if (sample_casts[p->data.type][conv_expr->conv->in_type] != c_none &&
1083 		    !sample_casts[p->data.type][conv_expr->conv->in_type](p))
1084 			return NULL;
1085 
1086 		/* OK cast succeeded */
1087 
1088 		if (!conv_expr->conv->process(conv_expr->arg_p, p, conv_expr->conv->private))
1089 			return NULL;
1090 	}
1091 	return p;
1092 }
1093 
1094 /*
1095  * Resolve all remaining arguments in proxy <p>. Returns the number of
1096  * errors or 0 if everything is fine.
1097  */
smp_resolve_args(struct proxy * p)1098 int smp_resolve_args(struct proxy *p)
1099 {
1100 	struct arg_list *cur, *bak;
1101 	const char *ctx, *where;
1102 	const char *conv_ctx, *conv_pre, *conv_pos;
1103 	struct userlist *ul;
1104 	struct my_regex *reg;
1105 	struct arg *arg;
1106 	int cfgerr = 0;
1107 	int rflags;
1108 
1109 	list_for_each_entry_safe(cur, bak, &p->conf.args.list, list) {
1110 		struct proxy *px;
1111 		struct server *srv;
1112 		struct stktable *t;
1113 		char *pname, *sname, *stktname;
1114 		char *err;
1115 
1116 		arg = cur->arg;
1117 
1118 		/* prepare output messages */
1119 		conv_pre = conv_pos = conv_ctx = "";
1120 		if (cur->conv) {
1121 			conv_ctx = cur->conv;
1122 			conv_pre = "conversion keyword '";
1123 			conv_pos = "' for ";
1124 		}
1125 
1126 		where = "in";
1127 		ctx = "sample fetch keyword";
1128 		switch (cur->ctx) {
1129 		case ARGC_STK:   where = "in stick rule in"; break;
1130 		case ARGC_TRK:   where = "in tracking rule in"; break;
1131 		case ARGC_LOG:   where = "in log-format string in"; break;
1132 		case ARGC_LOGSD: where = "in log-format-sd string in"; break;
1133 		case ARGC_HRQ:   where = "in http-request expression in"; break;
1134 		case ARGC_HRS:   where = "in http-response response in"; break;
1135 		case ARGC_UIF:   where = "in unique-id-format string in"; break;
1136 		case ARGC_RDR:   where = "in redirect format string in"; break;
1137 		case ARGC_CAP:   where = "in capture rule in"; break;
1138 		case ARGC_ACL:   ctx = "ACL keyword"; break;
1139 		case ARGC_SRV:   where = "in server directive in"; break;
1140 		case ARGC_SPOE:  where = "in spoe-message directive in"; break;
1141 		case ARGC_HERR:  where = "in http-error directive in"; break;
1142 		case ARGC_TCO:   where = "in tcp-request connection expression in"; break;
1143 		case ARGC_TSE:   where = "in tcp-request session expression in"; break;
1144 		case ARGC_TRQ:   where = "in tcp-request content expression in"; break;
1145 		case ARGC_TRS:   where = "in tcp-response content expression in"; break;
1146 		case ARGC_TCK:   where = "in tcp-check expression in"; break;
1147 		}
1148 
1149 		/* set a few default settings */
1150 		px = p;
1151 		pname = p->id;
1152 
1153 		switch (arg->type) {
1154 		case ARGT_SRV:
1155 			if (!arg->data.str.data) {
1156 				ha_alert("parsing [%s:%d] : missing server name in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1157 					 cur->file, cur->line,
1158 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1159 				cfgerr++;
1160 				continue;
1161 			}
1162 
1163 			/* we support two formats : "bck/srv" and "srv" */
1164 			sname = strrchr(arg->data.str.area, '/');
1165 
1166 			if (sname) {
1167 				*sname++ = '\0';
1168 				pname = arg->data.str.area;
1169 
1170 				px = proxy_be_by_name(pname);
1171 				if (!px) {
1172 					ha_alert("parsing [%s:%d] : unable to find proxy '%s' referenced in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1173 						 cur->file, cur->line, pname,
1174 						 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1175 					cfgerr++;
1176 					break;
1177 				}
1178 			}
1179 			else
1180 				sname = arg->data.str.area;
1181 
1182 			srv = findserver(px, sname);
1183 			if (!srv) {
1184 				ha_alert("parsing [%s:%d] : unable to find server '%s' in proxy '%s', referenced in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1185 					 cur->file, cur->line, sname, pname,
1186 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1187 				cfgerr++;
1188 				break;
1189 			}
1190 
1191 			chunk_destroy(&arg->data.str);
1192 			arg->unresolved = 0;
1193 			arg->data.srv = srv;
1194 			break;
1195 
1196 		case ARGT_FE:
1197 			if (arg->data.str.data) {
1198 				pname = arg->data.str.area;
1199 				px = proxy_fe_by_name(pname);
1200 			}
1201 
1202 			if (!px) {
1203 				ha_alert("parsing [%s:%d] : unable to find frontend '%s' referenced in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1204 					 cur->file, cur->line, pname,
1205 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1206 				cfgerr++;
1207 				break;
1208 			}
1209 
1210 			if (!(px->cap & PR_CAP_FE)) {
1211 				ha_alert("parsing [%s:%d] : proxy '%s', referenced in arg %d of %s%s%s%s '%s' %s proxy '%s', has not frontend capability.\n",
1212 					 cur->file, cur->line, pname,
1213 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1214 				cfgerr++;
1215 				break;
1216 			}
1217 
1218 			chunk_destroy(&arg->data.str);
1219 			arg->unresolved = 0;
1220 			arg->data.prx = px;
1221 			break;
1222 
1223 		case ARGT_BE:
1224 			if (arg->data.str.data) {
1225 				pname = arg->data.str.area;
1226 				px = proxy_be_by_name(pname);
1227 			}
1228 
1229 			if (!px) {
1230 				ha_alert("parsing [%s:%d] : unable to find backend '%s' referenced in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1231 					 cur->file, cur->line, pname,
1232 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1233 				cfgerr++;
1234 				break;
1235 			}
1236 
1237 			if (!(px->cap & PR_CAP_BE)) {
1238 				ha_alert("parsing [%s:%d] : proxy '%s', referenced in arg %d of %s%s%s%s '%s' %s proxy '%s', has not backend capability.\n",
1239 					 cur->file, cur->line, pname,
1240 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1241 				cfgerr++;
1242 				break;
1243 			}
1244 
1245 			chunk_destroy(&arg->data.str);
1246 			arg->unresolved = 0;
1247 			arg->data.prx = px;
1248 			break;
1249 
1250 		case ARGT_TAB:
1251 			if (arg->data.str.data)
1252 				stktname = arg->data.str.area;
1253 			else
1254 				stktname = px->id;
1255 
1256 			t = stktable_find_by_name(stktname);
1257 			if (!t) {
1258 				ha_alert("parsing [%s:%d] : unable to find table '%s' referenced in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1259 					 cur->file, cur->line, stktname,
1260 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1261 				cfgerr++;
1262 				break;
1263 			}
1264 
1265 			if (!t->size) {
1266 				ha_alert("parsing [%s:%d] : no table in proxy '%s' referenced in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1267 					 cur->file, cur->line, stktname,
1268 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1269 				cfgerr++;
1270 				break;
1271 			}
1272 
1273 			if (t->proxy && (p->bind_proc & ~t->proxy->bind_proc)) {
1274 				ha_alert("parsing [%s:%d] : stick-table '%s' not present on all processes covered by proxy '%s'.\n",
1275 					 cur->file, cur->line, t->proxy->id, p->id);
1276 				cfgerr++;
1277 				break;
1278 			}
1279 
1280 			if (!in_proxies_list(t->proxies_list, p)) {
1281 				p->next_stkt_ref = t->proxies_list;
1282 				t->proxies_list = p;
1283 			}
1284 
1285 			chunk_destroy(&arg->data.str);
1286 			arg->unresolved = 0;
1287 			arg->data.t = t;
1288 			break;
1289 
1290 		case ARGT_USR:
1291 			if (!arg->data.str.data) {
1292 				ha_alert("parsing [%s:%d] : missing userlist name in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1293 					 cur->file, cur->line,
1294 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1295 				cfgerr++;
1296 				break;
1297 			}
1298 
1299 			if (p->uri_auth && p->uri_auth->userlist &&
1300 			    !strcmp(p->uri_auth->userlist->name, arg->data.str.area))
1301 				ul = p->uri_auth->userlist;
1302 			else
1303 				ul = auth_find_userlist(arg->data.str.area);
1304 
1305 			if (!ul) {
1306 				ha_alert("parsing [%s:%d] : unable to find userlist '%s' referenced in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1307 					 cur->file, cur->line,
1308 					 arg->data.str.area,
1309 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1310 				cfgerr++;
1311 				break;
1312 			}
1313 
1314 			chunk_destroy(&arg->data.str);
1315 			arg->unresolved = 0;
1316 			arg->data.usr = ul;
1317 			break;
1318 
1319 		case ARGT_REG:
1320 			if (!arg->data.str.data) {
1321 				ha_alert("parsing [%s:%d] : missing regex in arg %d of %s%s%s%s '%s' %s proxy '%s'.\n",
1322 					 cur->file, cur->line,
1323 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id);
1324 				cfgerr++;
1325 				continue;
1326 			}
1327 
1328 			rflags = 0;
1329 			rflags |= (arg->type_flags & ARGF_REG_ICASE) ? REG_ICASE : 0;
1330 			err = NULL;
1331 
1332 			if (!(reg = regex_comp(arg->data.str.area, !(rflags & REG_ICASE), 1 /* capture substr */, &err))) {
1333 				ha_alert("parsing [%s:%d] : error in regex '%s' in arg %d of %s%s%s%s '%s' %s proxy '%s' : %s.\n",
1334 					 cur->file, cur->line,
1335 					 arg->data.str.area,
1336 					 cur->arg_pos + 1, conv_pre, conv_ctx, conv_pos, ctx, cur->kw, where, p->id, err);
1337 				cfgerr++;
1338 				continue;
1339 			}
1340 
1341 			chunk_destroy(&arg->data.str);
1342 			arg->unresolved = 0;
1343 			arg->data.reg = reg;
1344 			break;
1345 
1346 
1347 		}
1348 
1349 		LIST_DEL(&cur->list);
1350 		free(cur);
1351 	} /* end of args processing */
1352 
1353 	return cfgerr;
1354 }
1355 
1356 /*
1357  * Process a fetch + format conversion as defined by the sample expression
1358  * <expr> on request or response considering the <opt> parameter. The output is
1359  * not explicitly set to <smp_type>, but shall be compatible with it as
1360  * specified by 'sample_casts' table. If a stable sample can be fetched, or an
1361  * unstable one when <opt> contains SMP_OPT_FINAL, the sample is converted and
1362  * returned without the SMP_F_MAY_CHANGE flag. If an unstable sample is found
1363  * and <opt> does not contain SMP_OPT_FINAL, then the sample is returned as-is
1364  * with its SMP_F_MAY_CHANGE flag so that the caller can check it and decide to
1365  * take actions (eg: wait longer). If a sample could not be found or could not
1366  * be converted, NULL is returned. The caller MUST NOT use the sample if the
1367  * SMP_F_MAY_CHANGE flag is present, as it is used only as a hint that there is
1368  * still hope to get it after waiting longer, and is not converted to string.
1369  * The possible output combinations are the following :
1370  *
1371  * return MAY_CHANGE FINAL   Meaning for the sample
1372  *  NULL      *        *     Not present and will never be (eg: header)
1373  *   smp      0        *     Final value converted (eg: header)
1374  *   smp      1        0     Not present yet, may appear later (eg: header)
1375  *   smp      1        1     never happens (either flag is cleared on output)
1376  */
sample_fetch_as_type(struct proxy * px,struct session * sess,struct stream * strm,unsigned int opt,struct sample_expr * expr,int smp_type)1377 struct sample *sample_fetch_as_type(struct proxy *px, struct session *sess,
1378                                    struct stream *strm, unsigned int opt,
1379                                    struct sample_expr *expr, int smp_type)
1380 {
1381 	struct sample *smp = &temp_smp;
1382 
1383 	memset(smp, 0, sizeof(*smp));
1384 
1385 	if (!sample_process(px, sess, strm, opt, expr, smp)) {
1386 		if ((smp->flags & SMP_F_MAY_CHANGE) && !(opt & SMP_OPT_FINAL))
1387 			return smp;
1388 		return NULL;
1389 	}
1390 
1391 	if (!sample_casts[smp->data.type][smp_type])
1392 		return NULL;
1393 
1394 	if (!sample_casts[smp->data.type][smp_type](smp))
1395 		return NULL;
1396 
1397 	smp->flags &= ~SMP_F_MAY_CHANGE;
1398 	return smp;
1399 }
1400 
release_sample_arg(struct arg * p)1401 static void release_sample_arg(struct arg *p)
1402 {
1403 	struct arg *p_back = p;
1404 
1405 	if (!p)
1406 		return;
1407 
1408 	while (p->type != ARGT_STOP) {
1409 		if (p->type == ARGT_STR || p->unresolved) {
1410 			chunk_destroy(&p->data.str);
1411 			p->unresolved = 0;
1412 		}
1413 		else if (p->type == ARGT_REG) {
1414 			regex_free(p->data.reg);
1415 			p->data.reg = NULL;
1416 		}
1417 		p++;
1418 	}
1419 
1420 	if (p_back != empty_arg_list)
1421 		free(p_back);
1422 }
1423 
release_sample_expr(struct sample_expr * expr)1424 void release_sample_expr(struct sample_expr *expr)
1425 {
1426 	struct sample_conv_expr *conv_expr, *conv_exprb;
1427 
1428 	if (!expr)
1429 		return;
1430 
1431 	list_for_each_entry_safe(conv_expr, conv_exprb, &expr->conv_exprs, list) {
1432 		LIST_DEL(&conv_expr->list);
1433 		release_sample_arg(conv_expr->arg_p);
1434 		free(conv_expr);
1435 	}
1436 
1437 	release_sample_arg(expr->arg_p);
1438 	free(expr);
1439 }
1440 
1441 /*****************************************************************/
1442 /*    Sample format convert functions                            */
1443 /*    These functions set the data type on return.               */
1444 /*****************************************************************/
1445 
sample_conv_debug(const struct arg * arg_p,struct sample * smp,void * private)1446 static int sample_conv_debug(const struct arg *arg_p, struct sample *smp, void *private)
1447 {
1448 	int i;
1449 	struct sample tmp;
1450 	struct buffer *buf;
1451 	struct sink *sink;
1452 	struct ist line;
1453 	char *pfx;
1454 
1455 	buf = alloc_trash_chunk();
1456 	if (!buf)
1457 		goto end;
1458 
1459 	sink = (struct sink *)arg_p[1].data.ptr;
1460 	BUG_ON(!sink);
1461 
1462 	pfx = arg_p[0].data.str.area;
1463 	BUG_ON(!pfx);
1464 
1465 	chunk_printf(buf, "[debug] %s: type=%s ", pfx, smp_to_type[smp->data.type]);
1466 	if (!sample_casts[smp->data.type][SMP_T_STR])
1467 		goto nocast;
1468 
1469 	/* Copy sample fetch. This puts the sample as const, the
1470 	 * cast will copy data if a transformation is required.
1471 	 */
1472 	memcpy(&tmp, smp, sizeof(struct sample));
1473 	tmp.flags = SMP_F_CONST;
1474 
1475 	if (!sample_casts[smp->data.type][SMP_T_STR](&tmp))
1476 		goto nocast;
1477 
1478 	/* Display the displayable chars*. */
1479 	b_putchr(buf, '<');
1480 	for (i = 0; i < tmp.data.u.str.data; i++) {
1481 		if (isprint((unsigned char)tmp.data.u.str.area[i]))
1482 			b_putchr(buf, tmp.data.u.str.area[i]);
1483 		else
1484 			b_putchr(buf, '.');
1485 	}
1486 	b_putchr(buf, '>');
1487 
1488  done:
1489 	line = ist2(buf->area, buf->data);
1490 	sink_write(sink, &line, 1, 0, 0, NULL);
1491  end:
1492 	free_trash_chunk(buf);
1493 	return 1;
1494  nocast:
1495 	chunk_appendf(buf, "(undisplayable)");
1496 	goto done;
1497 }
1498 
1499 // This function checks the "debug" converter's arguments.
smp_check_debug(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)1500 static int smp_check_debug(struct arg *args, struct sample_conv *conv,
1501                            const char *file, int line, char **err)
1502 {
1503 	const char *name = "buf0";
1504 	struct sink *sink = NULL;
1505 
1506 	if (args[0].type != ARGT_STR) {
1507 		/* optional prefix */
1508 		args[0].data.str.area = "";
1509 		args[0].data.str.data = 0;
1510 	}
1511 
1512 	if (args[1].type == ARGT_STR)
1513 		name = args[1].data.str.area;
1514 
1515 	sink = sink_find(name);
1516 	if (!sink) {
1517 		memprintf(err, "No such sink '%s'", name);
1518 		return 0;
1519 	}
1520 
1521 	chunk_destroy(&args[1].data.str);
1522 	args[1].type = ARGT_PTR;
1523 	args[1].data.ptr = sink;
1524 	return 1;
1525 }
1526 
sample_conv_base642bin(const struct arg * arg_p,struct sample * smp,void * private)1527 static int sample_conv_base642bin(const struct arg *arg_p, struct sample *smp, void *private)
1528 {
1529 	struct buffer *trash = get_trash_chunk();
1530 	int bin_len;
1531 
1532 	trash->data = 0;
1533 	bin_len = base64dec(smp->data.u.str.area, smp->data.u.str.data,
1534 			    trash->area, trash->size);
1535 	if (bin_len < 0)
1536 		return 0;
1537 
1538 	trash->data = bin_len;
1539 	smp->data.u.str = *trash;
1540 	smp->data.type = SMP_T_BIN;
1541 	smp->flags &= ~SMP_F_CONST;
1542 	return 1;
1543 }
1544 
sample_conv_bin2base64(const struct arg * arg_p,struct sample * smp,void * private)1545 static int sample_conv_bin2base64(const struct arg *arg_p, struct sample *smp, void *private)
1546 {
1547 	struct buffer *trash = get_trash_chunk();
1548 	int b64_len;
1549 
1550 	trash->data = 0;
1551 	b64_len = a2base64(smp->data.u.str.area, smp->data.u.str.data,
1552 			   trash->area, trash->size);
1553 	if (b64_len < 0)
1554 		return 0;
1555 
1556 	trash->data = b64_len;
1557 	smp->data.u.str = *trash;
1558 	smp->data.type = SMP_T_STR;
1559 	smp->flags &= ~SMP_F_CONST;
1560 	return 1;
1561 }
1562 
1563 
1564 /* This function returns a sample struct filled with the conversion of variable
1565  * <var> to sample type <type> (SMP_T_*), via a cast to the target type. If the
1566  * variable cannot be retrieved or casted, 0 is returned, otherwise 1.
1567  *
1568  * Keep in mind that the sample content may be written to a pre-allocated
1569  * trash chunk as returned by get_trash_chunk().
1570  */
sample_conv_var2smp(const struct var_desc * var,struct sample * smp,int type)1571 int sample_conv_var2smp(const struct var_desc *var, struct sample *smp, int type)
1572 {
1573 	if (!vars_get_by_desc(var, smp))
1574 		return 0;
1575 	if (!sample_casts[smp->data.type][type])
1576 		return 0;
1577 	if (!sample_casts[smp->data.type][type](smp))
1578 		return 0;
1579 	return 1;
1580 }
1581 
sample_conv_sha1(const struct arg * arg_p,struct sample * smp,void * private)1582 static int sample_conv_sha1(const struct arg *arg_p, struct sample *smp, void *private)
1583 {
1584 	blk_SHA_CTX ctx;
1585 	struct buffer *trash = get_trash_chunk();
1586 
1587 	memset(&ctx, 0, sizeof(ctx));
1588 
1589 	blk_SHA1_Init(&ctx);
1590 	blk_SHA1_Update(&ctx, smp->data.u.str.area, smp->data.u.str.data);
1591 	blk_SHA1_Final((unsigned char *) trash->area, &ctx);
1592 
1593 	trash->data = 20;
1594 	smp->data.u.str = *trash;
1595 	smp->data.type = SMP_T_BIN;
1596 	smp->flags &= ~SMP_F_CONST;
1597 	return 1;
1598 }
1599 
1600 #ifdef USE_OPENSSL
smp_check_sha2(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)1601 static int smp_check_sha2(struct arg *args, struct sample_conv *conv,
1602                           const char *file, int line, char **err)
1603 {
1604 	if (args[0].type == ARGT_STOP)
1605 		return 1;
1606 	if (args[0].type != ARGT_SINT) {
1607 		memprintf(err, "Invalid type '%s'", arg_type_names[args[0].type]);
1608 		return 0;
1609 	}
1610 
1611 	switch (args[0].data.sint) {
1612 		case 224:
1613 		case 256:
1614 		case 384:
1615 		case 512:
1616 			/* this is okay */
1617 			return 1;
1618 		default:
1619 			memprintf(err, "Unsupported number of bits: '%lld'", args[0].data.sint);
1620 			return 0;
1621 	}
1622 }
1623 
sample_conv_sha2(const struct arg * arg_p,struct sample * smp,void * private)1624 static int sample_conv_sha2(const struct arg *arg_p, struct sample *smp, void *private)
1625 {
1626 	struct buffer *trash = get_trash_chunk();
1627 	int bits = 256;
1628 	if (arg_p && arg_p->data.sint)
1629 		bits = arg_p->data.sint;
1630 
1631 	switch (bits) {
1632 	case 224: {
1633 		SHA256_CTX ctx;
1634 
1635 		memset(&ctx, 0, sizeof(ctx));
1636 
1637 		SHA224_Init(&ctx);
1638 		SHA224_Update(&ctx, smp->data.u.str.area, smp->data.u.str.data);
1639 		SHA224_Final((unsigned char *) trash->area, &ctx);
1640 		trash->data = SHA224_DIGEST_LENGTH;
1641 		break;
1642 	}
1643 	case 256: {
1644 		SHA256_CTX ctx;
1645 
1646 		memset(&ctx, 0, sizeof(ctx));
1647 
1648 		SHA256_Init(&ctx);
1649 		SHA256_Update(&ctx, smp->data.u.str.area, smp->data.u.str.data);
1650 		SHA256_Final((unsigned char *) trash->area, &ctx);
1651 		trash->data = SHA256_DIGEST_LENGTH;
1652 		break;
1653 	}
1654 	case 384: {
1655 		SHA512_CTX ctx;
1656 
1657 		memset(&ctx, 0, sizeof(ctx));
1658 
1659 		SHA384_Init(&ctx);
1660 		SHA384_Update(&ctx, smp->data.u.str.area, smp->data.u.str.data);
1661 		SHA384_Final((unsigned char *) trash->area, &ctx);
1662 		trash->data = SHA384_DIGEST_LENGTH;
1663 		break;
1664 	}
1665 	case 512: {
1666 		SHA512_CTX ctx;
1667 
1668 		memset(&ctx, 0, sizeof(ctx));
1669 
1670 		SHA512_Init(&ctx);
1671 		SHA512_Update(&ctx, smp->data.u.str.area, smp->data.u.str.data);
1672 		SHA512_Final((unsigned char *) trash->area, &ctx);
1673 		trash->data = SHA512_DIGEST_LENGTH;
1674 		break;
1675 	}
1676 	default:
1677 		return 0;
1678 	}
1679 
1680 	smp->data.u.str = *trash;
1681 	smp->data.type = SMP_T_BIN;
1682 	smp->flags &= ~SMP_F_CONST;
1683 	return 1;
1684 }
1685 
1686 /* This function returns a sample struct filled with an <arg> content.
1687  * If the <arg> contains a string, it is returned in the sample flagged as
1688  * SMP_F_CONST. If the <arg> contains a variable descriptor, the sample is
1689  * filled with the content of the variable by using vars_get_by_desc().
1690  *
1691  * Keep in mind that the sample content may be written to a pre-allocated
1692  * trash chunk as returned by get_trash_chunk().
1693  *
1694  * This function returns 0 if an error occurs, otherwise it returns 1.
1695  */
sample_conv_var2smp_str(const struct arg * arg,struct sample * smp)1696 int sample_conv_var2smp_str(const struct arg *arg, struct sample *smp)
1697 {
1698 	switch (arg->type) {
1699 	case ARGT_STR:
1700 		smp->data.type = SMP_T_STR;
1701 		smp->data.u.str = arg->data.str;
1702 		smp->flags = SMP_F_CONST;
1703 		return 1;
1704 	case ARGT_VAR:
1705 		return sample_conv_var2smp(&arg->data.var, smp, SMP_T_STR);
1706 	default:
1707 		return 0;
1708 	}
1709 }
1710 
1711 /* This function checks an <arg> and fills it with a variable type if the
1712  * <arg> string contains a valid variable name. If failed, the function
1713  * tries to perform a base64 decode operation on the same string, and
1714  * fills the <arg> with the decoded content.
1715  *
1716  * Validation is skipped if the <arg> string is empty.
1717  *
1718  * This function returns 0 if the variable lookup fails and the specified
1719  * <arg> string is not a valid base64 encoded string, as well if
1720  * unexpected argument type is specified or memory allocation error
1721  * occurs. Otherwise it returns 1.
1722  */
sample_check_arg_base64(struct arg * arg,char ** err)1723 static inline int sample_check_arg_base64(struct arg *arg, char **err)
1724 {
1725 	char *dec = NULL;
1726 	int dec_size;
1727 
1728 	if (arg->type != ARGT_STR) {
1729 		memprintf(err, "unexpected argument type");
1730 		return 0;
1731 	}
1732 
1733 	if (arg->data.str.data == 0) /* empty */
1734 		return 1;
1735 
1736 	if (vars_check_arg(arg, NULL))
1737 		return 1;
1738 
1739 	if (arg->data.str.data % 4) {
1740 		memprintf(err, "argument needs to be base64 encoded, and "
1741 		               "can either be a string or a variable");
1742 		return 0;
1743 	}
1744 
1745 	dec_size = (arg->data.str.data / 4 * 3)
1746 	           - (arg->data.str.area[arg->data.str.data-1] == '=' ? 1 : 0)
1747 	           - (arg->data.str.area[arg->data.str.data-2] == '=' ? 1 : 0);
1748 
1749 	if ((dec = malloc(dec_size)) == NULL) {
1750 		memprintf(err, "memory allocation error");
1751 		return 0;
1752 	}
1753 
1754 	dec_size = base64dec(arg->data.str.area, arg->data.str.data, dec, dec_size);
1755 	if (dec_size < 0) {
1756 		memprintf(err, "argument needs to be base64 encoded, and "
1757 		               "can either be a string or a variable");
1758 		free(dec);
1759 		return 0;
1760 	}
1761 
1762 	/* base64 decoded */
1763 	chunk_destroy(&arg->data.str);
1764 	arg->data.str.area = dec;
1765 	arg->data.str.data = dec_size;
1766 	return 1;
1767 }
1768 
1769 #if (HA_OPENSSL_VERSION_NUMBER >= 0x1000100fL)
check_aes_gcm(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)1770 static int check_aes_gcm(struct arg *args, struct sample_conv *conv,
1771 						  const char *file, int line, char **err)
1772 {
1773 	switch(args[0].data.sint) {
1774 	case 128:
1775 	case 192:
1776 	case 256:
1777 		break;
1778 	default:
1779 		memprintf(err, "key size must be 128, 192 or 256 (bits).");
1780 		return 0;
1781 	}
1782 
1783 	/* Try to decode variables. */
1784 	if (!sample_check_arg_base64(&args[1], err)) {
1785 		memprintf(err, "failed to parse nonce : %s", *err);
1786 		return 0;
1787 	}
1788 	if (!sample_check_arg_base64(&args[2], err)) {
1789 		memprintf(err, "failed to parse key : %s", *err);
1790 		return 0;
1791 	}
1792 	if (!sample_check_arg_base64(&args[3], err)) {
1793 		memprintf(err, "failed to parse aead_tag : %s", *err);
1794 		return 0;
1795 	}
1796 
1797 	return 1;
1798 }
1799 
1800 /* Arguments: AES size in bits, nonce, key, tag. The last three arguments are base64 encoded */
sample_conv_aes_gcm_dec(const struct arg * arg_p,struct sample * smp,void * private)1801 static int sample_conv_aes_gcm_dec(const struct arg *arg_p, struct sample *smp, void *private)
1802 {
1803 	struct sample nonce, key, aead_tag;
1804 	struct buffer *smp_trash = NULL, *smp_trash_alloc = NULL;
1805 	EVP_CIPHER_CTX *ctx;
1806 	int dec_size, ret;
1807 
1808 	smp_trash_alloc = alloc_trash_chunk();
1809 	if (!smp_trash_alloc)
1810 		return 0;
1811 
1812 	/* smp copy */
1813 	smp_trash_alloc->data = smp->data.u.str.data;
1814 	if (unlikely(smp_trash_alloc->data > smp_trash_alloc->size))
1815 		smp_trash_alloc->data = smp_trash_alloc->size;
1816 	memcpy(smp_trash_alloc->area, smp->data.u.str.area, smp_trash_alloc->data);
1817 
1818 	ctx = EVP_CIPHER_CTX_new();
1819 
1820 	if (!ctx)
1821 		goto err;
1822 
1823 	smp_trash = alloc_trash_chunk();
1824 	if (!smp_trash)
1825 		goto err;
1826 
1827 	smp_set_owner(&nonce, smp->px, smp->sess, smp->strm, smp->opt);
1828 	if (!sample_conv_var2smp_str(&arg_p[1], &nonce))
1829 		goto err;
1830 
1831 	if (arg_p[1].type == ARGT_VAR) {
1832 		dec_size = base64dec(nonce.data.u.str.area, nonce.data.u.str.data, smp_trash->area, smp_trash->size);
1833 		if (dec_size < 0)
1834 			goto err;
1835 		smp_trash->data = dec_size;
1836 		nonce.data.u.str = *smp_trash;
1837 	}
1838 
1839 	/* Set cipher type and mode */
1840 	switch(arg_p[0].data.sint) {
1841 	case 128:
1842 		EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
1843 		break;
1844 	case 192:
1845 		EVP_DecryptInit_ex(ctx, EVP_aes_192_gcm(), NULL, NULL, NULL);
1846 		break;
1847 	case 256:
1848 		EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
1849 		break;
1850 	}
1851 
1852 	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, nonce.data.u.str.data, NULL);
1853 
1854 	/* Initialise IV */
1855 	if(!EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, (unsigned char *) nonce.data.u.str.area))
1856 		goto err;
1857 
1858 	smp_set_owner(&key, smp->px, smp->sess, smp->strm, smp->opt);
1859 	if (!sample_conv_var2smp_str(&arg_p[2], &key))
1860 		goto err;
1861 
1862 	if (arg_p[2].type == ARGT_VAR) {
1863 		dec_size = base64dec(key.data.u.str.area, key.data.u.str.data, smp_trash->area, smp_trash->size);
1864 		if (dec_size < 0)
1865 			goto err;
1866 		smp_trash->data = dec_size;
1867 		key.data.u.str = *smp_trash;
1868 	}
1869 
1870 	/* Initialise key */
1871 	if (!EVP_DecryptInit_ex(ctx, NULL, NULL, (unsigned char *) key.data.u.str.area, NULL))
1872 		goto err;
1873 
1874 	if (!EVP_DecryptUpdate(ctx, (unsigned char *) smp_trash->area, (int *) &smp_trash->data,
1875 	                       (unsigned char *) smp_trash_alloc->area, (int) smp_trash_alloc->data))
1876 		goto err;
1877 
1878 	smp_set_owner(&aead_tag, smp->px, smp->sess, smp->strm, smp->opt);
1879 	if (!sample_conv_var2smp_str(&arg_p[3], &aead_tag))
1880 		goto err;
1881 
1882 	if (arg_p[3].type == ARGT_VAR) {
1883 		dec_size = base64dec(aead_tag.data.u.str.area, aead_tag.data.u.str.data, smp_trash_alloc->area, smp_trash_alloc->size);
1884 		if (dec_size < 0)
1885 			goto err;
1886 		smp_trash_alloc->data = dec_size;
1887 		aead_tag.data.u.str = *smp_trash_alloc;
1888 	}
1889 
1890 	dec_size = smp_trash->data;
1891 
1892 	EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, aead_tag.data.u.str.data, (void *) aead_tag.data.u.str.area);
1893 	ret = EVP_DecryptFinal_ex(ctx, (unsigned char *) smp_trash->area + smp_trash->data, (int *) &smp_trash->data);
1894 
1895 	if (ret <= 0)
1896 		goto err;
1897 
1898 	smp->data.u.str.data = dec_size + smp_trash->data;
1899 	smp->data.u.str.area = smp_trash->area;
1900 	smp->data.type = SMP_T_BIN;
1901 	smp_dup(smp);
1902 	free_trash_chunk(smp_trash_alloc);
1903 	free_trash_chunk(smp_trash);
1904 	return 1;
1905 
1906 err:
1907 	free_trash_chunk(smp_trash_alloc);
1908 	free_trash_chunk(smp_trash);
1909 	return 0;
1910 }
1911 #endif /* HA_OPENSSL_VERSION_NUMBER */
1912 
check_crypto_digest(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)1913 static int check_crypto_digest(struct arg *args, struct sample_conv *conv,
1914 						  const char *file, int line, char **err)
1915 {
1916 	const EVP_MD *evp = EVP_get_digestbyname(args[0].data.str.area);
1917 
1918 	if (evp)
1919 		return 1;
1920 
1921 	memprintf(err, "algorithm must be a valid OpenSSL message digest name.");
1922 	return 0;
1923 }
1924 
sample_conv_crypto_digest(const struct arg * args,struct sample * smp,void * private)1925 static int sample_conv_crypto_digest(const struct arg *args, struct sample *smp, void *private)
1926 {
1927 	struct buffer *trash = get_trash_chunk();
1928 	unsigned char *md = (unsigned char*) trash->area;
1929 	unsigned int md_len = trash->size;
1930 	EVP_MD_CTX *ctx = EVP_MD_CTX_new();
1931 	const EVP_MD *evp = EVP_get_digestbyname(args[0].data.str.area);
1932 
1933 	if (!ctx)
1934 		return 0;
1935 
1936 	if (!EVP_DigestInit_ex(ctx, evp, NULL) ||
1937 	    !EVP_DigestUpdate(ctx, smp->data.u.str.area, smp->data.u.str.data) ||
1938 	    !EVP_DigestFinal_ex(ctx, md, &md_len)) {
1939 		EVP_MD_CTX_free(ctx);
1940 		return 0;
1941 	}
1942 
1943 	EVP_MD_CTX_free(ctx);
1944 
1945 	trash->data = md_len;
1946 	smp->data.u.str = *trash;
1947 	smp->data.type = SMP_T_BIN;
1948 	smp->flags &= ~SMP_F_CONST;
1949 	return 1;
1950 }
1951 
check_crypto_hmac(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)1952 static int check_crypto_hmac(struct arg *args, struct sample_conv *conv,
1953 						  const char *file, int line, char **err)
1954 {
1955 	if (!check_crypto_digest(args, conv, file, line, err))
1956 		return 0;
1957 
1958 	if (!sample_check_arg_base64(&args[1], err)) {
1959 		memprintf(err, "failed to parse key : %s", *err);
1960 		return 0;
1961 	}
1962 
1963 	return 1;
1964 }
1965 
sample_conv_crypto_hmac(const struct arg * args,struct sample * smp,void * private)1966 static int sample_conv_crypto_hmac(const struct arg *args, struct sample *smp, void *private)
1967 {
1968 	struct sample key;
1969 	struct buffer *trash = NULL, *key_trash = NULL;
1970 	unsigned char *md;
1971 	unsigned int md_len;
1972 	const EVP_MD *evp = EVP_get_digestbyname(args[0].data.str.area);
1973 	int dec_size;
1974 
1975 	smp_set_owner(&key, smp->px, smp->sess, smp->strm, smp->opt);
1976 	if (!sample_conv_var2smp_str(&args[1], &key))
1977 		return 0;
1978 
1979 	if (args[1].type == ARGT_VAR) {
1980 		key_trash = alloc_trash_chunk();
1981 		if (!key_trash)
1982 			goto err;
1983 
1984 		dec_size = base64dec(key.data.u.str.area, key.data.u.str.data, key_trash->area, key_trash->size);
1985 		if (dec_size < 0)
1986 			goto err;
1987 		key_trash->data = dec_size;
1988 		key.data.u.str = *key_trash;
1989 	}
1990 
1991 	trash = alloc_trash_chunk();
1992 	if (!trash)
1993 		goto err;
1994 
1995 	md = (unsigned char*) trash->area;
1996 	md_len = trash->size;
1997 	if (!HMAC(evp, key.data.u.str.area, key.data.u.str.data, (const unsigned char*) smp->data.u.str.area,
1998 	          smp->data.u.str.data, md, &md_len))
1999 		goto err;
2000 
2001 	free_trash_chunk(key_trash);
2002 
2003 	trash->data = md_len;
2004 	smp->data.u.str = *trash;
2005 	smp->data.type = SMP_T_BIN;
2006 	smp_dup(smp);
2007 	free_trash_chunk(trash);
2008 	return 1;
2009 
2010 err:
2011 	free_trash_chunk(key_trash);
2012 	free_trash_chunk(trash);
2013 	return 0;
2014 }
2015 
2016 #endif /* USE_OPENSSL */
2017 
sample_conv_bin2hex(const struct arg * arg_p,struct sample * smp,void * private)2018 static int sample_conv_bin2hex(const struct arg *arg_p, struct sample *smp, void *private)
2019 {
2020 	struct buffer *trash = get_trash_chunk();
2021 	unsigned char c;
2022 	int ptr = 0;
2023 
2024 	trash->data = 0;
2025 	while (ptr < smp->data.u.str.data && trash->data <= trash->size - 2) {
2026 		c = smp->data.u.str.area[ptr++];
2027 		trash->area[trash->data++] = hextab[(c >> 4) & 0xF];
2028 		trash->area[trash->data++] = hextab[c & 0xF];
2029 	}
2030 	smp->data.u.str = *trash;
2031 	smp->data.type = SMP_T_STR;
2032 	smp->flags &= ~SMP_F_CONST;
2033 	return 1;
2034 }
2035 
sample_conv_hex2int(const struct arg * arg_p,struct sample * smp,void * private)2036 static int sample_conv_hex2int(const struct arg *arg_p, struct sample *smp, void *private)
2037 {
2038 	long long int n = 0;
2039 	int i, c;
2040 
2041 	for (i = 0; i < smp->data.u.str.data; i++) {
2042 		if ((c = hex2i(smp->data.u.str.area[i])) < 0)
2043 			return 0;
2044 		n = (n << 4) + c;
2045 	}
2046 
2047 	smp->data.u.sint = n;
2048 	smp->data.type = SMP_T_SINT;
2049 	smp->flags &= ~SMP_F_CONST;
2050 	return 1;
2051 }
2052 
2053 /* hashes the binary input into a 32-bit unsigned int */
sample_conv_djb2(const struct arg * arg_p,struct sample * smp,void * private)2054 static int sample_conv_djb2(const struct arg *arg_p, struct sample *smp, void *private)
2055 {
2056 	smp->data.u.sint = hash_djb2(smp->data.u.str.area,
2057 				     smp->data.u.str.data);
2058 	if (arg_p && arg_p->data.sint)
2059 		smp->data.u.sint = full_hash(smp->data.u.sint);
2060 	smp->data.type = SMP_T_SINT;
2061 	return 1;
2062 }
2063 
sample_conv_length(const struct arg * arg_p,struct sample * smp,void * private)2064 static int sample_conv_length(const struct arg *arg_p, struct sample *smp, void *private)
2065 {
2066 	int i = smp->data.u.str.data;
2067 	smp->data.u.sint = i;
2068 	smp->data.type = SMP_T_SINT;
2069 	return 1;
2070 }
2071 
2072 
sample_conv_str2lower(const struct arg * arg_p,struct sample * smp,void * private)2073 static int sample_conv_str2lower(const struct arg *arg_p, struct sample *smp, void *private)
2074 {
2075 	int i;
2076 
2077 	if (!smp_make_rw(smp))
2078 		return 0;
2079 
2080 	for (i = 0; i < smp->data.u.str.data; i++) {
2081 		if ((smp->data.u.str.area[i] >= 'A') && (smp->data.u.str.area[i] <= 'Z'))
2082 			smp->data.u.str.area[i] += 'a' - 'A';
2083 	}
2084 	return 1;
2085 }
2086 
sample_conv_str2upper(const struct arg * arg_p,struct sample * smp,void * private)2087 static int sample_conv_str2upper(const struct arg *arg_p, struct sample *smp, void *private)
2088 {
2089 	int i;
2090 
2091 	if (!smp_make_rw(smp))
2092 		return 0;
2093 
2094 	for (i = 0; i < smp->data.u.str.data; i++) {
2095 		if ((smp->data.u.str.area[i] >= 'a') && (smp->data.u.str.area[i] <= 'z'))
2096 			smp->data.u.str.area[i] += 'A' - 'a';
2097 	}
2098 	return 1;
2099 }
2100 
2101 /* takes the IPv4 mask in args[0] and an optional IPv6 mask in args[1] */
sample_conv_ipmask(const struct arg * args,struct sample * smp,void * private)2102 static int sample_conv_ipmask(const struct arg *args, struct sample *smp, void *private)
2103 {
2104 	/* Attempt to convert to IPv4 to apply the correct mask. */
2105 	c_ipv62ip(smp);
2106 
2107 	if (smp->data.type == SMP_T_IPV4) {
2108 		smp->data.u.ipv4.s_addr &= args[0].data.ipv4.s_addr;
2109 		smp->data.type = SMP_T_IPV4;
2110 	}
2111 	else if (smp->data.type == SMP_T_IPV6) {
2112 		/* IPv6 cannot be converted without an IPv6 mask. */
2113 		if (args[1].type != ARGT_IPV6)
2114 			return 0;
2115 
2116 		write_u64(&smp->data.u.ipv6.s6_addr[0],
2117 			  read_u64(&smp->data.u.ipv6.s6_addr[0]) & read_u64(&args[1].data.ipv6.s6_addr[0]));
2118 		write_u64(&smp->data.u.ipv6.s6_addr[8],
2119 			  read_u64(&smp->data.u.ipv6.s6_addr[8]) & read_u64(&args[1].data.ipv6.s6_addr[8]));
2120 		smp->data.type = SMP_T_IPV6;
2121 	}
2122 
2123 	return 1;
2124 }
2125 
2126 /* takes an UINT value on input supposed to represent the time since EPOCH,
2127  * adds an optional offset found in args[1] and emits a string representing
2128  * the local time in the format specified in args[1] using strftime().
2129  */
sample_conv_ltime(const struct arg * args,struct sample * smp,void * private)2130 static int sample_conv_ltime(const struct arg *args, struct sample *smp, void *private)
2131 {
2132 	struct buffer *temp;
2133 	/* With high numbers, the date returned can be negative, the 55 bits mask prevent this. */
2134 	time_t curr_date = smp->data.u.sint & 0x007fffffffffffffLL;
2135 	struct tm tm;
2136 
2137 	/* add offset */
2138 	if (args[1].type == ARGT_SINT)
2139 		curr_date += args[1].data.sint;
2140 
2141 	get_localtime(curr_date, &tm);
2142 
2143 	temp = get_trash_chunk();
2144 	temp->data = strftime(temp->area, temp->size, args[0].data.str.area, &tm);
2145 	smp->data.u.str = *temp;
2146 	smp->data.type = SMP_T_STR;
2147 	return 1;
2148 }
2149 
2150 /* hashes the binary input into a 32-bit unsigned int */
sample_conv_sdbm(const struct arg * arg_p,struct sample * smp,void * private)2151 static int sample_conv_sdbm(const struct arg *arg_p, struct sample *smp, void *private)
2152 {
2153 	smp->data.u.sint = hash_sdbm(smp->data.u.str.area,
2154 				     smp->data.u.str.data);
2155 	if (arg_p && arg_p->data.sint)
2156 		smp->data.u.sint = full_hash(smp->data.u.sint);
2157 	smp->data.type = SMP_T_SINT;
2158 	return 1;
2159 }
2160 
2161 /* takes an UINT value on input supposed to represent the time since EPOCH,
2162  * adds an optional offset found in args[1] and emits a string representing
2163  * the UTC date in the format specified in args[1] using strftime().
2164  */
sample_conv_utime(const struct arg * args,struct sample * smp,void * private)2165 static int sample_conv_utime(const struct arg *args, struct sample *smp, void *private)
2166 {
2167 	struct buffer *temp;
2168 	/* With high numbers, the date returned can be negative, the 55 bits mask prevent this. */
2169 	time_t curr_date = smp->data.u.sint & 0x007fffffffffffffLL;
2170 	struct tm tm;
2171 
2172 	/* add offset */
2173 	if (args[1].type == ARGT_SINT)
2174 		curr_date += args[1].data.sint;
2175 
2176 	get_gmtime(curr_date, &tm);
2177 
2178 	temp = get_trash_chunk();
2179 	temp->data = strftime(temp->area, temp->size, args[0].data.str.area, &tm);
2180 	smp->data.u.str = *temp;
2181 	smp->data.type = SMP_T_STR;
2182 	return 1;
2183 }
2184 
2185 /* hashes the binary input into a 32-bit unsigned int */
sample_conv_wt6(const struct arg * arg_p,struct sample * smp,void * private)2186 static int sample_conv_wt6(const struct arg *arg_p, struct sample *smp, void *private)
2187 {
2188 	smp->data.u.sint = hash_wt6(smp->data.u.str.area,
2189 				    smp->data.u.str.data);
2190 	if (arg_p && arg_p->data.sint)
2191 		smp->data.u.sint = full_hash(smp->data.u.sint);
2192 	smp->data.type = SMP_T_SINT;
2193 	return 1;
2194 }
2195 
2196 /* hashes the binary input into a 32-bit unsigned int using xxh.
2197  * The seed of the hash defaults to 0 but can be changd in argument 1.
2198  */
sample_conv_xxh32(const struct arg * arg_p,struct sample * smp,void * private)2199 static int sample_conv_xxh32(const struct arg *arg_p, struct sample *smp, void *private)
2200 {
2201 	unsigned int seed;
2202 
2203 	if (arg_p && arg_p->data.sint)
2204 		seed = arg_p->data.sint;
2205 	else
2206 		seed = 0;
2207 	smp->data.u.sint = XXH32(smp->data.u.str.area, smp->data.u.str.data,
2208 				 seed);
2209 	smp->data.type = SMP_T_SINT;
2210 	return 1;
2211 }
2212 
2213 /* hashes the binary input into a 64-bit unsigned int using xxh.
2214  * In fact, the function returns a 64 bit unsigned, but the sample
2215  * storage of haproxy only proposes 64-bits signed, so the value is
2216  * cast as signed. This cast doesn't impact the hash repartition.
2217  * The seed of the hash defaults to 0 but can be changd in argument 1.
2218  */
sample_conv_xxh64(const struct arg * arg_p,struct sample * smp,void * private)2219 static int sample_conv_xxh64(const struct arg *arg_p, struct sample *smp, void *private)
2220 {
2221 	unsigned long long int seed;
2222 
2223 	if (arg_p && arg_p->data.sint)
2224 		seed = (unsigned long long int)arg_p->data.sint;
2225 	else
2226 		seed = 0;
2227 	smp->data.u.sint = (long long int)XXH64(smp->data.u.str.area,
2228 						smp->data.u.str.data, seed);
2229 	smp->data.type = SMP_T_SINT;
2230 	return 1;
2231 }
2232 
2233 /* hashes the binary input into a 32-bit unsigned int */
sample_conv_crc32(const struct arg * arg_p,struct sample * smp,void * private)2234 static int sample_conv_crc32(const struct arg *arg_p, struct sample *smp, void *private)
2235 {
2236 	smp->data.u.sint = hash_crc32(smp->data.u.str.area,
2237 				      smp->data.u.str.data);
2238 	if (arg_p && arg_p->data.sint)
2239 		smp->data.u.sint = full_hash(smp->data.u.sint);
2240 	smp->data.type = SMP_T_SINT;
2241 	return 1;
2242 }
2243 
2244 /* hashes the binary input into crc32c (RFC4960, Appendix B [8].) */
sample_conv_crc32c(const struct arg * arg_p,struct sample * smp,void * private)2245 static int sample_conv_crc32c(const struct arg *arg_p, struct sample *smp, void *private)
2246 {
2247 	smp->data.u.sint = hash_crc32c(smp->data.u.str.area,
2248 				       smp->data.u.str.data);
2249 	if (arg_p && arg_p->data.sint)
2250 		smp->data.u.sint = full_hash(smp->data.u.sint);
2251 	smp->data.type = SMP_T_SINT;
2252 	return 1;
2253 }
2254 
2255 /* This function escape special json characters. The returned string can be
2256  * safely set between two '"' and used as json string. The json string is
2257  * defined like this:
2258  *
2259  *    any Unicode character except '"' or '\' or control character
2260  *    \", \\, \/, \b, \f, \n, \r, \t, \u + four-hex-digits
2261  *
2262  * The enum input_type contain all the allowed mode for decoding the input
2263  * string.
2264  */
2265 enum input_type {
2266 	IT_ASCII = 0,
2267 	IT_UTF8,
2268 	IT_UTF8S,
2269 	IT_UTF8P,
2270 	IT_UTF8PS,
2271 };
sample_conv_json_check(struct arg * arg,struct sample_conv * conv,const char * file,int line,char ** err)2272 static int sample_conv_json_check(struct arg *arg, struct sample_conv *conv,
2273                                   const char *file, int line, char **err)
2274 {
2275 	enum input_type type;
2276 
2277 	if (!arg) {
2278 		memprintf(err, "Unexpected empty arg list");
2279 		return 0;
2280 	}
2281 
2282 	if (arg->type != ARGT_STR) {
2283 		memprintf(err, "Unexpected arg type");
2284 		return 0;
2285 	}
2286 
2287 	if (strcmp(arg->data.str.area, "") == 0)
2288 		type = IT_ASCII;
2289 	else if (strcmp(arg->data.str.area, "ascii") == 0)
2290 		type = IT_ASCII;
2291 	else if (strcmp(arg->data.str.area, "utf8") == 0)
2292 		type = IT_UTF8;
2293 	else if (strcmp(arg->data.str.area, "utf8s") == 0)
2294 		type = IT_UTF8S;
2295 	else if (strcmp(arg->data.str.area, "utf8p") == 0)
2296 		type = IT_UTF8P;
2297 	else if (strcmp(arg->data.str.area, "utf8ps") == 0)
2298 		type = IT_UTF8PS;
2299 	else {
2300 		memprintf(err, "Unexpected input code type. "
2301 			  "Allowed value are 'ascii', 'utf8', 'utf8s', 'utf8p' and 'utf8ps'");
2302 		return 0;
2303 	}
2304 
2305 	chunk_destroy(&arg->data.str);
2306 	arg->type = ARGT_SINT;
2307 	arg->data.sint = type;
2308 	return 1;
2309 }
2310 
sample_conv_json(const struct arg * arg_p,struct sample * smp,void * private)2311 static int sample_conv_json(const struct arg *arg_p, struct sample *smp, void *private)
2312 {
2313 	struct buffer *temp;
2314 	char _str[7]; /* \u + 4 hex digit + null char for sprintf. */
2315 	const char *str;
2316 	int len;
2317 	enum input_type input_type = IT_ASCII;
2318 	unsigned int c;
2319 	unsigned int ret;
2320 	char *p;
2321 
2322 	if (arg_p)
2323 		input_type = arg_p->data.sint;
2324 
2325 	temp = get_trash_chunk();
2326 	temp->data = 0;
2327 
2328 	p = smp->data.u.str.area;
2329 	while (p < smp->data.u.str.area + smp->data.u.str.data) {
2330 
2331 		if (input_type == IT_ASCII) {
2332 			/* Read input as ASCII. */
2333 			c = *(unsigned char *)p;
2334 			p++;
2335 		}
2336 		else {
2337 			/* Read input as UTF8. */
2338 			ret = utf8_next(p,
2339 					smp->data.u.str.data - ( p - smp->data.u.str.area),
2340 					&c);
2341 			p += utf8_return_length(ret);
2342 
2343 			if (input_type == IT_UTF8 && utf8_return_code(ret) != UTF8_CODE_OK)
2344 					return 0;
2345 			if (input_type == IT_UTF8S && utf8_return_code(ret) != UTF8_CODE_OK)
2346 					continue;
2347 			if (input_type == IT_UTF8P && utf8_return_code(ret) & (UTF8_CODE_INVRANGE|UTF8_CODE_BADSEQ))
2348 					return 0;
2349 			if (input_type == IT_UTF8PS && utf8_return_code(ret) & (UTF8_CODE_INVRANGE|UTF8_CODE_BADSEQ))
2350 					continue;
2351 
2352 			/* Check too big values. */
2353 			if ((unsigned int)c > 0xffff) {
2354 				if (input_type == IT_UTF8 || input_type == IT_UTF8P)
2355 					return 0;
2356 				continue;
2357 			}
2358 		}
2359 
2360 		/* Convert character. */
2361 		if (c == '"') {
2362 			len = 2;
2363 			str = "\\\"";
2364 		}
2365 		else if (c == '\\') {
2366 			len = 2;
2367 			str = "\\\\";
2368 		}
2369 		else if (c == '/') {
2370 			len = 2;
2371 			str = "\\/";
2372 		}
2373 		else if (c == '\b') {
2374 			len = 2;
2375 			str = "\\b";
2376 		}
2377 		else if (c == '\f') {
2378 			len = 2;
2379 			str = "\\f";
2380 		}
2381 		else if (c == '\r') {
2382 			len = 2;
2383 			str = "\\r";
2384 		}
2385 		else if (c == '\n') {
2386 			len = 2;
2387 			str = "\\n";
2388 		}
2389 		else if (c == '\t') {
2390 			len = 2;
2391 			str = "\\t";
2392 		}
2393 		else if (c > 0xff || !isprint((unsigned char)c)) {
2394 			/* isprint generate a segfault if c is too big. The man says that
2395 			 * c must have the value of an unsigned char or EOF.
2396 			 */
2397 			len = 6;
2398 			_str[0] = '\\';
2399 			_str[1] = 'u';
2400 			snprintf(&_str[2], 5, "%04x", (unsigned short)c);
2401 			str = _str;
2402 		}
2403 		else {
2404 			len = 1;
2405 			_str[0] = c;
2406 			str = _str;
2407 		}
2408 
2409 		/* Check length */
2410 		if (temp->data + len > temp->size)
2411 			return 0;
2412 
2413 		/* Copy string. */
2414 		memcpy(temp->area + temp->data, str, len);
2415 		temp->data += len;
2416 	}
2417 
2418 	smp->flags &= ~SMP_F_CONST;
2419 	smp->data.u.str = *temp;
2420 	smp->data.type = SMP_T_STR;
2421 
2422 	return 1;
2423 }
2424 
2425 /* This sample function is designed to extract some bytes from an input buffer.
2426  * First arg is the offset.
2427  * Optional second arg is the length to truncate */
sample_conv_bytes(const struct arg * arg_p,struct sample * smp,void * private)2428 static int sample_conv_bytes(const struct arg *arg_p, struct sample *smp, void *private)
2429 {
2430 	if (smp->data.u.str.data <= arg_p[0].data.sint) {
2431 		smp->data.u.str.data = 0;
2432 		return 1;
2433 	}
2434 
2435 	if (smp->data.u.str.size)
2436 			smp->data.u.str.size -= arg_p[0].data.sint;
2437 	smp->data.u.str.data -= arg_p[0].data.sint;
2438 	smp->data.u.str.area += arg_p[0].data.sint;
2439 
2440 	if ((arg_p[1].type == ARGT_SINT) && (arg_p[1].data.sint < smp->data.u.str.data))
2441 		smp->data.u.str.data = arg_p[1].data.sint;
2442 
2443 	return 1;
2444 }
2445 
sample_conv_field_check(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)2446 static int sample_conv_field_check(struct arg *args, struct sample_conv *conv,
2447                                   const char *file, int line, char **err)
2448 {
2449 	struct arg *arg = args;
2450 
2451 	if (!arg) {
2452 		memprintf(err, "Unexpected empty arg list");
2453 		return 0;
2454 	}
2455 
2456 	if (arg->type != ARGT_SINT) {
2457 		memprintf(err, "Unexpected arg type");
2458 		return 0;
2459 	}
2460 
2461 	if (!arg->data.sint) {
2462 		memprintf(err, "Unexpected value 0 for index");
2463 		return 0;
2464 	}
2465 
2466 	arg++;
2467 
2468 	if (arg->type != ARGT_STR) {
2469 		memprintf(err, "Unexpected arg type");
2470 		return 0;
2471 	}
2472 
2473 	if (!arg->data.str.data) {
2474 		memprintf(err, "Empty separators list");
2475 		return 0;
2476 	}
2477 
2478 	return 1;
2479 }
2480 
2481 /* This sample function is designed to a return selected part of a string (field).
2482  * First arg is the index of the field (start at 1)
2483  * Second arg is a char list of separators (type string)
2484  */
sample_conv_field(const struct arg * arg_p,struct sample * smp,void * private)2485 static int sample_conv_field(const struct arg *arg_p, struct sample *smp, void *private)
2486 {
2487 	int field;
2488 	char *start, *end;
2489 	int i;
2490 	int count = (arg_p[2].type == ARGT_SINT) ? arg_p[2].data.sint : 1;
2491 
2492 	if (!arg_p[0].data.sint)
2493 		return 0;
2494 
2495 	if (arg_p[0].data.sint < 0) {
2496 		field = -1;
2497 		end = start = smp->data.u.str.area + smp->data.u.str.data;
2498 		while (start > smp->data.u.str.area) {
2499 			for (i = 0 ; i < arg_p[1].data.str.data; i++) {
2500 				if (*(start-1) == arg_p[1].data.str.area[i]) {
2501 					if (field == arg_p[0].data.sint) {
2502 						if (count == 1)
2503 							goto found;
2504 						else if (count > 1)
2505 							count--;
2506 					} else {
2507 						end = start-1;
2508 						field--;
2509 					}
2510 					break;
2511 				}
2512 			}
2513 			start--;
2514 		}
2515 	} else {
2516 		field = 1;
2517 		end = start = smp->data.u.str.area;
2518 		while (end - smp->data.u.str.area < smp->data.u.str.data) {
2519 			for (i = 0 ; i < arg_p[1].data.str.data; i++) {
2520 				if (*end == arg_p[1].data.str.area[i]) {
2521 					if (field == arg_p[0].data.sint) {
2522 						if (count == 1)
2523 							goto found;
2524 						else if (count > 1)
2525 							count--;
2526 					} else {
2527 						start = end+1;
2528 						field++;
2529 					}
2530 					break;
2531 				}
2532 			}
2533 			end++;
2534 		}
2535 	}
2536 
2537 	/* Field not found */
2538 	if (field != arg_p[0].data.sint) {
2539 		smp->data.u.str.data = 0;
2540 		return 0;
2541 	}
2542 found:
2543 	smp->data.u.str.data = end - start;
2544 	/* If ret string is len 0, no need to
2545            change pointers or to update size */
2546 	if (!smp->data.u.str.data)
2547 		return 1;
2548 
2549 	/* Compute remaining size if needed
2550            Note: smp->data.u.str.size cannot be set to 0 */
2551 	if (smp->data.u.str.size)
2552 		smp->data.u.str.size -= start - smp->data.u.str.area;
2553 
2554 	smp->data.u.str.area = start;
2555 
2556 	return 1;
2557 }
2558 
2559 /* This sample function is designed to return a word from a string.
2560  * First arg is the index of the word (start at 1)
2561  * Second arg is a char list of words separators (type string)
2562  */
sample_conv_word(const struct arg * arg_p,struct sample * smp,void * private)2563 static int sample_conv_word(const struct arg *arg_p, struct sample *smp, void *private)
2564 {
2565 	int word;
2566 	char *start, *end;
2567 	int i, issep, inword;
2568 	int count = (arg_p[2].type == ARGT_SINT) ? arg_p[2].data.sint : 1;
2569 
2570 	if (!arg_p[0].data.sint)
2571 		return 0;
2572 
2573 	word = 0;
2574 	inword = 0;
2575 	if (arg_p[0].data.sint < 0) {
2576 		end = start = smp->data.u.str.area + smp->data.u.str.data;
2577 		while (start > smp->data.u.str.area) {
2578 			issep = 0;
2579 			for (i = 0 ; i < arg_p[1].data.str.data; i++) {
2580 				if (*(start-1) == arg_p[1].data.str.area[i]) {
2581 					issep = 1;
2582 					break;
2583 				}
2584 			}
2585 			if (!inword) {
2586 				if (!issep) {
2587 					if (word != arg_p[0].data.sint) {
2588 						word--;
2589 						end = start;
2590 					}
2591 					inword = 1;
2592 				}
2593 			}
2594 			else if (issep) {
2595 				if (word == arg_p[0].data.sint) {
2596 					if (count == 1)
2597 						goto found;
2598 					else if (count > 1)
2599 						count--;
2600 				}
2601 				inword = 0;
2602 			}
2603 			start--;
2604 		}
2605 	} else {
2606 		end = start = smp->data.u.str.area;
2607 		while (end - smp->data.u.str.area < smp->data.u.str.data) {
2608 			issep = 0;
2609 			for (i = 0 ; i < arg_p[1].data.str.data; i++) {
2610 				if (*end == arg_p[1].data.str.area[i]) {
2611 					issep = 1;
2612 					break;
2613 				}
2614 			}
2615 			if (!inword) {
2616 				if (!issep) {
2617 					if (word != arg_p[0].data.sint) {
2618 						word++;
2619 						start = end;
2620 					}
2621 					inword = 1;
2622 				}
2623 			}
2624 			else if (issep) {
2625 				if (word == arg_p[0].data.sint) {
2626 					if (count == 1)
2627 						goto found;
2628 					else if (count > 1)
2629 						count--;
2630 				}
2631 				inword = 0;
2632 			}
2633 			end++;
2634 		}
2635 	}
2636 
2637 	/* Field not found */
2638 	if (word != arg_p[0].data.sint) {
2639 		smp->data.u.str.data = 0;
2640 		return 1;
2641 	}
2642 found:
2643 	smp->data.u.str.data = end - start;
2644 	/* If ret string is len 0, no need to
2645            change pointers or to update size */
2646 	if (!smp->data.u.str.data)
2647 		return 1;
2648 
2649 	smp->data.u.str.area = start;
2650 
2651 	/* Compute remaining size if needed
2652            Note: smp->data.u.str.size cannot be set to 0 */
2653 	if (smp->data.u.str.size)
2654 		smp->data.u.str.size -= start - smp->data.u.str.area;
2655 
2656 	return 1;
2657 }
2658 
sample_conv_regsub_check(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)2659 static int sample_conv_regsub_check(struct arg *args, struct sample_conv *conv,
2660                                     const char *file, int line, char **err)
2661 {
2662 	struct arg *arg = args;
2663 	char *p;
2664 	int len;
2665 
2666 	/* arg0 is a regex, it uses type_flag for ICASE and global match */
2667 	arg[0].type_flags = 0;
2668 
2669 	if (arg[2].type != ARGT_STR)
2670 		return 1;
2671 
2672 	p = arg[2].data.str.area;
2673 	len = arg[2].data.str.data;
2674 	while (len) {
2675 		if (*p == 'i') {
2676 			arg[0].type_flags |= ARGF_REG_ICASE;
2677 		}
2678 		else if (*p == 'g') {
2679 			arg[0].type_flags |= ARGF_REG_GLOB;
2680 		}
2681 		else {
2682 			memprintf(err, "invalid regex flag '%c', only 'i' and 'g' are supported", *p);
2683 			return 0;
2684 		}
2685 		p++;
2686 		len--;
2687 	}
2688 	return 1;
2689 }
2690 
2691 /* This sample function is designed to do the equivalent of s/match/replace/ on
2692  * the input string. It applies a regex and restarts from the last matched
2693  * location until nothing matches anymore. First arg is the regex to apply to
2694  * the input string, second arg is the replacement expression.
2695  */
sample_conv_regsub(const struct arg * arg_p,struct sample * smp,void * private)2696 static int sample_conv_regsub(const struct arg *arg_p, struct sample *smp, void *private)
2697 {
2698 	char *start, *end;
2699 	struct my_regex *reg = arg_p[0].data.reg;
2700 	regmatch_t pmatch[MAX_MATCH];
2701 	struct buffer *trash = get_trash_chunk();
2702 	struct buffer *output;
2703 	int flag, max;
2704 	int found;
2705 
2706 	start = smp->data.u.str.area;
2707 	end = start + smp->data.u.str.data;
2708 
2709 	flag = 0;
2710 	while (1) {
2711 		/* check for last round which is used to copy remaining parts
2712 		 * when not running in global replacement mode.
2713 		 */
2714 		found = 0;
2715 		if ((arg_p[0].type_flags & ARGF_REG_GLOB) || !(flag & REG_NOTBOL)) {
2716 			/* Note: we can have start == end on empty strings or at the end */
2717 			found = regex_exec_match2(reg, start, end - start, MAX_MATCH, pmatch, flag);
2718 		}
2719 
2720 		if (!found)
2721 			pmatch[0].rm_so = end - start;
2722 
2723 		/* copy the heading non-matching part (which may also be the tail if nothing matches) */
2724 		max = trash->size - trash->data;
2725 		if (max && pmatch[0].rm_so > 0) {
2726 			if (max > pmatch[0].rm_so)
2727 				max = pmatch[0].rm_so;
2728 			memcpy(trash->area + trash->data, start, max);
2729 			trash->data += max;
2730 		}
2731 
2732 		if (!found)
2733 			break;
2734 
2735 		output = alloc_trash_chunk();
2736 		if (!output)
2737 			break;
2738 
2739 		output->data = exp_replace(output->area, output->size, start, arg_p[1].data.str.area, pmatch);
2740 
2741 		/* replace the matching part */
2742 		max = output->size - output->data;
2743 		if (max) {
2744 			if (max > output->data)
2745 				max = output->data;
2746 			memcpy(trash->area + trash->data,
2747 			       output->area, max);
2748 			trash->data += max;
2749 		}
2750 
2751 		free_trash_chunk(output);
2752 
2753 		/* stop here if we're done with this string */
2754 		if (start >= end)
2755 			break;
2756 
2757 		/* We have a special case for matches of length 0 (eg: "x*y*").
2758 		 * These ones are considered to match in front of a character,
2759 		 * so we have to copy that character and skip to the next one.
2760 		 */
2761 		if (!pmatch[0].rm_eo) {
2762 			if (trash->data < trash->size)
2763 				trash->area[trash->data++] = start[pmatch[0].rm_eo];
2764 			pmatch[0].rm_eo++;
2765 		}
2766 
2767 		start += pmatch[0].rm_eo;
2768 		flag |= REG_NOTBOL;
2769 	}
2770 
2771 	smp->data.u.str = *trash;
2772 	return 1;
2773 }
2774 
2775 /* This function check an operator entry. It expects a string.
2776  * The string can be an integer or a variable name.
2777  */
check_operator(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)2778 static int check_operator(struct arg *args, struct sample_conv *conv,
2779                           const char *file, int line, char **err)
2780 {
2781 	const char *str;
2782 	const char *end;
2783 	long long int i;
2784 
2785 	/* Try to decode a variable. */
2786 	if (vars_check_arg(&args[0], NULL))
2787 		return 1;
2788 
2789 	/* Try to convert an integer */
2790 	str = args[0].data.str.area;
2791 	end = str + strlen(str);
2792 	i = read_int64(&str, end);
2793 	if (*str != '\0') {
2794 		memprintf(err, "expects an integer or a variable name");
2795 		return 0;
2796 	}
2797 
2798 	chunk_destroy(&args[0].data.str);
2799 	args[0].type = ARGT_SINT;
2800 	args[0].data.sint = i;
2801 	return 1;
2802 }
2803 
2804 /* This function returns a sample struct filled with an arg content.
2805  * If the arg contain an integer, the integer is returned in the
2806  * sample. If the arg contains a variable descriptor, it returns the
2807  * variable value.
2808  *
2809  * This function returns 0 if an error occurs, otherwise it returns 1.
2810  */
sample_conv_var2smp_sint(const struct arg * arg,struct sample * smp)2811 int sample_conv_var2smp_sint(const struct arg *arg, struct sample *smp)
2812 {
2813 	switch (arg->type) {
2814 	case ARGT_SINT:
2815 		smp->data.type = SMP_T_SINT;
2816 		smp->data.u.sint = arg->data.sint;
2817 		return 1;
2818 	case ARGT_VAR:
2819 		return sample_conv_var2smp(&arg->data.var, smp, SMP_T_SINT);
2820 	default:
2821 		return 0;
2822 	}
2823 }
2824 
2825 /* Takes a SINT on input, applies a binary twos complement and returns the SINT
2826  * result.
2827  */
sample_conv_binary_cpl(const struct arg * arg_p,struct sample * smp,void * private)2828 static int sample_conv_binary_cpl(const struct arg *arg_p, struct sample *smp, void *private)
2829 {
2830 	smp->data.u.sint = ~smp->data.u.sint;
2831 	return 1;
2832 }
2833 
2834 /* Takes a SINT on input, applies a binary "and" with the SINT directly in
2835  * arg_p or in the variable described in arg_p, and returns the SINT result.
2836  */
sample_conv_binary_and(const struct arg * arg_p,struct sample * smp,void * private)2837 static int sample_conv_binary_and(const struct arg *arg_p, struct sample *smp, void *private)
2838 {
2839 	struct sample tmp;
2840 
2841 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
2842 	if (!sample_conv_var2smp_sint(arg_p, &tmp))
2843 		return 0;
2844 	smp->data.u.sint &= tmp.data.u.sint;
2845 	return 1;
2846 }
2847 
2848 /* Takes a SINT on input, applies a binary "or" with the SINT directly in
2849  * arg_p or in the variable described in arg_p, and returns the SINT result.
2850  */
sample_conv_binary_or(const struct arg * arg_p,struct sample * smp,void * private)2851 static int sample_conv_binary_or(const struct arg *arg_p, struct sample *smp, void *private)
2852 {
2853 	struct sample tmp;
2854 
2855 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
2856 	if (!sample_conv_var2smp_sint(arg_p, &tmp))
2857 		return 0;
2858 	smp->data.u.sint |= tmp.data.u.sint;
2859 	return 1;
2860 }
2861 
2862 /* Takes a SINT on input, applies a binary "xor" with the SINT directly in
2863  * arg_p or in the variable described in arg_p, and returns the SINT result.
2864  */
sample_conv_binary_xor(const struct arg * arg_p,struct sample * smp,void * private)2865 static int sample_conv_binary_xor(const struct arg *arg_p, struct sample *smp, void *private)
2866 {
2867 	struct sample tmp;
2868 
2869 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
2870 	if (!sample_conv_var2smp_sint(arg_p, &tmp))
2871 		return 0;
2872 	smp->data.u.sint ^= tmp.data.u.sint;
2873 	return 1;
2874 }
2875 
arith_add(long long int a,long long int b)2876 static inline long long int arith_add(long long int a, long long int b)
2877 {
2878 	/* Prevent overflow and makes capped calculus.
2879 	 * We must ensure that the check calculus doesn't
2880 	 * exceed the signed 64 bits limits.
2881 	 *
2882 	 *        +----------+----------+
2883 	 *        |   a<0    |   a>=0   |
2884 	 * +------+----------+----------+
2885 	 * | b<0  | MIN-a>b  | no check |
2886 	 * +------+----------+----------+
2887 	 * | b>=0 | no check | MAX-a<b  |
2888 	 * +------+----------+----------+
2889 	 */
2890 	if ((a ^ b) >= 0) {
2891 		/* signs are different. */
2892 		if (a < 0) {
2893 			if (LLONG_MIN - a > b)
2894 				return LLONG_MIN;
2895 		}
2896 		if (LLONG_MAX - a < b)
2897 			return LLONG_MAX;
2898 	}
2899 	return a + b;
2900 }
2901 
2902 /* Takes a SINT on input, applies an arithmetic "add" with the SINT directly in
2903  * arg_p or in the variable described in arg_p, and returns the SINT result.
2904  */
sample_conv_arith_add(const struct arg * arg_p,struct sample * smp,void * private)2905 static int sample_conv_arith_add(const struct arg *arg_p, struct sample *smp, void *private)
2906 {
2907 	struct sample tmp;
2908 
2909 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
2910 	if (!sample_conv_var2smp_sint(arg_p, &tmp))
2911 		return 0;
2912 	smp->data.u.sint = arith_add(smp->data.u.sint, tmp.data.u.sint);
2913 	return 1;
2914 }
2915 
2916 /* Takes a SINT on input, applies an arithmetic "sub" with the SINT directly in
2917  * arg_p or in the variable described in arg_p, and returns the SINT result.
2918  */
sample_conv_arith_sub(const struct arg * arg_p,struct sample * smp,void * private)2919 static int sample_conv_arith_sub(const struct arg *arg_p,
2920                                  struct sample *smp, void *private)
2921 {
2922 	struct sample tmp;
2923 
2924 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
2925 	if (!sample_conv_var2smp_sint(arg_p, &tmp))
2926 		return 0;
2927 
2928 	/* We cannot represent -LLONG_MIN because abs(LLONG_MIN) is greater
2929 	 * than abs(LLONG_MAX). So, the following code use LLONG_MAX in place
2930 	 * of -LLONG_MIN and correct the result.
2931 	 */
2932 	if (tmp.data.u.sint == LLONG_MIN) {
2933 		smp->data.u.sint = arith_add(smp->data.u.sint, LLONG_MAX);
2934 		if (smp->data.u.sint < LLONG_MAX)
2935 			smp->data.u.sint++;
2936 		return 1;
2937 	}
2938 
2939 	/* standard subtraction: we use the "add" function and negate
2940 	 * the second operand.
2941 	 */
2942 	smp->data.u.sint = arith_add(smp->data.u.sint, -tmp.data.u.sint);
2943 	return 1;
2944 }
2945 
2946 /* Takes a SINT on input, applies an arithmetic "mul" with the SINT directly in
2947  * arg_p or in the variable described in arg_p, and returns the SINT result.
2948  * If the result makes an overflow, then the largest possible quantity is
2949  * returned.
2950  */
sample_conv_arith_mul(const struct arg * arg_p,struct sample * smp,void * private)2951 static int sample_conv_arith_mul(const struct arg *arg_p,
2952                                  struct sample *smp, void *private)
2953 {
2954 	struct sample tmp;
2955 	long long int c;
2956 
2957 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
2958 	if (!sample_conv_var2smp_sint(arg_p, &tmp))
2959 		return 0;
2960 
2961 	/* prevent divide by 0 during the check */
2962 	if (!smp->data.u.sint || !tmp.data.u.sint) {
2963 		smp->data.u.sint = 0;
2964 		return 1;
2965 	}
2966 
2967 	/* The multiply between LLONG_MIN and -1 returns a
2968 	 * "floating point exception".
2969 	 */
2970 	if (smp->data.u.sint == LLONG_MIN && tmp.data.u.sint == -1) {
2971 		smp->data.u.sint = LLONG_MAX;
2972 		return 1;
2973 	}
2974 
2975 	/* execute standard multiplication. */
2976 	c = smp->data.u.sint * tmp.data.u.sint;
2977 
2978 	/* check for overflow and makes capped multiply. */
2979 	if (smp->data.u.sint != c / tmp.data.u.sint) {
2980 		if ((smp->data.u.sint < 0) == (tmp.data.u.sint < 0)) {
2981 			smp->data.u.sint = LLONG_MAX;
2982 			return 1;
2983 		}
2984 		smp->data.u.sint = LLONG_MIN;
2985 		return 1;
2986 	}
2987 	smp->data.u.sint = c;
2988 	return 1;
2989 }
2990 
2991 /* Takes a SINT on input, applies an arithmetic "div" with the SINT directly in
2992  * arg_p or in the variable described in arg_p, and returns the SINT result.
2993  * If arg_p makes the result overflow, then the largest possible quantity is
2994  * returned.
2995  */
sample_conv_arith_div(const struct arg * arg_p,struct sample * smp,void * private)2996 static int sample_conv_arith_div(const struct arg *arg_p,
2997                                  struct sample *smp, void *private)
2998 {
2999 	struct sample tmp;
3000 
3001 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
3002 	if (!sample_conv_var2smp_sint(arg_p, &tmp))
3003 		return 0;
3004 
3005 	if (tmp.data.u.sint) {
3006 		/* The divide between LLONG_MIN and -1 returns a
3007 		 * "floating point exception".
3008 		 */
3009 		if (smp->data.u.sint == LLONG_MIN && tmp.data.u.sint == -1) {
3010 			smp->data.u.sint = LLONG_MAX;
3011 			return 1;
3012 		}
3013 		smp->data.u.sint /= tmp.data.u.sint;
3014 		return 1;
3015 	}
3016 	smp->data.u.sint = LLONG_MAX;
3017 	return 1;
3018 }
3019 
3020 /* Takes a SINT on input, applies an arithmetic "mod" with the SINT directly in
3021  * arg_p or in the variable described in arg_p, and returns the SINT result.
3022  * If arg_p makes the result overflow, then 0 is returned.
3023  */
sample_conv_arith_mod(const struct arg * arg_p,struct sample * smp,void * private)3024 static int sample_conv_arith_mod(const struct arg *arg_p,
3025                                  struct sample *smp, void *private)
3026 {
3027 	struct sample tmp;
3028 
3029 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
3030 	if (!sample_conv_var2smp_sint(arg_p, &tmp))
3031 		return 0;
3032 
3033 	if (tmp.data.u.sint) {
3034 		/* The divide between LLONG_MIN and -1 returns a
3035 		 * "floating point exception".
3036 		 */
3037 		if (smp->data.u.sint == LLONG_MIN && tmp.data.u.sint == -1) {
3038 			smp->data.u.sint = 0;
3039 			return 1;
3040 		}
3041 		smp->data.u.sint %= tmp.data.u.sint;
3042 		return 1;
3043 	}
3044 	smp->data.u.sint = 0;
3045 	return 1;
3046 }
3047 
3048 /* Takes an SINT on input, applies an arithmetic "neg" and returns the SINT
3049  * result.
3050  */
sample_conv_arith_neg(const struct arg * arg_p,struct sample * smp,void * private)3051 static int sample_conv_arith_neg(const struct arg *arg_p,
3052                                  struct sample *smp, void *private)
3053 {
3054 	if (smp->data.u.sint == LLONG_MIN)
3055 		smp->data.u.sint = LLONG_MAX;
3056 	else
3057 		smp->data.u.sint = -smp->data.u.sint;
3058 	return 1;
3059 }
3060 
3061 /* Takes a SINT on input, returns true is the value is non-null, otherwise
3062  * false. The output is a BOOL.
3063  */
sample_conv_arith_bool(const struct arg * arg_p,struct sample * smp,void * private)3064 static int sample_conv_arith_bool(const struct arg *arg_p,
3065                                   struct sample *smp, void *private)
3066 {
3067 	smp->data.u.sint = !!smp->data.u.sint;
3068 	smp->data.type = SMP_T_BOOL;
3069 	return 1;
3070 }
3071 
3072 /* Takes a SINT on input, returns false is the value is non-null, otherwise
3073  * truee. The output is a BOOL.
3074  */
sample_conv_arith_not(const struct arg * arg_p,struct sample * smp,void * private)3075 static int sample_conv_arith_not(const struct arg *arg_p,
3076                                  struct sample *smp, void *private)
3077 {
3078 	smp->data.u.sint = !smp->data.u.sint;
3079 	smp->data.type = SMP_T_BOOL;
3080 	return 1;
3081 }
3082 
3083 /* Takes a SINT on input, returns true is the value is odd, otherwise false.
3084  * The output is a BOOL.
3085  */
sample_conv_arith_odd(const struct arg * arg_p,struct sample * smp,void * private)3086 static int sample_conv_arith_odd(const struct arg *arg_p,
3087                                  struct sample *smp, void *private)
3088 {
3089 	smp->data.u.sint = smp->data.u.sint & 1;
3090 	smp->data.type = SMP_T_BOOL;
3091 	return 1;
3092 }
3093 
3094 /* Takes a SINT on input, returns true is the value is even, otherwise false.
3095  * The output is a BOOL.
3096  */
sample_conv_arith_even(const struct arg * arg_p,struct sample * smp,void * private)3097 static int sample_conv_arith_even(const struct arg *arg_p,
3098                                   struct sample *smp, void *private)
3099 {
3100 	smp->data.u.sint = !(smp->data.u.sint & 1);
3101 	smp->data.type = SMP_T_BOOL;
3102 	return 1;
3103 }
3104 
3105 /* appends an optional const string, an optional variable contents and another
3106  * optional const string to an existing string.
3107  */
sample_conv_concat(const struct arg * arg_p,struct sample * smp,void * private)3108 static int sample_conv_concat(const struct arg *arg_p, struct sample *smp, void *private)
3109 {
3110 	struct buffer *trash;
3111 	struct sample tmp;
3112 	int max;
3113 
3114 	trash = alloc_trash_chunk();
3115 	if (!trash)
3116 		return 0;
3117 
3118 	trash->data = smp->data.u.str.data;
3119 	if (trash->data > trash->size - 1)
3120 		trash->data = trash->size - 1;
3121 
3122 	memcpy(trash->area, smp->data.u.str.area, trash->data);
3123 	trash->area[trash->data] = 0;
3124 
3125 	/* append first string */
3126 	max = arg_p[0].data.str.data;
3127 	if (max > trash->size - 1 - trash->data)
3128 		max = trash->size - 1 - trash->data;
3129 
3130 	if (max) {
3131 		memcpy(trash->area + trash->data, arg_p[0].data.str.area, max);
3132 		trash->data += max;
3133 		trash->area[trash->data] = 0;
3134 	}
3135 
3136 	/* append second string (variable) if it's found and we can turn it
3137 	 * into a string.
3138 	 */
3139 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
3140 	if (arg_p[1].type == ARGT_VAR && vars_get_by_desc(&arg_p[1].data.var, &tmp) &&
3141 	    (sample_casts[tmp.data.type][SMP_T_STR] == c_none ||
3142 	     sample_casts[tmp.data.type][SMP_T_STR](&tmp))) {
3143 
3144 		max = tmp.data.u.str.data;
3145 		if (max > trash->size - 1 - trash->data)
3146 			max = trash->size - 1 - trash->data;
3147 
3148 		if (max) {
3149 			memcpy(trash->area + trash->data, tmp.data.u.str.area,
3150 			       max);
3151 			trash->data += max;
3152 			trash->area[trash->data] = 0;
3153 		}
3154 	}
3155 
3156 	/* append third string */
3157 	max = arg_p[2].data.str.data;
3158 	if (max > trash->size - 1 - trash->data)
3159 		max = trash->size - 1 - trash->data;
3160 
3161 	if (max) {
3162 		memcpy(trash->area + trash->data, arg_p[2].data.str.area, max);
3163 		trash->data += max;
3164 		trash->area[trash->data] = 0;
3165 	}
3166 
3167 	smp->data.u.str = *trash;
3168 	smp->data.type = SMP_T_STR;
3169 	smp_dup(smp);
3170 	free_trash_chunk(trash);
3171 	return 1;
3172 }
3173 
3174 /* This function checks the "concat" converter's arguments and extracts the
3175  * variable name and its scope.
3176  */
smp_check_concat(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)3177 static int smp_check_concat(struct arg *args, struct sample_conv *conv,
3178                            const char *file, int line, char **err)
3179 {
3180 	/* Try to decode a variable. */
3181 	if (args[1].data.str.data > 0 && !vars_check_arg(&args[1], NULL)) {
3182 		memprintf(err, "failed to register variable name '%s'",
3183 			  args[1].data.str.area);
3184 		return 0;
3185 	}
3186 	return 1;
3187 }
3188 
3189 /* Compares string with a variable containing a string. Return value
3190  * is compatible with strcmp(3)'s return value.
3191  */
sample_conv_strcmp(const struct arg * arg_p,struct sample * smp,void * private)3192 static int sample_conv_strcmp(const struct arg *arg_p, struct sample *smp, void *private)
3193 {
3194 	struct sample tmp;
3195 	int max, result;
3196 
3197 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
3198 	if (arg_p[0].type != ARGT_VAR)
3199 		return 0;
3200 
3201 	if (!sample_conv_var2smp(&arg_p[0].data.var, &tmp, SMP_T_STR))
3202 		return 0;
3203 
3204 	max = MIN(smp->data.u.str.data, tmp.data.u.str.data);
3205 	result = strncmp(smp->data.u.str.area, tmp.data.u.str.area, max);
3206 	if (result == 0) {
3207 		if (smp->data.u.str.data != tmp.data.u.str.data) {
3208 			if (smp->data.u.str.data < tmp.data.u.str.data) {
3209 				result = -1;
3210 			}
3211 			else {
3212 				result = 1;
3213 			}
3214 		}
3215 	}
3216 
3217 	smp->data.u.sint = result;
3218 	smp->data.type = SMP_T_SINT;
3219 	return 1;
3220 }
3221 
3222 #ifdef USE_OPENSSL
3223 /* Compares bytestring with a variable containing a bytestring. Return value
3224  * is `true` if both bytestrings are bytewise identical and `false` otherwise.
3225  *
3226  * Comparison will be performed in constant time if both bytestrings are of
3227  * the same length. If the lengths differ execution time will not be constant.
3228  */
sample_conv_secure_memcmp(const struct arg * arg_p,struct sample * smp,void * private)3229 static int sample_conv_secure_memcmp(const struct arg *arg_p, struct sample *smp, void *private)
3230 {
3231 	struct sample tmp;
3232 	int result;
3233 
3234 	smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
3235 	if (arg_p[0].type != ARGT_VAR)
3236 		return 0;
3237 
3238 	if (!sample_conv_var2smp(&arg_p[0].data.var, &tmp, SMP_T_BIN))
3239 		return 0;
3240 
3241 	if (smp->data.u.str.data != tmp.data.u.str.data) {
3242 		smp->data.u.sint = 0;
3243 		smp->data.type = SMP_T_BOOL;
3244 		return 1;
3245 	}
3246 
3247 	/* The following comparison is performed in constant time. */
3248 	result = CRYPTO_memcmp(smp->data.u.str.area, tmp.data.u.str.area, smp->data.u.str.data);
3249 
3250 	smp->data.u.sint = result == 0;
3251 	smp->data.type = SMP_T_BOOL;
3252 	return 1;
3253 }
3254 #endif
3255 
3256 /* Takes a boolean as input. Returns the first argument if that boolean is true and
3257  * the second argument otherwise.
3258  */
sample_conv_iif(const struct arg * arg_p,struct sample * smp,void * private)3259 static int sample_conv_iif(const struct arg *arg_p, struct sample *smp, void *private)
3260 {
3261 	smp->data.type = SMP_T_STR;
3262 	smp->flags |= SMP_F_CONST;
3263 
3264 	if (smp->data.u.sint) {
3265 		smp->data.u.str.data = arg_p[0].data.str.data;
3266 		smp->data.u.str.area = arg_p[0].data.str.area;
3267 	}
3268 	else {
3269 		smp->data.u.str.data = arg_p[1].data.str.data;
3270 		smp->data.u.str.area = arg_p[1].data.str.area;
3271 	}
3272 
3273 	return 1;
3274 }
3275 
3276 #define GRPC_MSG_COMPRESS_FLAG_SZ 1 /* 1 byte */
3277 #define GRPC_MSG_LENGTH_SZ        4 /* 4 bytes */
3278 #define GRPC_MSG_HEADER_SZ        (GRPC_MSG_COMPRESS_FLAG_SZ + GRPC_MSG_LENGTH_SZ)
3279 
3280 /*
3281  * Extract the field value of an input binary sample. Takes a mandatory argument:
3282  * the protocol buffers field identifier (dotted notation) internally represented
3283  * as an array of unsigned integers and its size.
3284  * Return 1 if the field was found, 0 if not.
3285  */
sample_conv_ungrpc(const struct arg * arg_p,struct sample * smp,void * private)3286 static int sample_conv_ungrpc(const struct arg *arg_p, struct sample *smp, void *private)
3287 {
3288 	unsigned char *pos;
3289 	size_t grpc_left;
3290 
3291 	pos = (unsigned char *)smp->data.u.str.area;
3292 	grpc_left = smp->data.u.str.data;
3293 
3294 	while (grpc_left > GRPC_MSG_HEADER_SZ) {
3295 		size_t grpc_msg_len, left;
3296 
3297 		grpc_msg_len = left = ntohl(*(uint32_t *)(pos + GRPC_MSG_COMPRESS_FLAG_SZ));
3298 
3299 		pos += GRPC_MSG_HEADER_SZ;
3300 		grpc_left -= GRPC_MSG_HEADER_SZ;
3301 
3302 		if (grpc_left < left)
3303 			return 0;
3304 
3305 		if (protobuf_field_lookup(arg_p, smp, &pos, &left))
3306 			return 1;
3307 
3308 		grpc_left -= grpc_msg_len;
3309 	}
3310 
3311 	return 0;
3312 }
3313 
sample_conv_protobuf(const struct arg * arg_p,struct sample * smp,void * private)3314 static int sample_conv_protobuf(const struct arg *arg_p, struct sample *smp, void *private)
3315 {
3316 	unsigned char *pos;
3317 	size_t left;
3318 
3319 	pos = (unsigned char *)smp->data.u.str.area;
3320 	left = smp->data.u.str.data;
3321 
3322 	return protobuf_field_lookup(arg_p, smp, &pos, &left);
3323 }
3324 
sample_conv_protobuf_check(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)3325 static int sample_conv_protobuf_check(struct arg *args, struct sample_conv *conv,
3326                                       const char *file, int line, char **err)
3327 {
3328 	if (!args[1].type) {
3329 		args[1].type = ARGT_SINT;
3330 		args[1].data.sint = PBUF_T_BINARY;
3331 	}
3332 	else {
3333 		int pbuf_type;
3334 
3335 		pbuf_type = protobuf_type(args[1].data.str.area);
3336 		if (pbuf_type == -1) {
3337 			memprintf(err, "Wrong protocol buffer type '%s'", args[1].data.str.area);
3338 			return 0;
3339 		}
3340 
3341 		chunk_destroy(&args[1].data.str);
3342 		args[1].type = ARGT_SINT;
3343 		args[1].data.sint = pbuf_type;
3344 	}
3345 
3346 	return 1;
3347 }
3348 
3349 /* This function checks the "strcmp" converter's arguments and extracts the
3350  * variable name and its scope.
3351  */
smp_check_strcmp(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)3352 static int smp_check_strcmp(struct arg *args, struct sample_conv *conv,
3353                            const char *file, int line, char **err)
3354 {
3355 	/* Try to decode a variable. */
3356 	if (vars_check_arg(&args[0], NULL))
3357 		return 1;
3358 
3359 	memprintf(err, "failed to register variable name '%s'",
3360 		  args[0].data.str.area);
3361 	return 0;
3362 }
3363 
3364 #ifdef USE_OPENSSL
3365 /* This function checks the "secure_memcmp" converter's arguments and extracts the
3366  * variable name and its scope.
3367  */
smp_check_secure_memcmp(struct arg * args,struct sample_conv * conv,const char * file,int line,char ** err)3368 static int smp_check_secure_memcmp(struct arg *args, struct sample_conv *conv,
3369                            const char *file, int line, char **err)
3370 {
3371 	/* Try to decode a variable. */
3372 	if (vars_check_arg(&args[0], NULL))
3373 		return 1;
3374 
3375 	memprintf(err, "failed to register variable name '%s'",
3376 		  args[0].data.str.area);
3377 	return 0;
3378 }
3379 #endif
3380 
3381 /**/
sample_conv_htonl(const struct arg * arg_p,struct sample * smp,void * private)3382 static int sample_conv_htonl(const struct arg *arg_p, struct sample *smp, void *private)
3383 {
3384 	struct buffer *tmp;
3385 	uint32_t n;
3386 
3387 	n = htonl((uint32_t)smp->data.u.sint);
3388 	tmp = get_trash_chunk();
3389 
3390 	memcpy(b_head(tmp), &n, 4);
3391 	b_add(tmp, 4);
3392 
3393 	smp->data.u.str = *tmp;
3394 	smp->data.type = SMP_T_BIN;
3395 	return 1;
3396 }
3397 
3398 /**/
sample_conv_cut_crlf(const struct arg * arg_p,struct sample * smp,void * private)3399 static int sample_conv_cut_crlf(const struct arg *arg_p, struct sample *smp, void *private)
3400 {
3401 	char *p;
3402 	size_t l;
3403 
3404 	p = smp->data.u.str.area;
3405 	for (l = 0; l < smp->data.u.str.data; l++) {
3406 		if (*(p+l) == '\r' || *(p+l) == '\n')
3407 			break;
3408 	}
3409 	smp->data.u.str.data = l;
3410 	return 1;
3411 }
3412 
3413 /**/
sample_conv_ltrim(const struct arg * arg_p,struct sample * smp,void * private)3414 static int sample_conv_ltrim(const struct arg *arg_p, struct sample *smp, void *private)
3415 {
3416 	char *delimiters, *p;
3417 	size_t dlen, l;
3418 
3419 	delimiters =  arg_p[0].data.str.area;
3420 	dlen = arg_p[0].data.str.data;
3421 
3422 	l = smp->data.u.str.data;
3423 	p = smp->data.u.str.area;
3424 	while (l && memchr(delimiters, *p, dlen) != NULL) {
3425 		p++;
3426 		l--;
3427 	}
3428 
3429 	smp->data.u.str.area = p;
3430 	smp->data.u.str.data = l;
3431 	return 1;
3432 }
3433 
3434 /**/
sample_conv_rtrim(const struct arg * arg_p,struct sample * smp,void * private)3435 static int sample_conv_rtrim(const struct arg *arg_p, struct sample *smp, void *private)
3436 {
3437 	char *delimiters, *p;
3438 	size_t dlen, l;
3439 
3440 	delimiters =  arg_p[0].data.str.area;
3441 	dlen = arg_p[0].data.str.data;
3442 
3443 	l = smp->data.u.str.data;
3444 	p = smp->data.u.str.area + l - 1;
3445 	while (l && memchr(delimiters, *p, dlen) != NULL) {
3446 		p--;
3447 		l--;
3448 	}
3449 
3450 	smp->data.u.str.data = l;
3451 	return 1;
3452 }
3453 
3454 /************************************************************************/
3455 /*       All supported sample fetch functions must be declared here     */
3456 /************************************************************************/
3457 
3458 /* force TRUE to be returned at the fetch level */
3459 static int
smp_fetch_true(const struct arg * args,struct sample * smp,const char * kw,void * private)3460 smp_fetch_true(const struct arg *args, struct sample *smp, const char *kw, void *private)
3461 {
3462 	if (!smp_make_rw(smp))
3463 		return 0;
3464 
3465 	smp->data.type = SMP_T_BOOL;
3466 	smp->data.u.sint = 1;
3467 	return 1;
3468 }
3469 
3470 /* force FALSE to be returned at the fetch level */
3471 static int
smp_fetch_false(const struct arg * args,struct sample * smp,const char * kw,void * private)3472 smp_fetch_false(const struct arg *args, struct sample *smp, const char *kw, void *private)
3473 {
3474 	smp->data.type = SMP_T_BOOL;
3475 	smp->data.u.sint = 0;
3476 	return 1;
3477 }
3478 
3479 /* retrieve environment variable $1 as a string */
3480 static int
smp_fetch_env(const struct arg * args,struct sample * smp,const char * kw,void * private)3481 smp_fetch_env(const struct arg *args, struct sample *smp, const char *kw, void *private)
3482 {
3483 	char *env;
3484 
3485 	if (!args || args[0].type != ARGT_STR)
3486 		return 0;
3487 
3488 	env = getenv(args[0].data.str.area);
3489 	if (!env)
3490 		return 0;
3491 
3492 	smp->data.type = SMP_T_STR;
3493 	smp->flags = SMP_F_CONST;
3494 	smp->data.u.str.area = env;
3495 	smp->data.u.str.data = strlen(env);
3496 	return 1;
3497 }
3498 
3499 /* Validates the data unit argument passed to "date" fetch. Argument 1 support an
3500  * optional string representing the unit of the result: "s" for seconds, "ms" for
3501  * milliseconds and "us" for microseconds.
3502  * Returns 0 on error and non-zero if OK.
3503  */
smp_check_date_unit(struct arg * args,char ** err)3504 int smp_check_date_unit(struct arg *args, char **err)
3505 {
3506         if (args[1].type == ARGT_STR) {
3507 		long long int unit;
3508 
3509                 if (strcmp(args[1].data.str.area, "s") == 0) {
3510                         unit = TIME_UNIT_S;
3511                 }
3512                 else if (strcmp(args[1].data.str.area, "ms") == 0) {
3513                         unit = TIME_UNIT_MS;
3514                 }
3515                 else if (strcmp(args[1].data.str.area, "us") == 0) {
3516                         unit = TIME_UNIT_US;
3517                 }
3518                 else {
3519                         memprintf(err, "expects 's', 'ms' or 'us', got '%s'",
3520                                   args[1].data.str.area);
3521                         return 0;
3522                 }
3523 
3524 		chunk_destroy(&args[1].data.str);
3525                 args[1].type = ARGT_SINT;
3526 		args[1].data.sint = unit;
3527         }
3528         else if (args[1].type != ARGT_STOP) {
3529                 memprintf(err, "Unexpected arg type");
3530                 return 0;
3531         }
3532 
3533         return 1;
3534 }
3535 
3536 /* retrieve the current local date in epoch time, converts it to milliseconds
3537  * or microseconds if asked to in optional args[1] unit param, and applies an
3538  * optional args[0] offset.
3539  */
3540 static int
smp_fetch_date(const struct arg * args,struct sample * smp,const char * kw,void * private)3541 smp_fetch_date(const struct arg *args, struct sample *smp, const char *kw, void *private)
3542 {
3543 	smp->data.u.sint = date.tv_sec;
3544 
3545 	/* report in milliseconds */
3546 	if (args && args[1].type == ARGT_SINT && args[1].data.sint == TIME_UNIT_MS) {
3547 		smp->data.u.sint *= 1000;
3548 		smp->data.u.sint += date.tv_usec / 1000;
3549 	}
3550 	/* report in microseconds */
3551 	else if (args && args[1].type == ARGT_SINT && args[1].data.sint == TIME_UNIT_US) {
3552 		smp->data.u.sint *= 1000000;
3553 		smp->data.u.sint += date.tv_usec;
3554 	}
3555 
3556 	/* add offset */
3557 	if (args && args[0].type == ARGT_SINT)
3558 		smp->data.u.sint += args[0].data.sint;
3559 
3560 	smp->data.type = SMP_T_SINT;
3561 	smp->flags |= SMP_F_VOL_TEST | SMP_F_MAY_CHANGE;
3562 	return 1;
3563 }
3564 
3565 /* retrieve the current microsecond part of the date  */
3566 static int
smp_fetch_date_us(const struct arg * args,struct sample * smp,const char * kw,void * private)3567 smp_fetch_date_us(const struct arg *args, struct sample *smp, const char *kw, void *private)
3568 {
3569 	smp->data.u.sint = date.tv_usec;
3570 	smp->data.type = SMP_T_SINT;
3571 	smp->flags |= SMP_F_VOL_TEST | SMP_F_MAY_CHANGE;
3572 	return 1;
3573 }
3574 
3575 
3576 /* returns the hostname */
3577 static int
smp_fetch_hostname(const struct arg * args,struct sample * smp,const char * kw,void * private)3578 smp_fetch_hostname(const struct arg *args, struct sample *smp, const char *kw, void *private)
3579 {
3580 	smp->data.type = SMP_T_STR;
3581 	smp->flags = SMP_F_CONST;
3582 	smp->data.u.str.area = hostname;
3583 	smp->data.u.str.data = strlen(hostname);
3584 	return 1;
3585 }
3586 
3587 /* returns the number of processes */
3588 static int
smp_fetch_nbproc(const struct arg * args,struct sample * smp,const char * kw,void * private)3589 smp_fetch_nbproc(const struct arg *args, struct sample *smp, const char *kw, void *private)
3590 {
3591 	smp->data.type = SMP_T_SINT;
3592 	smp->data.u.sint = global.nbproc;
3593 	return 1;
3594 }
3595 
3596 /* returns the number of the current process (between 1 and nbproc */
3597 static int
smp_fetch_proc(const struct arg * args,struct sample * smp,const char * kw,void * private)3598 smp_fetch_proc(const struct arg *args, struct sample *smp, const char *kw, void *private)
3599 {
3600 	smp->data.type = SMP_T_SINT;
3601 	smp->data.u.sint = relative_pid;
3602 	return 1;
3603 }
3604 
3605 /* returns the number of the current thread (between 1 and nbthread */
3606 static int
smp_fetch_thread(const struct arg * args,struct sample * smp,const char * kw,void * private)3607 smp_fetch_thread(const struct arg *args, struct sample *smp, const char *kw, void *private)
3608 {
3609 	smp->data.type = SMP_T_SINT;
3610 	smp->data.u.sint = tid;
3611 	return 1;
3612 }
3613 
3614 /* generate a random 32-bit integer for whatever purpose, with an optional
3615  * range specified in argument.
3616  */
3617 static int
smp_fetch_rand(const struct arg * args,struct sample * smp,const char * kw,void * private)3618 smp_fetch_rand(const struct arg *args, struct sample *smp, const char *kw, void *private)
3619 {
3620 	smp->data.u.sint = ha_random32();
3621 
3622 	/* reduce if needed. Don't do a modulo, use all bits! */
3623 	if (args && args[0].type == ARGT_SINT)
3624 		smp->data.u.sint = ((u64)smp->data.u.sint * (u64)args[0].data.sint) >> 32;
3625 
3626 	smp->data.type = SMP_T_SINT;
3627 	smp->flags |= SMP_F_VOL_TEST | SMP_F_MAY_CHANGE;
3628 	return 1;
3629 }
3630 
3631 /* returns true if the current process is stopping */
3632 static int
smp_fetch_stopping(const struct arg * args,struct sample * smp,const char * kw,void * private)3633 smp_fetch_stopping(const struct arg *args, struct sample *smp, const char *kw, void *private)
3634 {
3635 	smp->data.type = SMP_T_BOOL;
3636 	smp->data.u.sint = stopping;
3637 	return 1;
3638 }
3639 
3640 /* returns the number of calls of the current stream's process_stream() */
3641 static int
smp_fetch_cpu_calls(const struct arg * args,struct sample * smp,const char * kw,void * private)3642 smp_fetch_cpu_calls(const struct arg *args, struct sample *smp, const char *kw, void *private)
3643 {
3644 	if (!smp->strm)
3645 		return 0;
3646 
3647 	smp->data.type = SMP_T_SINT;
3648 	smp->data.u.sint = smp->strm->task->calls;
3649 	return 1;
3650 }
3651 
3652 /* returns the average number of nanoseconds spent processing the stream per call */
3653 static int
smp_fetch_cpu_ns_avg(const struct arg * args,struct sample * smp,const char * kw,void * private)3654 smp_fetch_cpu_ns_avg(const struct arg *args, struct sample *smp, const char *kw, void *private)
3655 {
3656 	if (!smp->strm)
3657 		return 0;
3658 
3659 	smp->data.type = SMP_T_SINT;
3660 	smp->data.u.sint = smp->strm->task->calls ? smp->strm->task->cpu_time / smp->strm->task->calls : 0;
3661 	return 1;
3662 }
3663 
3664 /* returns the total number of nanoseconds spent processing the stream */
3665 static int
smp_fetch_cpu_ns_tot(const struct arg * args,struct sample * smp,const char * kw,void * private)3666 smp_fetch_cpu_ns_tot(const struct arg *args, struct sample *smp, const char *kw, void *private)
3667 {
3668 	if (!smp->strm)
3669 		return 0;
3670 
3671 	smp->data.type = SMP_T_SINT;
3672 	smp->data.u.sint = smp->strm->task->cpu_time;
3673 	return 1;
3674 }
3675 
3676 /* returns the average number of nanoseconds per call spent waiting for other tasks to be processed */
3677 static int
smp_fetch_lat_ns_avg(const struct arg * args,struct sample * smp,const char * kw,void * private)3678 smp_fetch_lat_ns_avg(const struct arg *args, struct sample *smp, const char *kw, void *private)
3679 {
3680 	if (!smp->strm)
3681 		return 0;
3682 
3683 	smp->data.type = SMP_T_SINT;
3684 	smp->data.u.sint = smp->strm->task->calls ? smp->strm->task->lat_time / smp->strm->task->calls : 0;
3685 	return 1;
3686 }
3687 
3688 /* returns the total number of nanoseconds per call spent waiting for other tasks to be processed */
3689 static int
smp_fetch_lat_ns_tot(const struct arg * args,struct sample * smp,const char * kw,void * private)3690 smp_fetch_lat_ns_tot(const struct arg *args, struct sample *smp, const char *kw, void *private)
3691 {
3692 	if (!smp->strm)
3693 		return 0;
3694 
3695 	smp->data.type = SMP_T_SINT;
3696 	smp->data.u.sint = smp->strm->task->lat_time;
3697 	return 1;
3698 }
3699 
smp_fetch_const_str(const struct arg * args,struct sample * smp,const char * kw,void * private)3700 static int smp_fetch_const_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
3701 {
3702 	smp->flags |= SMP_F_CONST;
3703 	smp->data.type = SMP_T_STR;
3704 	smp->data.u.str.area = args[0].data.str.area;
3705 	smp->data.u.str.data = args[0].data.str.data;
3706 	return 1;
3707 }
3708 
smp_check_const_bool(struct arg * args,char ** err)3709 static int smp_check_const_bool(struct arg *args, char **err)
3710 {
3711 	if (strcasecmp(args[0].data.str.area, "true") == 0 ||
3712 	    strcasecmp(args[0].data.str.area, "1") == 0) {
3713 		chunk_destroy(&args[0].data.str);
3714 		args[0].type = ARGT_SINT;
3715 		args[0].data.sint = 1;
3716 		return 1;
3717 	}
3718 	if (strcasecmp(args[0].data.str.area, "false") == 0 ||
3719 	    strcasecmp(args[0].data.str.area, "0") == 0) {
3720 		chunk_destroy(&args[0].data.str);
3721 		args[0].type = ARGT_SINT;
3722 		args[0].data.sint = 0;
3723 		return 1;
3724 	}
3725 	memprintf(err, "Expects 'true', 'false', '0' or '1'");
3726 	return 0;
3727 }
3728 
smp_fetch_const_bool(const struct arg * args,struct sample * smp,const char * kw,void * private)3729 static int smp_fetch_const_bool(const struct arg *args, struct sample *smp, const char *kw, void *private)
3730 {
3731 	smp->data.type = SMP_T_BOOL;
3732 	smp->data.u.sint = args[0].data.sint;
3733 	return 1;
3734 }
3735 
smp_fetch_const_int(const struct arg * args,struct sample * smp,const char * kw,void * private)3736 static int smp_fetch_const_int(const struct arg *args, struct sample *smp, const char *kw, void *private)
3737 {
3738 	smp->data.type = SMP_T_SINT;
3739 	smp->data.u.sint = args[0].data.sint;
3740 	return 1;
3741 }
3742 
smp_fetch_const_ipv4(const struct arg * args,struct sample * smp,const char * kw,void * private)3743 static int smp_fetch_const_ipv4(const struct arg *args, struct sample *smp, const char *kw, void *private)
3744 {
3745 	smp->data.type = SMP_T_IPV4;
3746 	smp->data.u.ipv4 = args[0].data.ipv4;
3747 	return 1;
3748 }
3749 
smp_fetch_const_ipv6(const struct arg * args,struct sample * smp,const char * kw,void * private)3750 static int smp_fetch_const_ipv6(const struct arg *args, struct sample *smp, const char *kw, void *private)
3751 {
3752 	smp->data.type = SMP_T_IPV6;
3753 	smp->data.u.ipv6 = args[0].data.ipv6;
3754 	return 1;
3755 }
3756 
smp_check_const_bin(struct arg * args,char ** err)3757 static int smp_check_const_bin(struct arg *args, char **err)
3758 {
3759 	char *binstr = NULL;
3760 	int binstrlen;
3761 
3762 	if (!parse_binary(args[0].data.str.area, &binstr, &binstrlen, err))
3763 		return 0;
3764 	chunk_destroy(&args[0].data.str);
3765 	args[0].type = ARGT_STR;
3766 	args[0].data.str.area = binstr;
3767 	args[0].data.str.data = binstrlen;
3768 	return 1;
3769 }
3770 
smp_fetch_const_bin(const struct arg * args,struct sample * smp,const char * kw,void * private)3771 static int smp_fetch_const_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
3772 {
3773 	smp->flags |= SMP_F_CONST;
3774 	smp->data.type = SMP_T_BIN;
3775 	smp->data.u.str.area = args[0].data.str.area;
3776 	smp->data.u.str.data = args[0].data.str.data;
3777 	return 1;
3778 }
3779 
smp_check_const_meth(struct arg * args,char ** err)3780 static int smp_check_const_meth(struct arg *args, char **err)
3781 {
3782 	enum http_meth_t meth;
3783 	int i;
3784 
3785 	meth = find_http_meth(args[0].data.str.area, args[0].data.str.data);
3786 	if (meth != HTTP_METH_OTHER) {
3787 		chunk_destroy(&args[0].data.str);
3788 		args[0].type = ARGT_SINT;
3789 		args[0].data.sint = meth;
3790 	} else {
3791 		/* Check method avalaibility. A method is a token defined as :
3792 		 * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
3793 		 *         "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
3794 		 * token = 1*tchar
3795 		 */
3796 		for (i = 0; i < args[0].data.str.data; i++) {
3797 			if (!HTTP_IS_TOKEN(args[0].data.str.area[i])) {
3798 				memprintf(err, "expects valid method.");
3799 				return 0;
3800 			}
3801 		}
3802 	}
3803 	return 1;
3804 }
3805 
smp_fetch_const_meth(const struct arg * args,struct sample * smp,const char * kw,void * private)3806 static int smp_fetch_const_meth(const struct arg *args, struct sample *smp, const char *kw, void *private)
3807 {
3808 	smp->data.type = SMP_T_METH;
3809 	if (args[0].type == ARGT_SINT) {
3810 		smp->flags &= ~SMP_F_CONST;
3811 		smp->data.u.meth.meth = args[0].data.sint;
3812 		smp->data.u.meth.str.area = "";
3813 		smp->data.u.meth.str.data = 0;
3814 	} else {
3815 		smp->flags |= SMP_F_CONST;
3816 		smp->data.u.meth.meth = HTTP_METH_OTHER;
3817 		smp->data.u.meth.str.area = args[0].data.str.area;
3818 		smp->data.u.meth.str.data = args[0].data.str.data;
3819 	}
3820 	return 1;
3821 }
3822 
3823 // This function checks the "uuid" sample's arguments.
3824 // Function won't get called when no parameter is specified (maybe a bug?)
smp_check_uuid(struct arg * args,char ** err)3825 static int smp_check_uuid(struct arg *args, char **err)
3826 {
3827 	if (!args[0].type) {
3828 		args[0].type = ARGT_SINT;
3829 		args[0].data.sint = 4;
3830 	}
3831 	else if (args[0].data.sint != 4) {
3832 		memprintf(err, "Unsupported UUID version: '%lld'", args[0].data.sint);
3833 		return 0;
3834 	}
3835 
3836 	return 1;
3837 }
3838 
3839 // Generate a RFC4122 UUID (default is v4 = fully random)
smp_fetch_uuid(const struct arg * args,struct sample * smp,const char * kw,void * private)3840 static int smp_fetch_uuid(const struct arg *args, struct sample *smp, const char *kw, void *private)
3841 {
3842 	if (args[0].data.sint == 4 || !args[0].type) {
3843 		ha_generate_uuid(&trash);
3844 		smp->data.type = SMP_T_STR;
3845 		smp->flags = SMP_F_VOL_TEST | SMP_F_MAY_CHANGE;
3846 		smp->data.u.str = trash;
3847 		return 1;
3848 	}
3849 
3850 	// more implementations of other uuid formats possible here
3851 	return 0;
3852 }
3853 
3854 /* Note: must not be declared <const> as its list will be overwritten.
3855  * Note: fetches that may return multiple types must be declared as the lowest
3856  * common denominator, the type that can be casted into all other ones. For
3857  * instance IPv4/IPv6 must be declared IPv4.
3858  */
3859 static struct sample_fetch_kw_list smp_kws = {ILH, {
3860 	{ "always_false", smp_fetch_false, 0,            NULL, SMP_T_BOOL, SMP_USE_INTRN },
3861 	{ "always_true",  smp_fetch_true,  0,            NULL, SMP_T_BOOL, SMP_USE_INTRN },
3862 	{ "env",          smp_fetch_env,   ARG1(1,STR),  NULL, SMP_T_STR,  SMP_USE_INTRN },
3863 	{ "date",         smp_fetch_date,  ARG2(0,SINT,STR), smp_check_date_unit, SMP_T_SINT, SMP_USE_INTRN },
3864 	{ "date_us",      smp_fetch_date_us,  0,         NULL, SMP_T_SINT, SMP_USE_INTRN },
3865 	{ "hostname",     smp_fetch_hostname, 0,         NULL, SMP_T_STR,  SMP_USE_INTRN },
3866 	{ "nbproc",       smp_fetch_nbproc,0,            NULL, SMP_T_SINT, SMP_USE_INTRN },
3867 	{ "proc",         smp_fetch_proc,  0,            NULL, SMP_T_SINT, SMP_USE_INTRN },
3868 	{ "thread",       smp_fetch_thread,  0,          NULL, SMP_T_SINT, SMP_USE_INTRN },
3869 	{ "rand",         smp_fetch_rand,  ARG1(0,SINT), NULL, SMP_T_SINT, SMP_USE_INTRN },
3870 	{ "stopping",     smp_fetch_stopping, 0,         NULL, SMP_T_BOOL, SMP_USE_INTRN },
3871 	{ "stopping",     smp_fetch_stopping, 0,         NULL, SMP_T_BOOL, SMP_USE_INTRN },
3872 	{ "uuid",         smp_fetch_uuid,  ARG1(0, SINT),      smp_check_uuid, SMP_T_STR, SMP_USE_INTRN },
3873 
3874 	{ "cpu_calls",    smp_fetch_cpu_calls,  0,       NULL, SMP_T_SINT, SMP_USE_INTRN },
3875 	{ "cpu_ns_avg",   smp_fetch_cpu_ns_avg, 0,       NULL, SMP_T_SINT, SMP_USE_INTRN },
3876 	{ "cpu_ns_tot",   smp_fetch_cpu_ns_tot, 0,       NULL, SMP_T_SINT, SMP_USE_INTRN },
3877 	{ "lat_ns_avg",   smp_fetch_lat_ns_avg, 0,       NULL, SMP_T_SINT, SMP_USE_INTRN },
3878 	{ "lat_ns_tot",   smp_fetch_lat_ns_tot, 0,       NULL, SMP_T_SINT, SMP_USE_INTRN },
3879 
3880 	{ "str",  smp_fetch_const_str,  ARG1(1,STR),  NULL                , SMP_T_STR,  SMP_USE_INTRN },
3881 	{ "bool", smp_fetch_const_bool, ARG1(1,STR),  smp_check_const_bool, SMP_T_BOOL, SMP_USE_INTRN },
3882 	{ "int",  smp_fetch_const_int,  ARG1(1,SINT), NULL                , SMP_T_SINT, SMP_USE_INTRN },
3883 	{ "ipv4", smp_fetch_const_ipv4, ARG1(1,IPV4), NULL                , SMP_T_IPV4, SMP_USE_INTRN },
3884 	{ "ipv6", smp_fetch_const_ipv6, ARG1(1,IPV6), NULL                , SMP_T_IPV6, SMP_USE_INTRN },
3885 	{ "bin",  smp_fetch_const_bin,  ARG1(1,STR),  smp_check_const_bin , SMP_T_BIN,  SMP_USE_INTRN },
3886 	{ "meth", smp_fetch_const_meth, ARG1(1,STR),  smp_check_const_meth, SMP_T_METH, SMP_USE_INTRN },
3887 
3888 	{ /* END */ },
3889 }};
3890 
3891 INITCALL1(STG_REGISTER, sample_register_fetches, &smp_kws);
3892 
3893 /* Note: must not be declared <const> as its list will be overwritten */
3894 static struct sample_conv_kw_list sample_conv_kws = {ILH, {
3895 	{ "debug",  sample_conv_debug,     ARG2(0,STR,STR), smp_check_debug, SMP_T_ANY,  SMP_T_ANY },
3896 	{ "b64dec", sample_conv_base642bin,0,            NULL, SMP_T_STR,  SMP_T_BIN  },
3897 	{ "base64", sample_conv_bin2base64,0,            NULL, SMP_T_BIN,  SMP_T_STR  },
3898 	{ "upper",  sample_conv_str2upper, 0,            NULL, SMP_T_STR,  SMP_T_STR  },
3899 	{ "lower",  sample_conv_str2lower, 0,            NULL, SMP_T_STR,  SMP_T_STR  },
3900 	{ "length", sample_conv_length,    0,            NULL, SMP_T_STR,  SMP_T_SINT },
3901 	{ "hex",    sample_conv_bin2hex,   0,            NULL, SMP_T_BIN,  SMP_T_STR  },
3902 	{ "hex2i",  sample_conv_hex2int,   0,            NULL, SMP_T_STR,  SMP_T_SINT },
3903 	{ "ipmask", sample_conv_ipmask,    ARG2(1,MSK4,MSK6), NULL, SMP_T_ADDR, SMP_T_IPV4 },
3904 	{ "ltime",  sample_conv_ltime,     ARG2(1,STR,SINT), NULL, SMP_T_SINT, SMP_T_STR },
3905 	{ "utime",  sample_conv_utime,     ARG2(1,STR,SINT), NULL, SMP_T_SINT, SMP_T_STR },
3906 	{ "crc32",  sample_conv_crc32,     ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
3907 	{ "crc32c", sample_conv_crc32c,    ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
3908 	{ "djb2",   sample_conv_djb2,      ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
3909 	{ "sdbm",   sample_conv_sdbm,      ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
3910 	{ "wt6",    sample_conv_wt6,       ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
3911 	{ "xxh32",  sample_conv_xxh32,     ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
3912 	{ "xxh64",  sample_conv_xxh64,     ARG1(0,SINT), NULL, SMP_T_BIN,  SMP_T_SINT  },
3913 	{ "json",   sample_conv_json,      ARG1(1,STR),  sample_conv_json_check, SMP_T_STR,  SMP_T_STR },
3914 	{ "bytes",  sample_conv_bytes,     ARG2(1,SINT,SINT), NULL, SMP_T_BIN,  SMP_T_BIN },
3915 	{ "field",  sample_conv_field,     ARG3(2,SINT,STR,SINT), sample_conv_field_check, SMP_T_STR,  SMP_T_STR },
3916 	{ "word",   sample_conv_word,      ARG3(2,SINT,STR,SINT), sample_conv_field_check, SMP_T_STR,  SMP_T_STR },
3917 	{ "regsub", sample_conv_regsub,    ARG3(2,REG,STR,STR), sample_conv_regsub_check, SMP_T_STR, SMP_T_STR },
3918 	{ "sha1",   sample_conv_sha1,      0,            NULL, SMP_T_BIN,  SMP_T_BIN  },
3919 #ifdef USE_OPENSSL
3920 	{ "sha2",   sample_conv_sha2,      ARG1(0, SINT), smp_check_sha2, SMP_T_BIN,  SMP_T_BIN  },
3921 #if (HA_OPENSSL_VERSION_NUMBER >= 0x1000100fL)
3922 	{ "aes_gcm_dec", sample_conv_aes_gcm_dec,   ARG4(4,SINT,STR,STR,STR), check_aes_gcm,       SMP_T_BIN, SMP_T_BIN },
3923 #endif
3924 	{ "digest",      sample_conv_crypto_digest, ARG1(1,STR),              check_crypto_digest, SMP_T_BIN, SMP_T_BIN },
3925 	{ "hmac",        sample_conv_crypto_hmac,   ARG2(2,STR,STR),          check_crypto_hmac,   SMP_T_BIN, SMP_T_BIN },
3926 #endif
3927 	{ "concat", sample_conv_concat,    ARG3(1,STR,STR,STR), smp_check_concat, SMP_T_STR,  SMP_T_STR },
3928 	{ "strcmp", sample_conv_strcmp,    ARG1(1,STR), smp_check_strcmp, SMP_T_STR,  SMP_T_SINT },
3929 #ifdef USE_OPENSSL
3930 	{ "secure_memcmp", sample_conv_secure_memcmp,    ARG1(1,STR), smp_check_secure_memcmp, SMP_T_BIN,  SMP_T_BOOL },
3931 #endif
3932 
3933 	/* gRPC converters. */
3934 	{ "ungrpc", sample_conv_ungrpc,    ARG2(1,PBUF_FNUM,STR), sample_conv_protobuf_check, SMP_T_BIN, SMP_T_BIN  },
3935 	{ "protobuf", sample_conv_protobuf, ARG2(1,PBUF_FNUM,STR), sample_conv_protobuf_check, SMP_T_BIN, SMP_T_BIN  },
3936 
3937 	{ "iif", sample_conv_iif, ARG2(2, STR, STR), NULL, SMP_T_BOOL, SMP_T_STR },
3938 
3939 	{ "and",    sample_conv_binary_and, ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT  },
3940 	{ "or",     sample_conv_binary_or,  ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT  },
3941 	{ "xor",    sample_conv_binary_xor, ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT  },
3942 	{ "cpl",    sample_conv_binary_cpl,           0, NULL, SMP_T_SINT, SMP_T_SINT  },
3943 	{ "bool",   sample_conv_arith_bool,           0, NULL, SMP_T_SINT, SMP_T_BOOL },
3944 	{ "not",    sample_conv_arith_not,            0, NULL, SMP_T_SINT, SMP_T_BOOL },
3945 	{ "odd",    sample_conv_arith_odd,            0, NULL, SMP_T_SINT, SMP_T_BOOL },
3946 	{ "even",   sample_conv_arith_even,           0, NULL, SMP_T_SINT, SMP_T_BOOL },
3947 	{ "add",    sample_conv_arith_add,  ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT  },
3948 	{ "sub",    sample_conv_arith_sub,  ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT  },
3949 	{ "mul",    sample_conv_arith_mul,  ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT  },
3950 	{ "div",    sample_conv_arith_div,  ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT  },
3951 	{ "mod",    sample_conv_arith_mod,  ARG1(1,STR), check_operator, SMP_T_SINT, SMP_T_SINT  },
3952 	{ "neg",    sample_conv_arith_neg,            0, NULL, SMP_T_SINT, SMP_T_SINT  },
3953 
3954 	{ "htonl",    sample_conv_htonl,              0, NULL, SMP_T_SINT, SMP_T_BIN  },
3955 	{ "cut_crlf", sample_conv_cut_crlf,           0, NULL, SMP_T_STR,  SMP_T_STR  },
3956 	{ "ltrim",    sample_conv_ltrim,    ARG1(1,STR), NULL, SMP_T_STR,  SMP_T_STR  },
3957 	{ "rtrim",    sample_conv_rtrim,    ARG1(1,STR), NULL, SMP_T_STR,  SMP_T_STR  },
3958 	{ NULL, NULL, 0, 0, 0 },
3959 }};
3960 
3961 INITCALL1(STG_REGISTER, sample_register_convs, &sample_conv_kws);
3962