1d4afb5ceSopenharmony_ci/*
2d4afb5ceSopenharmony_ci * libwebsockets - small server side websockets and web server implementation
3d4afb5ceSopenharmony_ci *
4d4afb5ceSopenharmony_ci * Copyright (C) 2019 - 2021 Andy Green <andy@warmcat.com>
5d4afb5ceSopenharmony_ci *
6d4afb5ceSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy
7d4afb5ceSopenharmony_ci * of this software and associated documentation files (the "Software"), to
8d4afb5ceSopenharmony_ci * deal in the Software without restriction, including without limitation the
9d4afb5ceSopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10d4afb5ceSopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is
11d4afb5ceSopenharmony_ci * furnished to do so, subject to the following conditions:
12d4afb5ceSopenharmony_ci *
13d4afb5ceSopenharmony_ci * The above copyright notice and this permission notice shall be included in
14d4afb5ceSopenharmony_ci * all copies or substantial portions of the Software.
15d4afb5ceSopenharmony_ci *
16d4afb5ceSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17d4afb5ceSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18d4afb5ceSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19d4afb5ceSopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20d4afb5ceSopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21d4afb5ceSopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22d4afb5ceSopenharmony_ci * IN THE SOFTWARE.
23d4afb5ceSopenharmony_ci *
24d4afb5ceSopenharmony_ci * This file contains the stuff related to JSON-provided policy, it's not built
25d4afb5ceSopenharmony_ci * if LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY enabled.
26d4afb5ceSopenharmony_ci */
27d4afb5ceSopenharmony_ci
28d4afb5ceSopenharmony_ci#include <private-lib-core.h>
29d4afb5ceSopenharmony_ci
30d4afb5ceSopenharmony_cistatic const char * const lejp_tokens_policy[] = {
31d4afb5ceSopenharmony_ci	"release",
32d4afb5ceSopenharmony_ci	"product",
33d4afb5ceSopenharmony_ci	"schema-version",
34d4afb5ceSopenharmony_ci	"via-socks5",
35d4afb5ceSopenharmony_ci	"retry[].*.backoff",
36d4afb5ceSopenharmony_ci	"retry[].*.conceal",
37d4afb5ceSopenharmony_ci	"retry[].*.jitterpc",
38d4afb5ceSopenharmony_ci	"retry[].*.svalidping",
39d4afb5ceSopenharmony_ci	"retry[].*.svalidhup",
40d4afb5ceSopenharmony_ci	"retry[].*",
41d4afb5ceSopenharmony_ci	"certs[].*",
42d4afb5ceSopenharmony_ci	"trust_stores[].name",
43d4afb5ceSopenharmony_ci	"trust_stores[].stack",
44d4afb5ceSopenharmony_ci	"metrics[].name",
45d4afb5ceSopenharmony_ci	"metrics[].us_schedule",
46d4afb5ceSopenharmony_ci	"metrics[].us_halflife",
47d4afb5ceSopenharmony_ci	"metrics[].min_outlier",
48d4afb5ceSopenharmony_ci	"metrics[].report",
49d4afb5ceSopenharmony_ci	"s[].*.endpoint",
50d4afb5ceSopenharmony_ci	"s[].*.via-socks5",
51d4afb5ceSopenharmony_ci	"s[].*.protocol",
52d4afb5ceSopenharmony_ci	"s[].*.port",
53d4afb5ceSopenharmony_ci	"s[].*.plugins",
54d4afb5ceSopenharmony_ci	"s[].*.tls",
55d4afb5ceSopenharmony_ci	"s[].*.client_cert",
56d4afb5ceSopenharmony_ci	"s[].*.opportunistic",
57d4afb5ceSopenharmony_ci	"s[].*.nailed_up",
58d4afb5ceSopenharmony_ci	"s[].*.allow_redirects",
59d4afb5ceSopenharmony_ci	"s[].*.urgent_tx",
60d4afb5ceSopenharmony_ci	"s[].*.urgent_rx",
61d4afb5ceSopenharmony_ci	"s[].*.attr_priority",
62d4afb5ceSopenharmony_ci	"s[].*.attr_low_latency",
63d4afb5ceSopenharmony_ci	"s[].*.attr_high_throughput",
64d4afb5ceSopenharmony_ci	"s[].*.attr_high_reliability",
65d4afb5ceSopenharmony_ci	"s[].*.attr_low_cost",
66d4afb5ceSopenharmony_ci	"s[].*.long_poll",
67d4afb5ceSopenharmony_ci	"s[].*.ws_prioritize_reads",
68d4afb5ceSopenharmony_ci	"s[].*.retry",
69d4afb5ceSopenharmony_ci	"s[].*.timeout_ms",
70d4afb5ceSopenharmony_ci	"s[].*.perf",
71d4afb5ceSopenharmony_ci	"s[].*.tls_trust_store",
72d4afb5ceSopenharmony_ci	"s[].*.proxy_buflen",
73d4afb5ceSopenharmony_ci	"s[].*.proxy_buflen_rxflow_on_above",
74d4afb5ceSopenharmony_ci	"s[].*.proxy_buflen_rxflow_off_below",
75d4afb5ceSopenharmony_ci	"s[].*.client_buflen",
76d4afb5ceSopenharmony_ci	"s[].*.client_buflen_rxflow_on_above",
77d4afb5ceSopenharmony_ci	"s[].*.client_buflen_rxflow_off_below",
78d4afb5ceSopenharmony_ci	"s[].*.metadata",
79d4afb5ceSopenharmony_ci	"s[].*.metadata[].*",
80d4afb5ceSopenharmony_ci	"s[].*.http_resp_map",
81d4afb5ceSopenharmony_ci	"s[].*.http_resp_map[].*",
82d4afb5ceSopenharmony_ci
83d4afb5ceSopenharmony_ci	"s[].*.http_auth_header",
84d4afb5ceSopenharmony_ci	"s[].*.http_dsn_header",
85d4afb5ceSopenharmony_ci	"s[].*.http_fwv_header",
86d4afb5ceSopenharmony_ci	"s[].*.http_devtype_header",
87d4afb5ceSopenharmony_ci
88d4afb5ceSopenharmony_ci	"s[].*.http_auth_preamble",
89d4afb5ceSopenharmony_ci
90d4afb5ceSopenharmony_ci	"s[].*.http_no_content_length",
91d4afb5ceSopenharmony_ci	"s[].*.rideshare",	/* streamtype name this rides shotgun with */
92d4afb5ceSopenharmony_ci	"s[].*.payload_fmt",
93d4afb5ceSopenharmony_ci	"s[].*.http_method",
94d4afb5ceSopenharmony_ci	"s[].*.http_url",
95d4afb5ceSopenharmony_ci	"s[].*.nghttp2_quirk_end_stream",
96d4afb5ceSopenharmony_ci	"s[].*.h2q_oflow_txcr",
97d4afb5ceSopenharmony_ci	"s[].*.http_multipart_name",
98d4afb5ceSopenharmony_ci	"s[].*.http_multipart_filename",
99d4afb5ceSopenharmony_ci	"s[].*.http_mime_content_type",
100d4afb5ceSopenharmony_ci	"s[].*.http_www_form_urlencoded",
101d4afb5ceSopenharmony_ci	"s[].*.http_expect",
102d4afb5ceSopenharmony_ci	"s[].*.http_cookies",
103d4afb5ceSopenharmony_ci	"s[].*.http_fail_redirect",
104d4afb5ceSopenharmony_ci	"s[].*.http_multipart_ss_in",
105d4afb5ceSopenharmony_ci	"s[].*.ws_subprotocol",
106d4afb5ceSopenharmony_ci	"s[].*.ws_binary",
107d4afb5ceSopenharmony_ci	"s[].*.local_sink",
108d4afb5ceSopenharmony_ci	"s[].*.server",
109d4afb5ceSopenharmony_ci	"s[].*.server_cert",
110d4afb5ceSopenharmony_ci	"s[].*.server_key",
111d4afb5ceSopenharmony_ci	"s[].*.mqtt_topic",
112d4afb5ceSopenharmony_ci	"s[].*.mqtt_subscribe",
113d4afb5ceSopenharmony_ci	"s[].*.mqtt_qos",
114d4afb5ceSopenharmony_ci	"s[].*.mqtt_retain",
115d4afb5ceSopenharmony_ci	"s[].*.mqtt_keep_alive",
116d4afb5ceSopenharmony_ci	"s[].*.mqtt_clean_start",
117d4afb5ceSopenharmony_ci	"s[].*.mqtt_will_topic",
118d4afb5ceSopenharmony_ci	"s[].*.mqtt_will_message",
119d4afb5ceSopenharmony_ci	"s[].*.mqtt_will_qos",
120d4afb5ceSopenharmony_ci	"s[].*.mqtt_will_retain",
121d4afb5ceSopenharmony_ci	"s[].*.mqtt_birth_topic",
122d4afb5ceSopenharmony_ci	"s[].*.mqtt_birth_message",
123d4afb5ceSopenharmony_ci	"s[].*.mqtt_birth_qos",
124d4afb5ceSopenharmony_ci	"s[].*.mqtt_birth_retain",
125d4afb5ceSopenharmony_ci	"s[].*.aws_iot",
126d4afb5ceSopenharmony_ci	"s[].*.swake_validity",
127d4afb5ceSopenharmony_ci	"s[].*.use_auth",
128d4afb5ceSopenharmony_ci	"s[].*.aws_region",
129d4afb5ceSopenharmony_ci	"s[].*.aws_service",
130d4afb5ceSopenharmony_ci	"s[].*.direct_proto_str",
131d4afb5ceSopenharmony_ci	"s[].*",
132d4afb5ceSopenharmony_ci	"auth[].name",
133d4afb5ceSopenharmony_ci	"auth[].type",
134d4afb5ceSopenharmony_ci	"auth[].streamtype",
135d4afb5ceSopenharmony_ci	"auth[].blob",
136d4afb5ceSopenharmony_ci	"auth[]",
137d4afb5ceSopenharmony_ci};
138d4afb5ceSopenharmony_ci
139d4afb5ceSopenharmony_citypedef enum {
140d4afb5ceSopenharmony_ci	LSSPPT_RELEASE,
141d4afb5ceSopenharmony_ci	LSSPPT_PRODUCT,
142d4afb5ceSopenharmony_ci	LSSPPT_SCHEMA_VERSION,
143d4afb5ceSopenharmony_ci	LSSPPT_VIA_SOCKS5,
144d4afb5ceSopenharmony_ci	LSSPPT_BACKOFF,
145d4afb5ceSopenharmony_ci	LSSPPT_CONCEAL,
146d4afb5ceSopenharmony_ci	LSSPPT_JITTERPC,
147d4afb5ceSopenharmony_ci	LSSPPT_VALIDPING_S,
148d4afb5ceSopenharmony_ci	LSSPPT_VALIDHUP_S,
149d4afb5ceSopenharmony_ci	LSSPPT_RETRY,
150d4afb5ceSopenharmony_ci	LSSPPT_CERTS,
151d4afb5ceSopenharmony_ci	LSSPPT_TRUST_STORES_NAME,
152d4afb5ceSopenharmony_ci	LSSPPT_TRUST_STORES_STACK,
153d4afb5ceSopenharmony_ci	LSSPPT_METRICS_NAME,
154d4afb5ceSopenharmony_ci	LSSPPT_METRICS_US_SCHEDULE,
155d4afb5ceSopenharmony_ci	LSSPPT_METRICS_US_HALFLIFE,
156d4afb5ceSopenharmony_ci	LSSPPT_METRICS_MIN_OUTLIER,
157d4afb5ceSopenharmony_ci	LSSPPT_METRICS_REPORT,
158d4afb5ceSopenharmony_ci	LSSPPT_ENDPOINT,
159d4afb5ceSopenharmony_ci	LSSPPT_VH_VIA_SOCKS5,
160d4afb5ceSopenharmony_ci	LSSPPT_PROTOCOL,
161d4afb5ceSopenharmony_ci	LSSPPT_PORT,
162d4afb5ceSopenharmony_ci	LSSPPT_PLUGINS,
163d4afb5ceSopenharmony_ci	LSSPPT_TLS,
164d4afb5ceSopenharmony_ci	LSSPPT_TLS_CLIENT_CERT,
165d4afb5ceSopenharmony_ci	LSSPPT_OPPORTUNISTIC,
166d4afb5ceSopenharmony_ci	LSSPPT_NAILED_UP,
167d4afb5ceSopenharmony_ci	LSSPPT_ALLOW_REDIRECTS,
168d4afb5ceSopenharmony_ci	LSSPPT_URGENT_TX,
169d4afb5ceSopenharmony_ci	LSSPPT_URGENT_RX,
170d4afb5ceSopenharmony_ci	LSSPPT_ATTR_PRIORITY,
171d4afb5ceSopenharmony_ci	LSSPPT_ATTR_LOW_LATENCY,
172d4afb5ceSopenharmony_ci	LSSPPT_ATTR_HIGH_THROUGHPUT,
173d4afb5ceSopenharmony_ci	LSSPPT_ATTR_HIGH_RELIABILITY,
174d4afb5ceSopenharmony_ci	LSSPPT_ATTR_LOW_COST,
175d4afb5ceSopenharmony_ci	LSSPPT_LONG_POLL,
176d4afb5ceSopenharmony_ci	LSSPPT_PRIORITIZE_READS,
177d4afb5ceSopenharmony_ci	LSSPPT_RETRYPTR,
178d4afb5ceSopenharmony_ci	LSSPPT_DEFAULT_TIMEOUT_MS,
179d4afb5ceSopenharmony_ci	LSSPPT_PERF,
180d4afb5ceSopenharmony_ci	LSSPPT_TRUST,
181d4afb5ceSopenharmony_ci	LSSPPT_PROXY_BUFLEN,
182d4afb5ceSopenharmony_ci	LSSPPT_PROXY_BUFLEN_RXFLOW_ON_ABOVE,
183d4afb5ceSopenharmony_ci	LSSPPT_PROXY_BUFLEN_RXFLOW_OFF_BELOW,
184d4afb5ceSopenharmony_ci	LSSPPT_CLIENT_BUFLEN,
185d4afb5ceSopenharmony_ci	LSSPPT_CLIENT_BUFLEN_RXFLOW_ON_ABOVE,
186d4afb5ceSopenharmony_ci	LSSPPT_CLIENT_BUFLEN_RXFLOW_OFF_BELOW,
187d4afb5ceSopenharmony_ci	LSSPPT_METADATA,
188d4afb5ceSopenharmony_ci	LSSPPT_METADATA_ITEM,
189d4afb5ceSopenharmony_ci	LSSPPT_HTTPRESPMAP,
190d4afb5ceSopenharmony_ci	LSSPPT_HTTPRESPMAP_ITEM,
191d4afb5ceSopenharmony_ci
192d4afb5ceSopenharmony_ci	LSSPPT_HTTP_AUTH_HEADER,
193d4afb5ceSopenharmony_ci	LSSPPT_HTTP_DSN_HEADER,
194d4afb5ceSopenharmony_ci	LSSPPT_HTTP_FWV_HEADER,
195d4afb5ceSopenharmony_ci	LSSPPT_HTTP_TYPE_HEADER,
196d4afb5ceSopenharmony_ci
197d4afb5ceSopenharmony_ci	LSSPPT_HTTP_AUTH_PREAMBLE,
198d4afb5ceSopenharmony_ci	LSSPPT_HTTP_NO_CONTENT_LENGTH,
199d4afb5ceSopenharmony_ci	LSSPPT_RIDESHARE,
200d4afb5ceSopenharmony_ci	LSSPPT_PAYLOAD_FORMAT,
201d4afb5ceSopenharmony_ci	LSSPPT_HTTP_METHOD,
202d4afb5ceSopenharmony_ci	LSSPPT_HTTP_URL,
203d4afb5ceSopenharmony_ci	LSSPPT_NGHTTP2_QUIRK_END_STREAM,
204d4afb5ceSopenharmony_ci	LSSPPT_H2_QUIRK_OVERFLOWS_TXCR,
205d4afb5ceSopenharmony_ci	LSSPPT_HTTP_MULTIPART_NAME,
206d4afb5ceSopenharmony_ci	LSSPPT_HTTP_MULTIPART_FILENAME,
207d4afb5ceSopenharmony_ci	LSSPPT_HTTP_MULTIPART_CONTENT_TYPE,
208d4afb5ceSopenharmony_ci	LSSPPT_HTTP_WWW_FORM_URLENCODED,
209d4afb5ceSopenharmony_ci	LSSPPT_HTTP_EXPECT,
210d4afb5ceSopenharmony_ci	LSSPPT_HTTP_COOKIES,
211d4afb5ceSopenharmony_ci	LSSPPT_HTTP_FAIL_REDIRECT,
212d4afb5ceSopenharmony_ci	LSSPPT_HTTP_MULTIPART_SS_IN,
213d4afb5ceSopenharmony_ci	LSSPPT_WS_SUBPROTOCOL,
214d4afb5ceSopenharmony_ci	LSSPPT_WS_BINARY,
215d4afb5ceSopenharmony_ci	LSSPPT_LOCAL_SINK,
216d4afb5ceSopenharmony_ci	LSSPPT_SERVER,
217d4afb5ceSopenharmony_ci	LSSPPT_SERVER_CERT,
218d4afb5ceSopenharmony_ci	LSSPPT_SERVER_KEY,
219d4afb5ceSopenharmony_ci	LSSPPT_MQTT_TOPIC,
220d4afb5ceSopenharmony_ci	LSSPPT_MQTT_SUBSCRIBE,
221d4afb5ceSopenharmony_ci	LSSPPT_MQTT_QOS,
222d4afb5ceSopenharmony_ci	LSSPPT_MQTT_RETAIN,
223d4afb5ceSopenharmony_ci	LSSPPT_MQTT_KEEPALIVE,
224d4afb5ceSopenharmony_ci	LSSPPT_MQTT_CLEAN_START,
225d4afb5ceSopenharmony_ci	LSSPPT_MQTT_WILL_TOPIC,
226d4afb5ceSopenharmony_ci	LSSPPT_MQTT_WILL_MESSAGE,
227d4afb5ceSopenharmony_ci	LSSPPT_MQTT_WILL_QOS,
228d4afb5ceSopenharmony_ci	LSSPPT_MQTT_WILL_RETAIN,
229d4afb5ceSopenharmony_ci	LSSPPT_MQTT_BIRTH_TOPIC,
230d4afb5ceSopenharmony_ci	LSSPPT_MQTT_BIRTH_MESSAGE,
231d4afb5ceSopenharmony_ci	LSSPPT_MQTT_BIRTH_QOS,
232d4afb5ceSopenharmony_ci	LSSPPT_MQTT_BIRTH_RETAIN,
233d4afb5ceSopenharmony_ci	LSSPPT_MQTT_AWS_IOT,
234d4afb5ceSopenharmony_ci	LSSPPT_SWAKE_VALIDITY,
235d4afb5ceSopenharmony_ci	LSSPPT_USE_AUTH,
236d4afb5ceSopenharmony_ci	LSSPPT_AWS_REGION,
237d4afb5ceSopenharmony_ci	LSSPPT_AWS_SERVICE,
238d4afb5ceSopenharmony_ci	LSSPPT_DIRECT_PROTO_STR,
239d4afb5ceSopenharmony_ci	LSSPPT_STREAMTYPES,
240d4afb5ceSopenharmony_ci	LSSPPT_AUTH_NAME,
241d4afb5ceSopenharmony_ci	LSSPPT_AUTH_TYPE,
242d4afb5ceSopenharmony_ci	LSSPPT_AUTH_STREAMTYPE,
243d4afb5ceSopenharmony_ci	LSSPPT_AUTH_BLOB,
244d4afb5ceSopenharmony_ci	LSSPPT_AUTH,
245d4afb5ceSopenharmony_ci
246d4afb5ceSopenharmony_ci} policy_token_t;
247d4afb5ceSopenharmony_ci
248d4afb5ceSopenharmony_ci#define POL_AC_INITIAL	2048
249d4afb5ceSopenharmony_ci#define POL_AC_GRAIN	800
250d4afb5ceSopenharmony_ci#define MAX_CERT_TEMP	3072 /* used to discover actual cert size for realloc */
251d4afb5ceSopenharmony_ci
252d4afb5ceSopenharmony_cistatic uint16_t sizes[] = {
253d4afb5ceSopenharmony_ci	sizeof(backoff_t),
254d4afb5ceSopenharmony_ci	sizeof(lws_ss_x509_t),
255d4afb5ceSopenharmony_ci	sizeof(lws_ss_trust_store_t),
256d4afb5ceSopenharmony_ci	sizeof(lws_ss_policy_t),
257d4afb5ceSopenharmony_ci	sizeof(lws_ss_auth_t),
258d4afb5ceSopenharmony_ci	sizeof(lws_metric_policy_t),
259d4afb5ceSopenharmony_ci};
260d4afb5ceSopenharmony_ci
261d4afb5ceSopenharmony_cistatic const char * const protonames[] = {
262d4afb5ceSopenharmony_ci	"h1",		/* LWSSSP_H1 */
263d4afb5ceSopenharmony_ci	"h2",		/* LWSSSP_H2 */
264d4afb5ceSopenharmony_ci	"ws",		/* LWSSSP_WS */
265d4afb5ceSopenharmony_ci	"mqtt",		/* LWSSSP_MQTT */
266d4afb5ceSopenharmony_ci	"raw",		/* LWSSSP_RAW */
267d4afb5ceSopenharmony_ci};
268d4afb5ceSopenharmony_ci
269d4afb5ceSopenharmony_cistatic const lws_ss_auth_t *
270d4afb5ceSopenharmony_cilws_ss_policy_find_auth_by_name(struct policy_cb_args *a,
271d4afb5ceSopenharmony_ci				const char *name, size_t len)
272d4afb5ceSopenharmony_ci{
273d4afb5ceSopenharmony_ci	const lws_ss_auth_t *auth = a->heads[LTY_AUTH].a;
274d4afb5ceSopenharmony_ci
275d4afb5ceSopenharmony_ci	while (auth) {
276d4afb5ceSopenharmony_ci		if (auth->name &&
277d4afb5ceSopenharmony_ci		    len == strlen(auth->name) &&
278d4afb5ceSopenharmony_ci		    !strncmp(auth->name, name, len))
279d4afb5ceSopenharmony_ci			return auth;
280d4afb5ceSopenharmony_ci
281d4afb5ceSopenharmony_ci		auth = auth->next;
282d4afb5ceSopenharmony_ci	}
283d4afb5ceSopenharmony_ci
284d4afb5ceSopenharmony_ci	return NULL;
285d4afb5ceSopenharmony_ci}
286d4afb5ceSopenharmony_ci
287d4afb5ceSopenharmony_cistatic int
288d4afb5ceSopenharmony_cilws_ss_policy_alloc_helper(struct policy_cb_args *a, int type)
289d4afb5ceSopenharmony_ci{
290d4afb5ceSopenharmony_ci	/*
291d4afb5ceSopenharmony_ci	 * We do the pointers always as .b union member, all of the
292d4afb5ceSopenharmony_ci	 * participating structs begin with .next and .name the same
293d4afb5ceSopenharmony_ci	 */
294d4afb5ceSopenharmony_ci
295d4afb5ceSopenharmony_ci	a->curr[type].b = lwsac_use_zero(&a->ac,
296d4afb5ceSopenharmony_ci				sizes[type], POL_AC_GRAIN);
297d4afb5ceSopenharmony_ci	if (!a->curr[type].b)
298d4afb5ceSopenharmony_ci		return 1;
299d4afb5ceSopenharmony_ci
300d4afb5ceSopenharmony_ci	a->curr[type].b->next = a->heads[type].b;
301d4afb5ceSopenharmony_ci	a->heads[type].b = a->curr[type].b;
302d4afb5ceSopenharmony_ci
303d4afb5ceSopenharmony_ci	return 0;
304d4afb5ceSopenharmony_ci}
305d4afb5ceSopenharmony_ci
306d4afb5ceSopenharmony_cistatic signed char
307d4afb5ceSopenharmony_cilws_ss_policy_parser_cb(struct lejp_ctx *ctx, char reason)
308d4afb5ceSopenharmony_ci{
309d4afb5ceSopenharmony_ci	struct policy_cb_args *a = (struct policy_cb_args *)ctx->user;
310d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SSPLUGINS)
311d4afb5ceSopenharmony_ci	const lws_ss_plugin_t **pin;
312d4afb5ceSopenharmony_ci#endif
313d4afb5ceSopenharmony_ci	char **pp, dotstar[32], *q;
314d4afb5ceSopenharmony_ci	lws_ss_trust_store_t *ts;
315d4afb5ceSopenharmony_ci	lws_ss_metadata_t *pmd;
316d4afb5ceSopenharmony_ci	lws_ss_x509_t *x, **py;
317d4afb5ceSopenharmony_ci	lws_ss_policy_t *p2;
318d4afb5ceSopenharmony_ci	lws_retry_bo_t *b;
319d4afb5ceSopenharmony_ci	size_t inl, outl;
320d4afb5ceSopenharmony_ci	uint8_t *extant;
321d4afb5ceSopenharmony_ci	backoff_t *bot;
322d4afb5ceSopenharmony_ci	int n = -1;
323d4afb5ceSopenharmony_ci
324d4afb5ceSopenharmony_ci//	lwsl_debug("%s: %d %d %s\n", __func__, reason, ctx->path_match - 1,
325d4afb5ceSopenharmony_ci//		   ctx->path);
326d4afb5ceSopenharmony_ci
327d4afb5ceSopenharmony_ci	switch (ctx->path_match - 1) {
328d4afb5ceSopenharmony_ci	case LSSPPT_RETRY:
329d4afb5ceSopenharmony_ci		n = LTY_BACKOFF;
330d4afb5ceSopenharmony_ci		break;
331d4afb5ceSopenharmony_ci	case LSSPPT_CERTS:
332d4afb5ceSopenharmony_ci		n = LTY_X509;
333d4afb5ceSopenharmony_ci		break;
334d4afb5ceSopenharmony_ci	case LSSPPT_TRUST_STORES_NAME:
335d4afb5ceSopenharmony_ci	case LSSPPT_TRUST_STORES_STACK:
336d4afb5ceSopenharmony_ci		n = LTY_TRUSTSTORE;
337d4afb5ceSopenharmony_ci		break;
338d4afb5ceSopenharmony_ci	case LSSPPT_STREAMTYPES:
339d4afb5ceSopenharmony_ci		n = LTY_POLICY;
340d4afb5ceSopenharmony_ci		break;
341d4afb5ceSopenharmony_ci	case LSSPPT_AUTH:
342d4afb5ceSopenharmony_ci		n = LTY_AUTH;
343d4afb5ceSopenharmony_ci		break;
344d4afb5ceSopenharmony_ci	case LSSPPT_METRICS_NAME:
345d4afb5ceSopenharmony_ci	case LSSPPT_METRICS_US_SCHEDULE:
346d4afb5ceSopenharmony_ci	case LSSPPT_METRICS_US_HALFLIFE:
347d4afb5ceSopenharmony_ci	case LSSPPT_METRICS_MIN_OUTLIER:
348d4afb5ceSopenharmony_ci	case LSSPPT_METRICS_REPORT:
349d4afb5ceSopenharmony_ci		n = LTY_METRICS;
350d4afb5ceSopenharmony_ci		break;
351d4afb5ceSopenharmony_ci	}
352d4afb5ceSopenharmony_ci
353d4afb5ceSopenharmony_ci	if (reason == LEJPCB_ARRAY_START &&
354d4afb5ceSopenharmony_ci	    (ctx->path_match - 1 == LSSPPT_PLUGINS ||
355d4afb5ceSopenharmony_ci	     ctx->path_match - 1 == LSSPPT_METADATA ||
356d4afb5ceSopenharmony_ci	     ctx->path_match - 1 == LSSPPT_HTTPRESPMAP))
357d4afb5ceSopenharmony_ci		a->count = 0;
358d4afb5ceSopenharmony_ci
359d4afb5ceSopenharmony_ci	if (reason == LEJPCB_OBJECT_START && n == LTY_AUTH) {
360d4afb5ceSopenharmony_ci		if (lws_ss_policy_alloc_helper(a, LTY_AUTH))
361d4afb5ceSopenharmony_ci			goto oom;
362d4afb5ceSopenharmony_ci		return 0;
363d4afb5ceSopenharmony_ci	}
364d4afb5ceSopenharmony_ci
365d4afb5ceSopenharmony_ci	if (reason == LEJPCB_ARRAY_END &&
366d4afb5ceSopenharmony_ci	    ctx->path_match - 1 == LSSPPT_TRUST_STORES_STACK && !a->count) {
367d4afb5ceSopenharmony_ci		lwsl_err("%s: at least one cert required in trust store\n",
368d4afb5ceSopenharmony_ci				__func__);
369d4afb5ceSopenharmony_ci		goto oom;
370d4afb5ceSopenharmony_ci	}
371d4afb5ceSopenharmony_ci
372d4afb5ceSopenharmony_ci	if (reason == LEJPCB_ARRAY_END && a->count && a->pending_respmap) {
373d4afb5ceSopenharmony_ci
374d4afb5ceSopenharmony_ci		// lwsl_notice("%s: allocating respmap %d\n", __func__, a->count);
375d4afb5ceSopenharmony_ci
376d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->u.http.respmap = lwsac_use_zero(&a->ac,
377d4afb5ceSopenharmony_ci			sizeof(lws_ss_http_respmap_t) * (unsigned int)a->count, POL_AC_GRAIN);
378d4afb5ceSopenharmony_ci
379d4afb5ceSopenharmony_ci		if (!a->curr[LTY_POLICY].p->u.http.respmap)
380d4afb5ceSopenharmony_ci			goto oom;
381d4afb5ceSopenharmony_ci
382d4afb5ceSopenharmony_ci		memcpy((void *)a->curr[LTY_POLICY].p->u.http.respmap,
383d4afb5ceSopenharmony_ci		       a->respmap, sizeof(lws_ss_http_respmap_t) * (unsigned int)a->count);
384d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->u.http.count_respmap = (uint8_t)a->count;
385d4afb5ceSopenharmony_ci		a->count = 0;
386d4afb5ceSopenharmony_ci		a->pending_respmap = 0;
387d4afb5ceSopenharmony_ci
388d4afb5ceSopenharmony_ci		return 0;
389d4afb5ceSopenharmony_ci	}
390d4afb5ceSopenharmony_ci
391d4afb5ceSopenharmony_ci	if (reason == LEJPCB_OBJECT_END && a->p) {
392d4afb5ceSopenharmony_ci		/*
393d4afb5ceSopenharmony_ci		 * Allocate a just-the-right-size buf for the cert DER now
394d4afb5ceSopenharmony_ci		 * we decoded it into the a->p temp buffer and know the exact
395d4afb5ceSopenharmony_ci		 * size.
396d4afb5ceSopenharmony_ci		 *
397d4afb5ceSopenharmony_ci		 * The struct *x is in the lwsac... the ca_der it points to
398d4afb5ceSopenharmony_ci		 * is individually allocated from the heap
399d4afb5ceSopenharmony_ci		 */
400d4afb5ceSopenharmony_ci		a->curr[LTY_X509].x->ca_der = lws_malloc((unsigned int)a->count, "ssx509");
401d4afb5ceSopenharmony_ci		if (!a->curr[LTY_X509].x->ca_der)
402d4afb5ceSopenharmony_ci			goto oom;
403d4afb5ceSopenharmony_ci		memcpy((uint8_t *)a->curr[LTY_X509].x->ca_der, a->p, (unsigned int)a->count);
404d4afb5ceSopenharmony_ci		a->curr[LTY_X509].x->ca_der_len = (unsigned int)a->count;
405d4afb5ceSopenharmony_ci
406d4afb5ceSopenharmony_ci		/*
407d4afb5ceSopenharmony_ci		 * ... and then we can free the temp buffer
408d4afb5ceSopenharmony_ci		 */
409d4afb5ceSopenharmony_ci		lws_free_set_NULL(a->p);
410d4afb5ceSopenharmony_ci
411d4afb5ceSopenharmony_ci		return 0;
412d4afb5ceSopenharmony_ci	}
413d4afb5ceSopenharmony_ci
414d4afb5ceSopenharmony_ci	if (reason == LEJPCB_PAIR_NAME && n != -1 &&
415d4afb5ceSopenharmony_ci	    (n != LTY_TRUSTSTORE && n != LTY_AUTH && n != LTY_METRICS)) {
416d4afb5ceSopenharmony_ci
417d4afb5ceSopenharmony_ci		p2 = NULL;
418d4afb5ceSopenharmony_ci		if (n == LTY_POLICY) {
419d4afb5ceSopenharmony_ci			/*
420d4afb5ceSopenharmony_ci			 * We want to allow for the possibility of overlays...
421d4afb5ceSopenharmony_ci			 * eg, we come later with a JSON snippet that overrides
422d4afb5ceSopenharmony_ci			 * select streamtype members of a streamtype that was
423d4afb5ceSopenharmony_ci			 * already defined
424d4afb5ceSopenharmony_ci			 */
425d4afb5ceSopenharmony_ci			p2 = (lws_ss_policy_t *)a->context->pss_policies;
426d4afb5ceSopenharmony_ci
427d4afb5ceSopenharmony_ci			while (p2) {
428d4afb5ceSopenharmony_ci				if (!strncmp(p2->streamtype,
429d4afb5ceSopenharmony_ci					     ctx->path + ctx->st[ctx->sp].p,
430d4afb5ceSopenharmony_ci					     (unsigned int)(ctx->path_match_len -
431d4afb5ceSopenharmony_ci						          ctx->st[ctx->sp].p))) {
432d4afb5ceSopenharmony_ci					lwsl_info("%s: overriding s[] %s\n",
433d4afb5ceSopenharmony_ci						  __func__, p2->streamtype);
434d4afb5ceSopenharmony_ci					break;
435d4afb5ceSopenharmony_ci				}
436d4afb5ceSopenharmony_ci
437d4afb5ceSopenharmony_ci				p2 = p2->next;
438d4afb5ceSopenharmony_ci			}
439d4afb5ceSopenharmony_ci		}
440d4afb5ceSopenharmony_ci
441d4afb5ceSopenharmony_ci		/*
442d4afb5ceSopenharmony_ci		 * We do the pointers always as .b union member, all of the
443d4afb5ceSopenharmony_ci		 * participating structs begin with .next and .name the same
444d4afb5ceSopenharmony_ci		 */
445d4afb5ceSopenharmony_ci		if (p2) /* we may be overriding existing streamtype... */
446d4afb5ceSopenharmony_ci			a->curr[n].b = (backoff_t *)p2;
447d4afb5ceSopenharmony_ci		else
448d4afb5ceSopenharmony_ci			a->curr[n].b = lwsac_use_zero(&a->ac, sizes[n],
449d4afb5ceSopenharmony_ci							POL_AC_GRAIN);
450d4afb5ceSopenharmony_ci		if (!a->curr[n].b)
451d4afb5ceSopenharmony_ci			goto oom;
452d4afb5ceSopenharmony_ci
453d4afb5ceSopenharmony_ci		if (n == LTY_X509) {
454d4afb5ceSopenharmony_ci			a->p = lws_malloc(MAX_CERT_TEMP, "cert temp");
455d4afb5ceSopenharmony_ci			if (!a->p)
456d4afb5ceSopenharmony_ci				goto oom;
457d4afb5ceSopenharmony_ci			memset(&a->b64, 0, sizeof(a->b64));
458d4afb5ceSopenharmony_ci		}
459d4afb5ceSopenharmony_ci
460d4afb5ceSopenharmony_ci		a->count = 0;
461d4afb5ceSopenharmony_ci		if (!p2) {
462d4afb5ceSopenharmony_ci			a->curr[n].b->next = a->heads[n].b;
463d4afb5ceSopenharmony_ci			a->heads[n].b = a->curr[n].b;
464d4afb5ceSopenharmony_ci			pp = (char **)&a->curr[n].b->name;
465d4afb5ceSopenharmony_ci
466d4afb5ceSopenharmony_ci			goto string1;
467d4afb5ceSopenharmony_ci		}
468d4afb5ceSopenharmony_ci
469d4afb5ceSopenharmony_ci		return 0; /* overriding */
470d4afb5ceSopenharmony_ci	}
471d4afb5ceSopenharmony_ci
472d4afb5ceSopenharmony_ci	if (!(reason & LEJP_FLAG_CB_IS_VALUE) || !ctx->path_match)
473d4afb5ceSopenharmony_ci		return 0;
474d4afb5ceSopenharmony_ci
475d4afb5ceSopenharmony_ci	switch (ctx->path_match - 1) {
476d4afb5ceSopenharmony_ci
477d4afb5ceSopenharmony_ci	/* strings */
478d4afb5ceSopenharmony_ci
479d4afb5ceSopenharmony_ci	case LSSPPT_RELEASE:
480d4afb5ceSopenharmony_ci		break;
481d4afb5ceSopenharmony_ci
482d4afb5ceSopenharmony_ci	case LSSPPT_PRODUCT:
483d4afb5ceSopenharmony_ci		break;
484d4afb5ceSopenharmony_ci
485d4afb5ceSopenharmony_ci	case LSSPPT_SCHEMA_VERSION:
486d4afb5ceSopenharmony_ci		break;
487d4afb5ceSopenharmony_ci
488d4afb5ceSopenharmony_ci	case LSSPPT_VIA_SOCKS5:
489d4afb5ceSopenharmony_ci		/* the global / default proxy */
490d4afb5ceSopenharmony_ci		pp = (char **)&a->socks5_proxy;
491d4afb5ceSopenharmony_ci		goto string2;
492d4afb5ceSopenharmony_ci
493d4afb5ceSopenharmony_ci	case LSSPPT_BACKOFF:
494d4afb5ceSopenharmony_ci		b = &a->curr[LTY_BACKOFF].b->r;
495d4afb5ceSopenharmony_ci		if (b->retry_ms_table_count == 8) {
496d4afb5ceSopenharmony_ci			lwsl_err("%s: > 8 backoff levels\n", __func__);
497d4afb5ceSopenharmony_ci			return 1;
498d4afb5ceSopenharmony_ci		}
499d4afb5ceSopenharmony_ci		if (!b->retry_ms_table_count) {
500d4afb5ceSopenharmony_ci			b->retry_ms_table = (uint32_t *)lwsac_use_zero(&a->ac,
501d4afb5ceSopenharmony_ci					   sizeof(uint32_t) * 8, POL_AC_GRAIN);
502d4afb5ceSopenharmony_ci			if (!b->retry_ms_table)
503d4afb5ceSopenharmony_ci				goto oom;
504d4afb5ceSopenharmony_ci		}
505d4afb5ceSopenharmony_ci
506d4afb5ceSopenharmony_ci		((uint32_t *)b->retry_ms_table)
507d4afb5ceSopenharmony_ci				[b->retry_ms_table_count++] = (uint32_t)atoi(ctx->buf);
508d4afb5ceSopenharmony_ci		break;
509d4afb5ceSopenharmony_ci
510d4afb5ceSopenharmony_ci	case LSSPPT_CONCEAL:
511d4afb5ceSopenharmony_ci		a->curr[LTY_BACKOFF].b->r.conceal_count = (uint16_t)atoi(ctx->buf);
512d4afb5ceSopenharmony_ci		break;
513d4afb5ceSopenharmony_ci
514d4afb5ceSopenharmony_ci	case LSSPPT_JITTERPC:
515d4afb5ceSopenharmony_ci		a->curr[LTY_BACKOFF].b->r.jitter_percent = (uint8_t)atoi(ctx->buf);
516d4afb5ceSopenharmony_ci		break;
517d4afb5ceSopenharmony_ci
518d4afb5ceSopenharmony_ci	case LSSPPT_VALIDPING_S:
519d4afb5ceSopenharmony_ci		a->curr[LTY_BACKOFF].b->r.secs_since_valid_ping = (uint16_t)atoi(ctx->buf);
520d4afb5ceSopenharmony_ci		break;
521d4afb5ceSopenharmony_ci
522d4afb5ceSopenharmony_ci	case LSSPPT_VALIDHUP_S:
523d4afb5ceSopenharmony_ci		a->curr[LTY_BACKOFF].b->r.secs_since_valid_hangup = (uint16_t)atoi(ctx->buf);
524d4afb5ceSopenharmony_ci		break;
525d4afb5ceSopenharmony_ci
526d4afb5ceSopenharmony_ci	case LSSPPT_CERTS:
527d4afb5ceSopenharmony_ci		if (a->count + ctx->npos >= MAX_CERT_TEMP) {
528d4afb5ceSopenharmony_ci			lwsl_err("%s: cert too big\n", __func__);
529d4afb5ceSopenharmony_ci			goto oom;
530d4afb5ceSopenharmony_ci		}
531d4afb5ceSopenharmony_ci		inl = ctx->npos;
532d4afb5ceSopenharmony_ci		outl = MAX_CERT_TEMP - (unsigned int)a->count;
533d4afb5ceSopenharmony_ci
534d4afb5ceSopenharmony_ci		lws_b64_decode_stateful(&a->b64, ctx->buf, &inl,
535d4afb5ceSopenharmony_ci					a->p + a->count, &outl,
536d4afb5ceSopenharmony_ci					reason == LEJPCB_VAL_STR_END);
537d4afb5ceSopenharmony_ci		a->count += (int)outl;
538d4afb5ceSopenharmony_ci		if (inl != ctx->npos) {
539d4afb5ceSopenharmony_ci			lwsl_err("%s: b64 decode fail\n", __func__);
540d4afb5ceSopenharmony_ci			goto oom;
541d4afb5ceSopenharmony_ci		}
542d4afb5ceSopenharmony_ci		break;
543d4afb5ceSopenharmony_ci
544d4afb5ceSopenharmony_ci	case LSSPPT_TRUST_STORES_NAME:
545d4afb5ceSopenharmony_ci		if (lws_ss_policy_alloc_helper(a, LTY_TRUSTSTORE))
546d4afb5ceSopenharmony_ci			goto oom;
547d4afb5ceSopenharmony_ci
548d4afb5ceSopenharmony_ci		a->count = 0;
549d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_TRUSTSTORE].b->name;
550d4afb5ceSopenharmony_ci
551d4afb5ceSopenharmony_ci		goto string2;
552d4afb5ceSopenharmony_ci
553d4afb5ceSopenharmony_ci	case LSSPPT_TRUST_STORES_STACK:
554d4afb5ceSopenharmony_ci		if (a->count >= (int)LWS_ARRAY_SIZE(
555d4afb5ceSopenharmony_ci					a->curr[LTY_TRUSTSTORE].t->ssx509)) {
556d4afb5ceSopenharmony_ci			lwsl_err("%s: trust store too big\n", __func__);
557d4afb5ceSopenharmony_ci			goto oom;
558d4afb5ceSopenharmony_ci		}
559d4afb5ceSopenharmony_ci		lwsl_debug("%s: trust stores stack %.*s\n", __func__,
560d4afb5ceSopenharmony_ci			   ctx->npos, ctx->buf);
561d4afb5ceSopenharmony_ci		x = a->heads[LTY_X509].x;
562d4afb5ceSopenharmony_ci		while (x) {
563d4afb5ceSopenharmony_ci			if (!strncmp(x->vhost_name, ctx->buf, ctx->npos)) {
564d4afb5ceSopenharmony_ci				a->curr[LTY_TRUSTSTORE].t->ssx509[a->count++] = x;
565d4afb5ceSopenharmony_ci				a->curr[LTY_TRUSTSTORE].t->count++;
566d4afb5ceSopenharmony_ci
567d4afb5ceSopenharmony_ci				return 0;
568d4afb5ceSopenharmony_ci			}
569d4afb5ceSopenharmony_ci			x = x->next;
570d4afb5ceSopenharmony_ci		}
571d4afb5ceSopenharmony_ci		lws_strnncpy(dotstar, ctx->buf, ctx->npos, sizeof(dotstar));
572d4afb5ceSopenharmony_ci		lwsl_err("%s: unknown trust store entry %s\n", __func__,
573d4afb5ceSopenharmony_ci			 dotstar);
574d4afb5ceSopenharmony_ci		goto oom;
575d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SYS_METRICS)
576d4afb5ceSopenharmony_ci	case LSSPPT_METRICS_NAME:
577d4afb5ceSopenharmony_ci		if (lws_ss_policy_alloc_helper(a, LTY_METRICS))
578d4afb5ceSopenharmony_ci			goto oom;
579d4afb5ceSopenharmony_ci
580d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_METRICS].b->name;
581d4afb5ceSopenharmony_ci
582d4afb5ceSopenharmony_ci		goto string2;
583d4afb5ceSopenharmony_ci
584d4afb5ceSopenharmony_ci	case LSSPPT_METRICS_US_SCHEDULE:
585d4afb5ceSopenharmony_ci		a->curr[LTY_METRICS].m->us_schedule = (uint64_t)atoll(ctx->buf);
586d4afb5ceSopenharmony_ci		break;
587d4afb5ceSopenharmony_ci
588d4afb5ceSopenharmony_ci	case LSSPPT_METRICS_US_HALFLIFE:
589d4afb5ceSopenharmony_ci		a->curr[LTY_METRICS].m->us_decay_unit = (uint32_t)atol(ctx->buf);
590d4afb5ceSopenharmony_ci		break;
591d4afb5ceSopenharmony_ci
592d4afb5ceSopenharmony_ci	case LSSPPT_METRICS_MIN_OUTLIER:
593d4afb5ceSopenharmony_ci		a->curr[LTY_METRICS].m->min_contributors = (uint8_t)atoi(ctx->buf);
594d4afb5ceSopenharmony_ci		break;
595d4afb5ceSopenharmony_ci
596d4afb5ceSopenharmony_ci	case LSSPPT_METRICS_REPORT:
597d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_METRICS].m->report;
598d4afb5ceSopenharmony_ci		goto string2;
599d4afb5ceSopenharmony_ci#endif
600d4afb5ceSopenharmony_ci
601d4afb5ceSopenharmony_ci	case LSSPPT_SERVER_CERT:
602d4afb5ceSopenharmony_ci	case LSSPPT_SERVER_KEY:
603d4afb5ceSopenharmony_ci
604d4afb5ceSopenharmony_ci		/* iterate through the certs */
605d4afb5ceSopenharmony_ci
606d4afb5ceSopenharmony_ci		py = &a->heads[LTY_X509].x;
607d4afb5ceSopenharmony_ci		x = a->heads[LTY_X509].x;
608d4afb5ceSopenharmony_ci		while (x) {
609d4afb5ceSopenharmony_ci			if (!strncmp(x->vhost_name, ctx->buf, ctx->npos) &&
610d4afb5ceSopenharmony_ci					!x->vhost_name[ctx->npos]) {
611d4afb5ceSopenharmony_ci				if ((ctx->path_match - 1) == LSSPPT_SERVER_CERT)
612d4afb5ceSopenharmony_ci					a->curr[LTY_POLICY].p->trust.server.cert = x;
613d4afb5ceSopenharmony_ci				else
614d4afb5ceSopenharmony_ci					a->curr[LTY_POLICY].p->trust.server.key = x;
615d4afb5ceSopenharmony_ci				/*
616d4afb5ceSopenharmony_ci				 * Certs that are for servers need to stick
617d4afb5ceSopenharmony_ci				 * around in DER form, so the vhost can be
618d4afb5ceSopenharmony_ci				 * instantiated when the server is brought up
619d4afb5ceSopenharmony_ci				 */
620d4afb5ceSopenharmony_ci				x->keep = 1;
621d4afb5ceSopenharmony_ci				lwsl_notice("%s: server '%s' keep %d %p\n",
622d4afb5ceSopenharmony_ci					    __func__, x->vhost_name,
623d4afb5ceSopenharmony_ci						ctx->path_match - 1, x);
624d4afb5ceSopenharmony_ci
625d4afb5ceSopenharmony_ci				/*
626d4afb5ceSopenharmony_ci				 * Server DER we need to move it to another
627d4afb5ceSopenharmony_ci				 * list just for destroying it when the context
628d4afb5ceSopenharmony_ci				 * is destroyed... snip us out of the live
629d4afb5ceSopenharmony_ci				 * X.509 list
630d4afb5ceSopenharmony_ci				 */
631d4afb5ceSopenharmony_ci
632d4afb5ceSopenharmony_ci				*py = x->next;
633d4afb5ceSopenharmony_ci
634d4afb5ceSopenharmony_ci				/*
635d4afb5ceSopenharmony_ci				 * ... and instead put us on the list of things
636d4afb5ceSopenharmony_ci				 * to keep hold of for context destruction
637d4afb5ceSopenharmony_ci				 */
638d4afb5ceSopenharmony_ci
639d4afb5ceSopenharmony_ci				x->next = a->context->server_der_list;
640d4afb5ceSopenharmony_ci				a->context->server_der_list = x;
641d4afb5ceSopenharmony_ci
642d4afb5ceSopenharmony_ci				return 0;
643d4afb5ceSopenharmony_ci			}
644d4afb5ceSopenharmony_ci			py = &x->next;
645d4afb5ceSopenharmony_ci			x = x->next;
646d4afb5ceSopenharmony_ci		}
647d4afb5ceSopenharmony_ci		lws_strnncpy(dotstar, ctx->buf, ctx->npos, sizeof(dotstar));
648d4afb5ceSopenharmony_ci		lwsl_err("%s: unknown cert / key %s\n", __func__, dotstar);
649d4afb5ceSopenharmony_ci		goto oom;
650d4afb5ceSopenharmony_ci
651d4afb5ceSopenharmony_ci	case LSSPPT_ENDPOINT:
652d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->endpoint;
653d4afb5ceSopenharmony_ci		goto string2;
654d4afb5ceSopenharmony_ci
655d4afb5ceSopenharmony_ci	case LSSPPT_VH_VIA_SOCKS5:
656d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->socks5_proxy;
657d4afb5ceSopenharmony_ci		goto string2;
658d4afb5ceSopenharmony_ci
659d4afb5ceSopenharmony_ci	case LSSPPT_PORT:
660d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->port = (uint16_t)atoi(ctx->buf);
661d4afb5ceSopenharmony_ci		break;
662d4afb5ceSopenharmony_ci
663d4afb5ceSopenharmony_ci	case LSSPPT_PROXY_BUFLEN:
664d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->proxy_buflen = (uint32_t)atol(ctx->buf);
665d4afb5ceSopenharmony_ci		break;
666d4afb5ceSopenharmony_ci
667d4afb5ceSopenharmony_ci	case LSSPPT_PROXY_BUFLEN_RXFLOW_ON_ABOVE:
668d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->proxy_buflen_rxflow_on_above =
669d4afb5ceSopenharmony_ci						(uint32_t)atol(ctx->buf);
670d4afb5ceSopenharmony_ci		break;
671d4afb5ceSopenharmony_ci	case LSSPPT_PROXY_BUFLEN_RXFLOW_OFF_BELOW:
672d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->proxy_buflen_rxflow_off_below =
673d4afb5ceSopenharmony_ci						(uint32_t)atol(ctx->buf);
674d4afb5ceSopenharmony_ci		break;
675d4afb5ceSopenharmony_ci
676d4afb5ceSopenharmony_ci	case LSSPPT_CLIENT_BUFLEN:
677d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->client_buflen = (uint32_t)atol(ctx->buf);
678d4afb5ceSopenharmony_ci		break;
679d4afb5ceSopenharmony_ci
680d4afb5ceSopenharmony_ci	case LSSPPT_CLIENT_BUFLEN_RXFLOW_ON_ABOVE:
681d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->client_buflen_rxflow_on_above =
682d4afb5ceSopenharmony_ci						(uint32_t)atol(ctx->buf);
683d4afb5ceSopenharmony_ci		break;
684d4afb5ceSopenharmony_ci	case LSSPPT_CLIENT_BUFLEN_RXFLOW_OFF_BELOW:
685d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->client_buflen_rxflow_off_below =
686d4afb5ceSopenharmony_ci						(uint32_t)atol(ctx->buf);
687d4afb5ceSopenharmony_ci		break;
688d4afb5ceSopenharmony_ci
689d4afb5ceSopenharmony_ci	case LSSPPT_HTTP_METHOD:
690d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->u.http.method;
691d4afb5ceSopenharmony_ci		goto string2;
692d4afb5ceSopenharmony_ci
693d4afb5ceSopenharmony_ci	case LSSPPT_HTTP_URL:
694d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->u.http.url;
695d4afb5ceSopenharmony_ci		goto string2;
696d4afb5ceSopenharmony_ci
697d4afb5ceSopenharmony_ci	case LSSPPT_RIDESHARE:
698d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->rideshare_streamtype;
699d4afb5ceSopenharmony_ci		goto string2;
700d4afb5ceSopenharmony_ci
701d4afb5ceSopenharmony_ci	case LSSPPT_PAYLOAD_FORMAT:
702d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->payload_fmt;
703d4afb5ceSopenharmony_ci		goto string2;
704d4afb5ceSopenharmony_ci
705d4afb5ceSopenharmony_ci	case LSSPPT_PLUGINS:
706d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SSPLUGINS)
707d4afb5ceSopenharmony_ci		pin = a->context->pss_plugins;
708d4afb5ceSopenharmony_ci		if (a->count ==
709d4afb5ceSopenharmony_ci			  (int)LWS_ARRAY_SIZE(a->curr[LTY_POLICY].p->plugins)) {
710d4afb5ceSopenharmony_ci			lwsl_err("%s: too many plugins\n", __func__);
711d4afb5ceSopenharmony_ci
712d4afb5ceSopenharmony_ci			goto oom;
713d4afb5ceSopenharmony_ci		}
714d4afb5ceSopenharmony_ci		if (!pin)
715d4afb5ceSopenharmony_ci			break;
716d4afb5ceSopenharmony_ci		while (*pin) {
717d4afb5ceSopenharmony_ci			if (!strncmp((*pin)->name, ctx->buf, ctx->npos)) {
718d4afb5ceSopenharmony_ci				a->curr[LTY_POLICY].p->plugins[a->count++] = *pin;
719d4afb5ceSopenharmony_ci				return 0;
720d4afb5ceSopenharmony_ci			}
721d4afb5ceSopenharmony_ci			pin++;
722d4afb5ceSopenharmony_ci		}
723d4afb5ceSopenharmony_ci		lwsl_err("%s: unknown plugin\n", __func__);
724d4afb5ceSopenharmony_ci		goto oom;
725d4afb5ceSopenharmony_ci#else
726d4afb5ceSopenharmony_ci		break;
727d4afb5ceSopenharmony_ci#endif
728d4afb5ceSopenharmony_ci
729d4afb5ceSopenharmony_ci	case LSSPPT_TLS:
730d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
731d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |= LWSSSPOLF_TLS;
732d4afb5ceSopenharmony_ci		break;
733d4afb5ceSopenharmony_ci
734d4afb5ceSopenharmony_ci	case LSSPPT_TLS_CLIENT_CERT:
735d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->client_cert = (uint8_t)(atoi(ctx->buf) + 1);
736d4afb5ceSopenharmony_ci		break;
737d4afb5ceSopenharmony_ci
738d4afb5ceSopenharmony_ci	case LSSPPT_AUTH_BLOB:
739d4afb5ceSopenharmony_ci		a->curr[LTY_AUTH].a->blob_index = (uint8_t)atoi(ctx->buf);
740d4afb5ceSopenharmony_ci		break;
741d4afb5ceSopenharmony_ci	case LSSPPT_HTTP_EXPECT:
742d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->u.http.resp_expect = (uint16_t)atoi(ctx->buf);
743d4afb5ceSopenharmony_ci		break;
744d4afb5ceSopenharmony_ci
745d4afb5ceSopenharmony_ci	case LSSPPT_DEFAULT_TIMEOUT_MS:
746d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->timeout_ms = (uint32_t)atoi(ctx->buf);
747d4afb5ceSopenharmony_ci		break;
748d4afb5ceSopenharmony_ci
749d4afb5ceSopenharmony_ci	case LSSPPT_ATTR_PRIORITY:
750d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->priority = (uint8_t)atoi(ctx->buf);
751d4afb5ceSopenharmony_ci		break;
752d4afb5ceSopenharmony_ci
753d4afb5ceSopenharmony_ci	case LSSPPT_OPPORTUNISTIC:
754d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
755d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |= LWSSSPOLF_OPPORTUNISTIC;
756d4afb5ceSopenharmony_ci		break;
757d4afb5ceSopenharmony_ci	case LSSPPT_NAILED_UP:
758d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
759d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |= LWSSSPOLF_NAILED_UP;
760d4afb5ceSopenharmony_ci		break;
761d4afb5ceSopenharmony_ci	case LSSPPT_URGENT_TX:
762d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
763d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |= LWSSSPOLF_URGENT_TX;
764d4afb5ceSopenharmony_ci		break;
765d4afb5ceSopenharmony_ci	case LSSPPT_URGENT_RX:
766d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
767d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |= LWSSSPOLF_URGENT_RX;
768d4afb5ceSopenharmony_ci		break;
769d4afb5ceSopenharmony_ci	case LSSPPT_LONG_POLL:
770d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
771d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |= LWSSSPOLF_LONG_POLL;
772d4afb5ceSopenharmony_ci		break;
773d4afb5ceSopenharmony_ci	case LSSPPT_PRIORITIZE_READS:
774d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
775d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |= LWSSSPOLF_PRIORITIZE_READS;
776d4afb5ceSopenharmony_ci		break;
777d4afb5ceSopenharmony_ci
778d4afb5ceSopenharmony_ci	case LSSPPT_HTTP_WWW_FORM_URLENCODED:
779d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
780d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |=
781d4afb5ceSopenharmony_ci					LWSSSPOLF_HTTP_X_WWW_FORM_URLENCODED;
782d4afb5ceSopenharmony_ci		break;
783d4afb5ceSopenharmony_ci	case LSSPPT_SWAKE_VALIDITY:
784d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
785d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |=
786d4afb5ceSopenharmony_ci					LWSSSPOLF_WAKE_SUSPEND__VALIDITY;
787d4afb5ceSopenharmony_ci		break;
788d4afb5ceSopenharmony_ci	case LSSPPT_ALLOW_REDIRECTS:
789d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
790d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |=
791d4afb5ceSopenharmony_ci						LWSSSPOLF_ALLOW_REDIRECTS;
792d4afb5ceSopenharmony_ci		break;
793d4afb5ceSopenharmony_ci	case LSSPPT_HTTP_COOKIES:
794d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
795d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |=
796d4afb5ceSopenharmony_ci						LWSSSPOLF_HTTP_CACHE_COOKIES;
797d4afb5ceSopenharmony_ci		break;
798d4afb5ceSopenharmony_ci	case LSSPPT_HTTP_MULTIPART_SS_IN:
799d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
800d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |=
801d4afb5ceSopenharmony_ci						LWSSSPOLF_HTTP_MULTIPART_IN;
802d4afb5ceSopenharmony_ci		return 0;
803d4afb5ceSopenharmony_ci
804d4afb5ceSopenharmony_ci	case LSSPPT_ATTR_LOW_LATENCY:
805d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
806d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |=
807d4afb5ceSopenharmony_ci						LWSSSPOLF_ATTR_LOW_LATENCY;
808d4afb5ceSopenharmony_ci		return 0;
809d4afb5ceSopenharmony_ci
810d4afb5ceSopenharmony_ci	case LSSPPT_ATTR_HIGH_THROUGHPUT:
811d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
812d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |=
813d4afb5ceSopenharmony_ci						LWSSSPOLF_ATTR_HIGH_THROUGHPUT;
814d4afb5ceSopenharmony_ci		return 0;
815d4afb5ceSopenharmony_ci
816d4afb5ceSopenharmony_ci	case LSSPPT_ATTR_HIGH_RELIABILITY:
817d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
818d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |=
819d4afb5ceSopenharmony_ci						LWSSSPOLF_ATTR_HIGH_RELIABILITY;
820d4afb5ceSopenharmony_ci		return 0;
821d4afb5ceSopenharmony_ci
822d4afb5ceSopenharmony_ci	case LSSPPT_ATTR_LOW_COST:
823d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
824d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |= LWSSSPOLF_ATTR_LOW_COST;
825d4afb5ceSopenharmony_ci		return 0;
826d4afb5ceSopenharmony_ci
827d4afb5ceSopenharmony_ci	case LSSPPT_PERF:
828d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
829d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |= LWSSSPOLF_PERF;
830d4afb5ceSopenharmony_ci		return 0;
831d4afb5ceSopenharmony_ci
832d4afb5ceSopenharmony_ci	case LSSPPT_RETRYPTR:
833d4afb5ceSopenharmony_ci		bot = a->heads[LTY_BACKOFF].b;
834d4afb5ceSopenharmony_ci		while (bot) {
835d4afb5ceSopenharmony_ci			if (!strncmp(ctx->buf, bot->name, ctx->npos)) {
836d4afb5ceSopenharmony_ci				a->curr[LTY_POLICY].p->retry_bo = &bot->r;
837d4afb5ceSopenharmony_ci
838d4afb5ceSopenharmony_ci				return 0;
839d4afb5ceSopenharmony_ci			}
840d4afb5ceSopenharmony_ci			bot = bot->next;
841d4afb5ceSopenharmony_ci		}
842d4afb5ceSopenharmony_ci		lwsl_err("%s: unknown backoff scheme\n", __func__);
843d4afb5ceSopenharmony_ci
844d4afb5ceSopenharmony_ci		return -1;
845d4afb5ceSopenharmony_ci
846d4afb5ceSopenharmony_ci	case LSSPPT_TRUST:
847d4afb5ceSopenharmony_ci		ts = a->heads[LTY_TRUSTSTORE].t;
848d4afb5ceSopenharmony_ci		while (ts) {
849d4afb5ceSopenharmony_ci			if (!strncmp(ctx->buf, ts->name, ctx->npos)) {
850d4afb5ceSopenharmony_ci				a->curr[LTY_POLICY].p->trust.store = ts;
851d4afb5ceSopenharmony_ci				return 0;
852d4afb5ceSopenharmony_ci			}
853d4afb5ceSopenharmony_ci			ts = ts->next;
854d4afb5ceSopenharmony_ci		}
855d4afb5ceSopenharmony_ci		lws_strnncpy(dotstar, ctx->buf, ctx->npos, sizeof(dotstar));
856d4afb5ceSopenharmony_ci		lwsl_err("%s: unknown trust store name %s\n", __func__,
857d4afb5ceSopenharmony_ci			 dotstar);
858d4afb5ceSopenharmony_ci
859d4afb5ceSopenharmony_ci		return -1;
860d4afb5ceSopenharmony_ci
861d4afb5ceSopenharmony_ci	case LSSPPT_METADATA:
862d4afb5ceSopenharmony_ci		break;
863d4afb5ceSopenharmony_ci
864d4afb5ceSopenharmony_ci	case LSSPPT_USE_AUTH:
865d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->auth =
866d4afb5ceSopenharmony_ci			lws_ss_policy_find_auth_by_name(a, ctx->buf, ctx->npos);
867d4afb5ceSopenharmony_ci		if (!a->curr[LTY_POLICY].p->auth) {
868d4afb5ceSopenharmony_ci			lws_strnncpy(dotstar, ctx->buf, ctx->npos, sizeof(dotstar));
869d4afb5ceSopenharmony_ci			lwsl_err("%s: unknown auth '%s'\n", __func__, dotstar);
870d4afb5ceSopenharmony_ci			return -1;
871d4afb5ceSopenharmony_ci		}
872d4afb5ceSopenharmony_ci		break;
873d4afb5ceSopenharmony_ci
874d4afb5ceSopenharmony_ci
875d4afb5ceSopenharmony_ci	case LSSPPT_METADATA_ITEM:
876d4afb5ceSopenharmony_ci		pmd = a->curr[LTY_POLICY].p->metadata;
877d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->metadata = lwsac_use_zero(&a->ac,
878d4afb5ceSopenharmony_ci			sizeof(lws_ss_metadata_t) + ctx->npos +
879d4afb5ceSopenharmony_ci			(unsigned int)(ctx->path_match_len - ctx->st[ctx->sp - 2].p + 1) + 2,
880d4afb5ceSopenharmony_ci			POL_AC_GRAIN);
881d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->metadata->next = pmd;
882d4afb5ceSopenharmony_ci
883d4afb5ceSopenharmony_ci		q = (char *)a->curr[LTY_POLICY].p->metadata +
884d4afb5ceSopenharmony_ci				sizeof(lws_ss_metadata_t);
885d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->metadata->name = q;
886d4afb5ceSopenharmony_ci		memcpy(q, ctx->path + ctx->st[ctx->sp - 2].p + 1,
887d4afb5ceSopenharmony_ci		       (unsigned int)(ctx->path_match_len - ctx->st[ctx->sp - 2].p));
888d4afb5ceSopenharmony_ci
889d4afb5ceSopenharmony_ci		q += ctx->path_match_len - ctx->st[ctx->sp - 2].p;
890d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->metadata->value__may_own_heap = q;
891d4afb5ceSopenharmony_ci		memcpy(q, ctx->buf, ctx->npos);
892d4afb5ceSopenharmony_ci
893d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
894d4afb5ceSopenharmony_ci		/*
895d4afb5ceSopenharmony_ci		 * Check the metadata value part to see if it's a well-known
896d4afb5ceSopenharmony_ci		 * http header... if so, LWS_HTTP_NO_KNOWN_HEADER (0xff) means
897d4afb5ceSopenharmony_ci		 * no header string match else it's the well-known header index
898d4afb5ceSopenharmony_ci		 */
899d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->metadata->value_is_http_token = (uint8_t)
900d4afb5ceSopenharmony_ci			lws_http_string_to_known_header(ctx->buf, ctx->npos);
901d4afb5ceSopenharmony_ci#endif
902d4afb5ceSopenharmony_ci
903d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->metadata->length = /* the index in handle->metadata */
904d4afb5ceSopenharmony_ci				a->curr[LTY_POLICY].p->metadata_count++;
905d4afb5ceSopenharmony_ci
906d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->metadata->value_length = ctx->npos;
907d4afb5ceSopenharmony_ci		break;
908d4afb5ceSopenharmony_ci
909d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
910d4afb5ceSopenharmony_ci
911d4afb5ceSopenharmony_ci	case LSSPPT_HTTPRESPMAP_ITEM:
912d4afb5ceSopenharmony_ci		if (a->count >= (int)LWS_ARRAY_SIZE(a->respmap)) {
913d4afb5ceSopenharmony_ci			lwsl_err("%s: respmap too big\n", __func__);
914d4afb5ceSopenharmony_ci			return -1;
915d4afb5ceSopenharmony_ci		}
916d4afb5ceSopenharmony_ci		a->respmap[a->count].resp = (uint16_t)
917d4afb5ceSopenharmony_ci				atoi(ctx->path + ctx->st[ctx->sp - 2].p + 1);
918d4afb5ceSopenharmony_ci		a->respmap[a->count].state = (uint16_t)atoi(ctx->buf);
919d4afb5ceSopenharmony_ci		a->pending_respmap = 1;
920d4afb5ceSopenharmony_ci		a->count++;
921d4afb5ceSopenharmony_ci		break;
922d4afb5ceSopenharmony_ci
923d4afb5ceSopenharmony_ci	case LSSPPT_HTTP_AUTH_HEADER:
924d4afb5ceSopenharmony_ci	case LSSPPT_HTTP_DSN_HEADER:
925d4afb5ceSopenharmony_ci	case LSSPPT_HTTP_FWV_HEADER:
926d4afb5ceSopenharmony_ci	case LSSPPT_HTTP_TYPE_HEADER:
927d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->u.http.blob_header[
928d4afb5ceSopenharmony_ci		               (ctx->path_match - 1) - LSSPPT_HTTP_AUTH_HEADER];
929d4afb5ceSopenharmony_ci		goto string2;
930d4afb5ceSopenharmony_ci
931d4afb5ceSopenharmony_ci	case LSSPPT_HTTP_AUTH_PREAMBLE:
932d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->u.http.auth_preamble;
933d4afb5ceSopenharmony_ci		goto string2;
934d4afb5ceSopenharmony_ci
935d4afb5ceSopenharmony_ci	case LSSPPT_HTTP_NO_CONTENT_LENGTH:
936d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
937d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |=
938d4afb5ceSopenharmony_ci					LWSSSPOLF_HTTP_NO_CONTENT_LENGTH;
939d4afb5ceSopenharmony_ci		break;
940d4afb5ceSopenharmony_ci
941d4afb5ceSopenharmony_ci	case LSSPPT_NGHTTP2_QUIRK_END_STREAM:
942d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
943d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |=
944d4afb5ceSopenharmony_ci					LWSSSPOLF_QUIRK_NGHTTP2_END_STREAM;
945d4afb5ceSopenharmony_ci		break;
946d4afb5ceSopenharmony_ci	case LSSPPT_H2_QUIRK_OVERFLOWS_TXCR:
947d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
948d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |=
949d4afb5ceSopenharmony_ci					LWSSSPOLF_H2_QUIRK_OVERFLOWS_TXCR;
950d4afb5ceSopenharmony_ci		break;
951d4afb5ceSopenharmony_ci	case LSSPPT_HTTP_MULTIPART_NAME:
952d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->flags |= LWSSSPOLF_HTTP_MULTIPART;
953d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->u.http.multipart_name;
954d4afb5ceSopenharmony_ci		goto string2;
955d4afb5ceSopenharmony_ci	case LSSPPT_HTTP_MULTIPART_FILENAME:
956d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->flags |= LWSSSPOLF_HTTP_MULTIPART;
957d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->u.http.multipart_filename;
958d4afb5ceSopenharmony_ci		goto string2;
959d4afb5ceSopenharmony_ci	case LSSPPT_HTTP_MULTIPART_CONTENT_TYPE:
960d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->flags |= LWSSSPOLF_HTTP_MULTIPART;
961d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->u.http.multipart_content_type;
962d4afb5ceSopenharmony_ci		goto string2;
963d4afb5ceSopenharmony_ci
964d4afb5ceSopenharmony_ci	case LSSPPT_AUTH_NAME:
965d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_AUTH].a->name;
966d4afb5ceSopenharmony_ci		goto string2;
967d4afb5ceSopenharmony_ci
968d4afb5ceSopenharmony_ci	case LSSPPT_AUTH_STREAMTYPE:
969d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_AUTH].a->streamtype;
970d4afb5ceSopenharmony_ci		goto string2;
971d4afb5ceSopenharmony_ci	case LSSPPT_AUTH_TYPE:
972d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_AUTH].a->type;
973d4afb5ceSopenharmony_ci		goto string2;
974d4afb5ceSopenharmony_ci	case LSSPPT_HTTP_FAIL_REDIRECT:
975d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->u.http.fail_redirect =
976d4afb5ceSopenharmony_ci						reason == LEJPCB_VAL_TRUE;
977d4afb5ceSopenharmony_ci		break;
978d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS_AUTH_SIGV4)
979d4afb5ceSopenharmony_ci	case LSSPPT_AWS_REGION:
980d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->aws_region;
981d4afb5ceSopenharmony_ci		goto string2;
982d4afb5ceSopenharmony_ci
983d4afb5ceSopenharmony_ci	case LSSPPT_AWS_SERVICE:
984d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->aws_service;
985d4afb5ceSopenharmony_ci		goto string2;
986d4afb5ceSopenharmony_ci#endif
987d4afb5ceSopenharmony_ci
988d4afb5ceSopenharmony_ci#endif
989d4afb5ceSopenharmony_ci
990d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_WS)
991d4afb5ceSopenharmony_ci
992d4afb5ceSopenharmony_ci	case LSSPPT_WS_SUBPROTOCOL:
993d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->u.http.u.ws.subprotocol;
994d4afb5ceSopenharmony_ci		goto string2;
995d4afb5ceSopenharmony_ci
996d4afb5ceSopenharmony_ci	case LSSPPT_WS_BINARY:
997d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->u.http.u.ws.binary =
998d4afb5ceSopenharmony_ci						reason == LEJPCB_VAL_TRUE;
999d4afb5ceSopenharmony_ci		break;
1000d4afb5ceSopenharmony_ci#endif
1001d4afb5ceSopenharmony_ci
1002d4afb5ceSopenharmony_ci	case LSSPPT_LOCAL_SINK:
1003d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
1004d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |= LWSSSPOLF_LOCAL_SINK;
1005d4afb5ceSopenharmony_ci		break;
1006d4afb5ceSopenharmony_ci
1007d4afb5ceSopenharmony_ci	case LSSPPT_SERVER:
1008d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
1009d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |= LWSSSPOLF_SERVER;
1010d4afb5ceSopenharmony_ci		break;
1011d4afb5ceSopenharmony_ci
1012d4afb5ceSopenharmony_ci#if defined(LWS_ROLE_MQTT)
1013d4afb5ceSopenharmony_ci	case LSSPPT_MQTT_TOPIC:
1014d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->u.mqtt.topic;
1015d4afb5ceSopenharmony_ci		goto string2;
1016d4afb5ceSopenharmony_ci
1017d4afb5ceSopenharmony_ci	case LSSPPT_MQTT_SUBSCRIBE:
1018d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->u.mqtt.subscribe;
1019d4afb5ceSopenharmony_ci		goto string2;
1020d4afb5ceSopenharmony_ci
1021d4afb5ceSopenharmony_ci	case LSSPPT_MQTT_QOS:
1022d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->u.mqtt.qos = (uint8_t)atoi(ctx->buf);
1023d4afb5ceSopenharmony_ci		break;
1024d4afb5ceSopenharmony_ci
1025d4afb5ceSopenharmony_ci	case LSSPPT_MQTT_RETAIN:
1026d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->u.mqtt.retain =
1027d4afb5ceSopenharmony_ci						reason == LEJPCB_VAL_TRUE;
1028d4afb5ceSopenharmony_ci		break;
1029d4afb5ceSopenharmony_ci
1030d4afb5ceSopenharmony_ci	case LSSPPT_MQTT_KEEPALIVE:
1031d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->u.mqtt.keep_alive = (uint16_t)atoi(ctx->buf);
1032d4afb5ceSopenharmony_ci		break;
1033d4afb5ceSopenharmony_ci
1034d4afb5ceSopenharmony_ci	case LSSPPT_MQTT_CLEAN_START:
1035d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->u.mqtt.clean_start =
1036d4afb5ceSopenharmony_ci						reason == LEJPCB_VAL_TRUE;
1037d4afb5ceSopenharmony_ci		break;
1038d4afb5ceSopenharmony_ci	case LSSPPT_MQTT_WILL_TOPIC:
1039d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->u.mqtt.will_topic;
1040d4afb5ceSopenharmony_ci		goto string2;
1041d4afb5ceSopenharmony_ci
1042d4afb5ceSopenharmony_ci	case LSSPPT_MQTT_WILL_MESSAGE:
1043d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->u.mqtt.will_message;
1044d4afb5ceSopenharmony_ci		goto string2;
1045d4afb5ceSopenharmony_ci
1046d4afb5ceSopenharmony_ci	case LSSPPT_MQTT_WILL_QOS:
1047d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->u.mqtt.will_qos = (uint8_t)atoi(ctx->buf);
1048d4afb5ceSopenharmony_ci		break;
1049d4afb5ceSopenharmony_ci	case LSSPPT_MQTT_WILL_RETAIN:
1050d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->u.mqtt.will_retain =
1051d4afb5ceSopenharmony_ci						reason == LEJPCB_VAL_TRUE;
1052d4afb5ceSopenharmony_ci		break;
1053d4afb5ceSopenharmony_ci	case LSSPPT_MQTT_BIRTH_TOPIC:
1054d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->u.mqtt.birth_topic;
1055d4afb5ceSopenharmony_ci		goto string2;
1056d4afb5ceSopenharmony_ci
1057d4afb5ceSopenharmony_ci	case LSSPPT_MQTT_BIRTH_MESSAGE:
1058d4afb5ceSopenharmony_ci		pp = (char **)&a->curr[LTY_POLICY].p->u.mqtt.birth_message;
1059d4afb5ceSopenharmony_ci		goto string2;
1060d4afb5ceSopenharmony_ci
1061d4afb5ceSopenharmony_ci	case LSSPPT_MQTT_BIRTH_QOS:
1062d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->u.mqtt.birth_qos = (uint8_t)atoi(ctx->buf);
1063d4afb5ceSopenharmony_ci		break;
1064d4afb5ceSopenharmony_ci	case LSSPPT_MQTT_BIRTH_RETAIN:
1065d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->u.mqtt.birth_retain =
1066d4afb5ceSopenharmony_ci						reason == LEJPCB_VAL_TRUE;
1067d4afb5ceSopenharmony_ci		break;
1068d4afb5ceSopenharmony_ci	case LSSPPT_MQTT_AWS_IOT:
1069d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
1070d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->u.mqtt.aws_iot =
1071d4afb5ceSopenharmony_ci						reason == LEJPCB_VAL_TRUE;
1072d4afb5ceSopenharmony_ci		break;
1073d4afb5ceSopenharmony_ci#endif
1074d4afb5ceSopenharmony_ci	case LSSPPT_DIRECT_PROTO_STR:
1075d4afb5ceSopenharmony_ci		if (reason == LEJPCB_VAL_TRUE)
1076d4afb5ceSopenharmony_ci			a->curr[LTY_POLICY].p->flags |=
1077d4afb5ceSopenharmony_ci					LWSSSPOLF_DIRECT_PROTO_STR;
1078d4afb5ceSopenharmony_ci		break;
1079d4afb5ceSopenharmony_ci
1080d4afb5ceSopenharmony_ci
1081d4afb5ceSopenharmony_ci	case LSSPPT_PROTOCOL:
1082d4afb5ceSopenharmony_ci		a->curr[LTY_POLICY].p->protocol = 0xff;
1083d4afb5ceSopenharmony_ci		for (n = 0; n < (int)LWS_ARRAY_SIZE(protonames); n++)
1084d4afb5ceSopenharmony_ci			if (strlen(protonames[n]) == ctx->npos &&
1085d4afb5ceSopenharmony_ci			    !strncmp(ctx->buf, protonames[n], ctx->npos))
1086d4afb5ceSopenharmony_ci				a->curr[LTY_POLICY].p->protocol = (uint8_t)n;
1087d4afb5ceSopenharmony_ci
1088d4afb5ceSopenharmony_ci		if (a->curr[LTY_POLICY].p->protocol != 0xff)
1089d4afb5ceSopenharmony_ci			break;
1090d4afb5ceSopenharmony_ci		lws_strnncpy(dotstar, ctx->buf, ctx->npos, sizeof(dotstar));
1091d4afb5ceSopenharmony_ci		lwsl_err("%s: unknown protocol name %s\n", __func__, dotstar);
1092d4afb5ceSopenharmony_ci		return -1;
1093d4afb5ceSopenharmony_ci
1094d4afb5ceSopenharmony_ci	default:
1095d4afb5ceSopenharmony_ci		break;
1096d4afb5ceSopenharmony_ci	}
1097d4afb5ceSopenharmony_ci
1098d4afb5ceSopenharmony_ci	return 0;
1099d4afb5ceSopenharmony_ci
1100d4afb5ceSopenharmony_cistring2:
1101d4afb5ceSopenharmony_ci	/*
1102d4afb5ceSopenharmony_ci	 * If we can do const string folding, reuse the existing string rather
1103d4afb5ceSopenharmony_ci	 * than make a new entry
1104d4afb5ceSopenharmony_ci	 */
1105d4afb5ceSopenharmony_ci	extant = lwsac_scan_extant(a->ac, (uint8_t *)ctx->buf, (size_t)ctx->npos, 1);
1106d4afb5ceSopenharmony_ci	if (extant) {
1107d4afb5ceSopenharmony_ci		*pp = (char *)extant;
1108d4afb5ceSopenharmony_ci
1109d4afb5ceSopenharmony_ci		return 0;
1110d4afb5ceSopenharmony_ci	}
1111d4afb5ceSopenharmony_ci	*pp = lwsac_use_backfill(&a->ac, (size_t)(ctx->npos + 1), POL_AC_GRAIN);
1112d4afb5ceSopenharmony_ci	if (!*pp)
1113d4afb5ceSopenharmony_ci		goto oom;
1114d4afb5ceSopenharmony_ci	memcpy(*pp, ctx->buf, ctx->npos);
1115d4afb5ceSopenharmony_ci	(*pp)[ctx->npos] = '\0';
1116d4afb5ceSopenharmony_ci
1117d4afb5ceSopenharmony_ci	return 0;
1118d4afb5ceSopenharmony_ci
1119d4afb5ceSopenharmony_cistring1:
1120d4afb5ceSopenharmony_ci	n = ctx->st[ctx->sp].p;
1121d4afb5ceSopenharmony_ci	*pp = lwsac_use_backfill(&a->ac, (size_t)ctx->path_match_len + (size_t)1 - (size_t)n,
1122d4afb5ceSopenharmony_ci				 POL_AC_GRAIN);
1123d4afb5ceSopenharmony_ci	if (!*pp)
1124d4afb5ceSopenharmony_ci		goto oom;
1125d4afb5ceSopenharmony_ci	memcpy(*pp, ctx->path + n, ctx->path_match_len - (unsigned int)n);
1126d4afb5ceSopenharmony_ci	(*pp)[ctx->path_match_len - n] = '\0';
1127d4afb5ceSopenharmony_ci
1128d4afb5ceSopenharmony_ci	return 0;
1129d4afb5ceSopenharmony_ci
1130d4afb5ceSopenharmony_cioom:
1131d4afb5ceSopenharmony_ci	lwsl_err("%s: OOM\n", __func__);
1132d4afb5ceSopenharmony_ci	lws_free_set_NULL(a->p);
1133d4afb5ceSopenharmony_ci	lwsac_free(&a->ac);
1134d4afb5ceSopenharmony_ci
1135d4afb5ceSopenharmony_ci	return -1;
1136d4afb5ceSopenharmony_ci}
1137d4afb5ceSopenharmony_ci
1138d4afb5ceSopenharmony_ciint
1139d4afb5ceSopenharmony_cilws_ss_policy_parse_begin(struct lws_context *context, int overlay)
1140d4afb5ceSopenharmony_ci{
1141d4afb5ceSopenharmony_ci	struct policy_cb_args *args;
1142d4afb5ceSopenharmony_ci	char *p;
1143d4afb5ceSopenharmony_ci
1144d4afb5ceSopenharmony_ci	args = lws_zalloc(sizeof(struct policy_cb_args), __func__);
1145d4afb5ceSopenharmony_ci	if (!args) {
1146d4afb5ceSopenharmony_ci		lwsl_err("%s: OOM\n", __func__);
1147d4afb5ceSopenharmony_ci
1148d4afb5ceSopenharmony_ci		return 1;
1149d4afb5ceSopenharmony_ci	}
1150d4afb5ceSopenharmony_ci	if (overlay)
1151d4afb5ceSopenharmony_ci		/* continue to use the existing lwsac */
1152d4afb5ceSopenharmony_ci		args->ac = context->ac_policy;
1153d4afb5ceSopenharmony_ci	else
1154d4afb5ceSopenharmony_ci		/* we don't want to see any old policy */
1155d4afb5ceSopenharmony_ci		context->pss_policies = NULL;
1156d4afb5ceSopenharmony_ci
1157d4afb5ceSopenharmony_ci	context->pol_args = args;
1158d4afb5ceSopenharmony_ci	args->context = context;
1159d4afb5ceSopenharmony_ci	p = lwsac_use(&args->ac, 1, POL_AC_INITIAL);
1160d4afb5ceSopenharmony_ci	if (!p) {
1161d4afb5ceSopenharmony_ci		lwsl_err("%s: OOM\n", __func__);
1162d4afb5ceSopenharmony_ci		lws_free_set_NULL(context->pol_args);
1163d4afb5ceSopenharmony_ci
1164d4afb5ceSopenharmony_ci		return -1;
1165d4afb5ceSopenharmony_ci	}
1166d4afb5ceSopenharmony_ci	*p = 0;
1167d4afb5ceSopenharmony_ci	lejp_construct(&args->jctx, lws_ss_policy_parser_cb, args,
1168d4afb5ceSopenharmony_ci		       lejp_tokens_policy, LWS_ARRAY_SIZE(lejp_tokens_policy));
1169d4afb5ceSopenharmony_ci
1170d4afb5ceSopenharmony_ci	return 0;
1171d4afb5ceSopenharmony_ci}
1172d4afb5ceSopenharmony_ci
1173d4afb5ceSopenharmony_ciint
1174d4afb5ceSopenharmony_cilws_ss_policy_parse_abandon(struct lws_context *context)
1175d4afb5ceSopenharmony_ci{
1176d4afb5ceSopenharmony_ci	struct policy_cb_args *args = (struct policy_cb_args *)context->pol_args;
1177d4afb5ceSopenharmony_ci	lws_ss_x509_t *x;
1178d4afb5ceSopenharmony_ci
1179d4afb5ceSopenharmony_ci	x = args->heads[LTY_X509].x;
1180d4afb5ceSopenharmony_ci	while (x) {
1181d4afb5ceSopenharmony_ci		/*
1182d4afb5ceSopenharmony_ci		 * Free all the client DER buffers now they have been parsed
1183d4afb5ceSopenharmony_ci		 * into tls library X.509 objects
1184d4afb5ceSopenharmony_ci		 */
1185d4afb5ceSopenharmony_ci		lws_free((void *)x->ca_der);
1186d4afb5ceSopenharmony_ci		x->ca_der = NULL;
1187d4afb5ceSopenharmony_ci
1188d4afb5ceSopenharmony_ci		x = x->next;
1189d4afb5ceSopenharmony_ci	}
1190d4afb5ceSopenharmony_ci
1191d4afb5ceSopenharmony_ci	x = context->server_der_list;
1192d4afb5ceSopenharmony_ci	while (x) {
1193d4afb5ceSopenharmony_ci		lws_free((void *)x->ca_der);
1194d4afb5ceSopenharmony_ci		x->ca_der = NULL;
1195d4afb5ceSopenharmony_ci
1196d4afb5ceSopenharmony_ci		x = x->next;
1197d4afb5ceSopenharmony_ci	}
1198d4afb5ceSopenharmony_ci
1199d4afb5ceSopenharmony_ci	lejp_destruct(&args->jctx);
1200d4afb5ceSopenharmony_ci	lwsac_free(&args->ac);
1201d4afb5ceSopenharmony_ci	lws_free_set_NULL(context->pol_args);
1202d4afb5ceSopenharmony_ci
1203d4afb5ceSopenharmony_ci	context->server_der_list = NULL;
1204d4afb5ceSopenharmony_ci
1205d4afb5ceSopenharmony_ci	return 0;
1206d4afb5ceSopenharmony_ci}
1207d4afb5ceSopenharmony_ci
1208d4afb5ceSopenharmony_ci#if !defined(LWS_PLAT_FREERTOS) && !defined(LWS_PLAT_OPTEE)
1209d4afb5ceSopenharmony_ciint
1210d4afb5ceSopenharmony_cilws_ss_policy_parse_file(struct lws_context *cx, const char *filepath)
1211d4afb5ceSopenharmony_ci{
1212d4afb5ceSopenharmony_ci	struct policy_cb_args *args = (struct policy_cb_args *)cx->pol_args;
1213d4afb5ceSopenharmony_ci	uint8_t buf[512];
1214d4afb5ceSopenharmony_ci	int n, m, fd = lws_open(filepath, LWS_O_RDONLY);
1215d4afb5ceSopenharmony_ci
1216d4afb5ceSopenharmony_ci	if (fd < 0)
1217d4afb5ceSopenharmony_ci		return LEJP_REJECT_UNKNOWN;
1218d4afb5ceSopenharmony_ci
1219d4afb5ceSopenharmony_ci	do {
1220d4afb5ceSopenharmony_ci		n = (int)read(fd, buf, sizeof(buf));
1221d4afb5ceSopenharmony_ci		if (n < 0) {
1222d4afb5ceSopenharmony_ci			m = -1;
1223d4afb5ceSopenharmony_ci			goto bail;
1224d4afb5ceSopenharmony_ci		}
1225d4afb5ceSopenharmony_ci
1226d4afb5ceSopenharmony_ci		m = lejp_parse(&args->jctx, buf, n);
1227d4afb5ceSopenharmony_ci		if (m != LEJP_CONTINUE && m < 0) {
1228d4afb5ceSopenharmony_ci			lwsl_err("%s: parse failed line %u: %d: %s\n", __func__,
1229d4afb5ceSopenharmony_ci				 (unsigned int)args->jctx.line, m,
1230d4afb5ceSopenharmony_ci				 lejp_error_to_string(m));
1231d4afb5ceSopenharmony_ci			lws_ss_policy_parse_abandon(cx);
1232d4afb5ceSopenharmony_ci
1233d4afb5ceSopenharmony_ci			m = -1;
1234d4afb5ceSopenharmony_ci			goto bail;
1235d4afb5ceSopenharmony_ci		}
1236d4afb5ceSopenharmony_ci
1237d4afb5ceSopenharmony_ci		if (m != LEJP_CONTINUE)
1238d4afb5ceSopenharmony_ci			break;
1239d4afb5ceSopenharmony_ci	} while (n);
1240d4afb5ceSopenharmony_ci
1241d4afb5ceSopenharmony_ci	m = 0;
1242d4afb5ceSopenharmony_cibail:
1243d4afb5ceSopenharmony_ci	close(fd);
1244d4afb5ceSopenharmony_ci
1245d4afb5ceSopenharmony_ci	return m;
1246d4afb5ceSopenharmony_ci}
1247d4afb5ceSopenharmony_ci#endif
1248d4afb5ceSopenharmony_ci
1249d4afb5ceSopenharmony_ciint
1250d4afb5ceSopenharmony_cilws_ss_policy_parse(struct lws_context *context, const uint8_t *buf, size_t len)
1251d4afb5ceSopenharmony_ci{
1252d4afb5ceSopenharmony_ci	struct policy_cb_args *args = (struct policy_cb_args *)context->pol_args;
1253d4afb5ceSopenharmony_ci	int m;
1254d4afb5ceSopenharmony_ci
1255d4afb5ceSopenharmony_ci#if !defined(LWS_PLAT_FREERTOS) && !defined(LWS_PLAT_OPTEE)
1256d4afb5ceSopenharmony_ci	if (args->jctx.line < 2 && buf[0] != '{' && !args->parse_data)
1257d4afb5ceSopenharmony_ci		return lws_ss_policy_parse_file(context, (const char *)buf);
1258d4afb5ceSopenharmony_ci#endif
1259d4afb5ceSopenharmony_ci
1260d4afb5ceSopenharmony_ci	args->parse_data = 1;
1261d4afb5ceSopenharmony_ci	m = lejp_parse(&args->jctx, buf, (int)len);
1262d4afb5ceSopenharmony_ci	if (m == LEJP_CONTINUE || m >= 0)
1263d4afb5ceSopenharmony_ci		return m;
1264d4afb5ceSopenharmony_ci
1265d4afb5ceSopenharmony_ci	lwsl_err("%s: parse failed line %u: %d: %s\n", __func__,
1266d4afb5ceSopenharmony_ci		 (unsigned int)args->jctx.line, m, lejp_error_to_string(m));
1267d4afb5ceSopenharmony_ci	lws_ss_policy_parse_abandon(context);
1268d4afb5ceSopenharmony_ci	assert(0);
1269d4afb5ceSopenharmony_ci
1270d4afb5ceSopenharmony_ci	return m;
1271d4afb5ceSopenharmony_ci}
1272d4afb5ceSopenharmony_ci
1273d4afb5ceSopenharmony_ciint
1274d4afb5ceSopenharmony_cilws_ss_policy_overlay(struct lws_context *context, const char *overlay)
1275d4afb5ceSopenharmony_ci{
1276d4afb5ceSopenharmony_ci	lws_ss_policy_parse_begin(context, 1);
1277d4afb5ceSopenharmony_ci	return lws_ss_policy_parse(context, (const uint8_t *)overlay,
1278d4afb5ceSopenharmony_ci				   strlen(overlay));
1279d4afb5ceSopenharmony_ci}
1280d4afb5ceSopenharmony_ci
1281d4afb5ceSopenharmony_ciconst lws_ss_policy_t *
1282d4afb5ceSopenharmony_cilws_ss_policy_get(struct lws_context *context)
1283d4afb5ceSopenharmony_ci{
1284d4afb5ceSopenharmony_ci	struct policy_cb_args *args = (struct policy_cb_args *)context->pol_args;
1285d4afb5ceSopenharmony_ci
1286d4afb5ceSopenharmony_ci	if (!args)
1287d4afb5ceSopenharmony_ci		return NULL;
1288d4afb5ceSopenharmony_ci
1289d4afb5ceSopenharmony_ci	return args->heads[LTY_POLICY].p;
1290d4afb5ceSopenharmony_ci}
1291d4afb5ceSopenharmony_ci
1292d4afb5ceSopenharmony_ciconst lws_ss_auth_t *
1293d4afb5ceSopenharmony_cilws_ss_auth_get(struct lws_context *context)
1294d4afb5ceSopenharmony_ci{
1295d4afb5ceSopenharmony_ci	struct policy_cb_args *args = (struct policy_cb_args *)context->pol_args;
1296d4afb5ceSopenharmony_ci
1297d4afb5ceSopenharmony_ci	if (!args)
1298d4afb5ceSopenharmony_ci		return NULL;
1299d4afb5ceSopenharmony_ci
1300d4afb5ceSopenharmony_ci	return args->heads[LTY_AUTH].a;
1301d4afb5ceSopenharmony_ci}
1302