libwebsockets
Lightweight C library for HTML5 websockets
lws-secure-streams-policy.h
Go to the documentation of this file.
1/*
2 * libwebsockets - small server side websockets and web server implementation
3 *
4 * Copyright (C) 2019 - 2021 Andy Green <andy@warmcat.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 *
24 * included from libwebsockets.h
25 */
26
27typedef int (*plugin_auth_status_cb)(struct lws_ss_handle *ss, int status);
28
29/**
30 * lws_ss_plugin_auth_t - api for an auth plugin
31 *
32 * Auth plugins create and sequence authenticated connections that can carry one
33 * or more streams to an endpoint. That may involve other connections to other
34 * places to eg, gather authenticated tokens and then make the real connection
35 * using the tokens.
36 *
37 * The secure stream object contains members to record which auth plugin the
38 * stream is bound to and an over-allocation of the secure stream object to
39 * contain the plugin auth private data.
40 *
41 * The auth plugin controls the state of the stream connection via the status
42 * callback, and handles retries.
43 *
44 * Network connections may require one kind of auth sequencing, and streams
45 * inside those connections another kind of auth sequencing depending on their
46 * role. So the secure stream object allows defining plugins for both kinds.
47 *
48 * Streams may disappear at any time and require reauth to bring a new one up.
49 * The auth plugin sequencer will connect / reconnect either on demand, or from
50 * the start and after any connectivity loss if any stream using the connection
51 * has the LWSSSPOLF_NAILED_UP flag.
52 */
53
54/* the public, const metrics policy definition */
55
56typedef struct lws_metric_policy {
57 /* order of first two mandated by JSON policy parsing scope union */
58 const struct lws_metric_policy *next;
59 const char *name;
60
61 const char *report;
62
63 /**< the metrics policy name in the policy, used to bind to it */
65 /**< us interval between lws_system metrics api reports */
66
68 /**< how many us to decay avg by half, 0 = no decay */
70 /**< before we can judge something is an outlier */
71} lws_metric_policy_t;
72
73typedef struct lws_ss_x509 {
75 const char *vhost_name; /**< vhost name using cert ctx */
76 const uint8_t *ca_der; /**< DER x.509 cert */
77 size_t ca_der_len; /**< length of DER cert */
78 uint8_t keep:1; /**< ie, if used in server tls */
79} lws_ss_x509_t;
80
81enum {
82 LWSSSPOLF_OPPORTUNISTIC = (1 << 0),
83 /**< the connection doesn't exist unless client asks to write */
84 LWSSSPOLF_NAILED_UP = (1 << 1),
85 /**< the connection tries to be connected the whole life of the ss */
86 LWSSSPOLF_URGENT_TX = (1 << 2),
87 /**< this connection carries critical tx data */
88 LWSSSPOLF_URGENT_RX = (1 << 3),
89 /**< this connection carries critical rx data */
90 LWSSSPOLF_TLS = (1 << 4),
91 /**< stream must be connected via a tls tunnel */
92 LWSSSPOLF_LONG_POLL = (1 << 5),
93 /**< stream used to receive async rx at arbitrary intervals */
94 LWSSSPOLF_AUTH_BEARER = (1 << 6),
95 /**< for http, use lws_system auth token 0 in authentication: bearer */
97 /**< don't add any content length even if we have it */
99 /**< set the client flag LCCSCF_H2_QUIRK_NGHTTP2_END_STREAM */
101 /**< set the client flag LCCSCF_H2_QUIRK_OVERFLOWS_TXCR */
103 /**< HPACK decoder state does not end cleanly */
104 LWSSSPOLF_HTTP_MULTIPART = (1 << 11),
105 /**< indicates stream goes out as specifically a multipart mime POST
106 * section... if the tx has LWSSS_FLAG_COALESCE_CONTINUES flag then more
107 * multipart sections are expected. Without it, the multipart wrapper
108 * is closed and the http transaction issue completed when this message
109 * finishes. */
111 /**< set up lws_system client cert */
112 LWSSSPOLF_LOCAL_SINK = (1 << 13),
113 /**< expected to bind to a local sink only */
115 /**< this stream's idle validity checks are critical enough we
116 * should arrange to wake from suspend to perform them
117 */
118 LWSSSPOLF_SERVER = (1 << 15),
119 /**< we listen on a socket as a server */
120 LWSSSPOLF_ALLOW_REDIRECTS = (1 << 16),
121 /**< follow redirects */
122 LWSSSPOLF_HTTP_MULTIPART_IN = (1 << 17),
123 /**< handle inbound multipart mime at SS level */
124
125 LWSSSPOLF_ATTR_LOW_LATENCY = (1 << 18),
126 /**< stream requires low latency */
128 /**< stream requires high throughput */
130 /**< stream requires high reliability */
131 LWSSSPOLF_ATTR_LOW_COST = (1 << 21),
132 /**< stream is not critical and should be handled as cheap as poss */
133 LWSSSPOLF_PERF = (1 << 22),
134 /**< capture and report performace information */
135 LWSSSPOLF_DIRECT_PROTO_STR = (1 << 23),
136 /**< metadata as direct protocol string, e.g. http header */
138 /**< Record http cookies and pass them back on future requests */
139 LWSSSPOLF_PRIORITIZE_READS = (1 << 25),
140 /**< prioritize clearing reads at expense of writes */
141
142};
143
144typedef struct lws_ss_trust_store {
146 const char *name;
147
148 const lws_ss_x509_t *ssx509[6];
149 int count;
150} lws_ss_trust_store_t;
151
152enum {
158
159
164
165 _LWSSS_HBI_COUNT /* always last */
167
168/*
169 * This does for both the static policy metadata entry, and the runtime metadata
170 * handling object.
171 */
172
173typedef struct lws_ss_metadata {
175 const char *name;
178
179 uint8_t value_length; /* only valid if set by policy */
180 uint8_t value_is_http_token; /* valid if set by policy */
181#if defined(LWS_WITH_SS_DIRECT_PROTOCOL_STR)
182 uint8_t name_on_lws_heap:1; /* proxy metatadata does this */
183#endif
184 uint8_t value_on_lws_heap:1; /* proxy + rx metadata does this */
185#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
187#endif
188} lws_ss_metadata_t;
189
190typedef struct lws_ss_http_respmap {
191 uint16_t resp; /* the http response code */
192 uint16_t state; /* low 16-bits of associated state */
193} lws_ss_http_respmap_t;
194
195/*
196 * This is a mapping between an auth streamtype and a name and other information
197 * that can be independently instantiated. Other streamtypes can indicate they
198 * require this authentication on their connection.
199 */
200
201typedef struct lws_ss_auth {
203 const char *name;
204
205 const char *type;
206 const char *streamtype;
208} lws_ss_auth_t;
209
210/**
211 * lws_ss_policy_t: policy database entry for a stream type
212 *
213 * Decides the system policy for how to implement connections of name
214 * .streamtype.
215 *
216 * Streams may need one kind of auth sequencing for the network connection and
217 * another kind of auth sequencing for the streams that are carried inside it,
218 * this is the purpose of .nauth and .sauth. Both are optional and may be NULL.
219 *
220 * An array of these is set at context creation time, ending with one with a
221 * NULL streamtype.
222 */
223typedef struct lws_ss_policy {
225 const char *streamtype; /**< stream type lhs to match on */
226
227 const char *endpoint; /**< DNS address to connect to */
228 const char *rideshare_streamtype; /**< optional transport
229 * on another, preexisting stream of this
230 * streamtype name */
231 const char *payload_fmt;
232 const char *socks5_proxy;
233 lws_ss_metadata_t *metadata; /* linked-list of metadata */
234 const lws_metric_policy_t *metrics; /* linked-list of metric policies */
235 const lws_ss_auth_t *auth; /* NULL or auth object we bind to */
236
237#if defined(LWS_WITH_SERVER)
238 const struct lws_protocol_vhost_options *pvo;
239#endif
240
241 /* protocol-specific connection policy details */
242
243 union {
244
245#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) || defined(LWS_ROLE_WS)
246
247 /* details for http-related protocols... */
248
249 struct {
250
251 /* common to all http-related protocols */
252
253 const char *method;
254 const char *url;
255
256 const char *multipart_name;
257 const char *multipart_filename;
258 const char *multipart_content_type;
259
260 const char *blob_header[_LWSSS_HBI_COUNT];
261 const char *auth_preamble;
262
263 const lws_ss_http_respmap_t *respmap;
264
265 union {
266// struct { /* LWSSSP_H1 */
267// } h1;
268// struct { /* LWSSSP_H2 */
269// } h2;
270 struct { /* LWSSSP_WS */
271 const char *subprotocol;
272 uint8_t binary;
273 /* false = TEXT, true = BINARY */
274 } ws;
275 } u;
276
277 uint16_t resp_expect;
278 uint8_t count_respmap;
279 uint8_t fail_redirect:1;
280 } http;
281
282#endif
283
284#if defined(LWS_ROLE_MQTT)
285
286 struct {
287 const char *topic; /* stream sends on this topic */
288 const char *subscribe; /* stream subscribes to this topic */
289
290 const char *will_topic;
291 const char *will_message;
292
293 const char *birth_topic;
294 const char *birth_message;
295
296 uint16_t keep_alive;
297 uint8_t qos;
298 uint8_t clean_start;
299 uint8_t will_qos;
300 uint8_t will_retain;
301 uint8_t birth_qos;
302 uint8_t birth_retain;
303 uint8_t aws_iot;
304 uint8_t retain;
305
306 } mqtt;
307
308#endif
309
310 /* details for non-http related protocols... */
311 } u;
312
313#if defined(LWS_WITH_SECURE_STREAMS_AUTH_SIGV4)
314 /* directly point to the metadata name, no need to expand */
315 const char *aws_region;
316 const char *aws_service;
317#endif
318 /*
319 * We're either a client connection policy that wants a trust store,
320 * or we're a server policy that wants a mem cert and key... Hold
321 * these mutually-exclusive things in a union.
322 */
323
324 union {
325 const lws_ss_trust_store_t *store;
326 /**< CA certs needed for conn validation, only set between
327 * policy parsing and vhost creation */
328 struct {
329 const lws_ss_x509_t *cert;
330 /**< the server's signed cert with the pubkey */
331 const lws_ss_x509_t *key;
332 /**< the server's matching private key */
333 } server;
334 } trust;
335
336 const lws_retry_bo_t *retry_bo; /**< retry policy to use */
337
340
341 uint32_t proxy_buflen; /**< max dsh alloc for proxy */
344
345 uint32_t client_buflen; /**< max dsh alloc for client */
348
349 uint32_t timeout_ms; /**< default message response
350 * timeout in ms */
351 uint32_t flags; /**< stream attribute flags */
352
353 uint16_t port; /**< endpoint port */
354
355 uint8_t metadata_count; /**< metadata count */
356 uint8_t protocol; /**< protocol index */
357 uint8_t client_cert; /**< which client cert to apply
358 0 = none, 1+ = cc 0+ */
359 uint8_t priority; /* 0 = normal, 6 = max normal,
360 * 7 = network management */
361} lws_ss_policy_t;
362
363#if !defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
364
365/*
366 * These only exist / have meaning if there's a dynamic JSON policy enabled
367 */
368
369LWS_VISIBLE LWS_EXTERN int
370lws_ss_policy_parse_begin(struct lws_context *context, int overlay);
371
372LWS_VISIBLE LWS_EXTERN int
373lws_ss_policy_parse_abandon(struct lws_context *context);
374
375LWS_VISIBLE LWS_EXTERN int
376lws_ss_policy_parse(struct lws_context *context, const uint8_t *buf, size_t len);
377
378LWS_VISIBLE LWS_EXTERN int
379lws_ss_policy_overlay(struct lws_context *context, const char *overlay);
380
381/*
382 * You almost certainly don't want these, they return the first policy or auth
383 * object in a linked-list of objects created by lws_ss_policy_parse above,
384 * they are exported to generate static policy with
385 */
386LWS_VISIBLE LWS_EXTERN const lws_ss_policy_t *
387lws_ss_policy_get(struct lws_context *context);
388
389LWS_VISIBLE LWS_EXTERN const lws_ss_auth_t *
390lws_ss_auth_get(struct lws_context *context);
391
392#endif
uint32_t client_buflen_rxflow_off_below
struct lws_ss_x509 * next
struct lws_ss_metadata * next
LWS_VISIBLE LWS_EXTERN int lws_ss_policy_overlay(struct lws_context *context, const char *overlay)
uint32_t client_buflen_rxflow_on_above
const lws_ss_x509_t * ssx509[6]
const lws_metric_policy_t * metrics
lws_ss_metadata_t * metadata
struct lws_ss_trust_store * next
@ LWSSSPOLF_HTTP_CACHE_COOKIES
@ LWSSSPOLF_OPPORTUNISTIC
@ LWSSSPOLF_ATTR_HIGH_RELIABILITY
@ LWSSSPOLF_H2_QUIRK_UNCLEAN_HPACK_STATE
@ LWSSSPOLF_WAKE_SUSPEND__VALIDITY
@ LWSSSPOLF_ALLOW_REDIRECTS
@ LWSSSPOLF_ATTR_LOW_LATENCY
@ LWSSSPOLF_AUTH_BEARER
@ LWSSSPOLF_QUIRK_NGHTTP2_END_STREAM
@ LWSSSPOLF_LONG_POLL
@ LWSSSPOLF_HTTP_MULTIPART_IN
@ LWSSSPOLF_URGENT_TX
@ LWSSSPOLF_NAILED_UP
@ LWSSSPOLF_URGENT_RX
@ LWSSSPOLF_ATTR_LOW_COST
@ LWSSSPOLF_LOCAL_SINK
@ LWSSSPOLF_HTTP_X_WWW_FORM_URLENCODED
@ LWSSSPOLF_HTTP_NO_CONTENT_LENGTH
@ LWSSSPOLF_HTTP_MULTIPART
@ LWSSSPOLF_PRIORITIZE_READS
@ LWSSSPOLF_DIRECT_PROTO_STR
@ LWSSSPOLF_H2_QUIRK_OVERFLOWS_TXCR
@ LWSSSPOLF_ATTR_HIGH_THROUGHPUT
LWS_VISIBLE LWS_EXTERN int lws_ss_policy_parse_abandon(struct lws_context *context)
uint32_t proxy_buflen_rxflow_off_below
struct lws_ss_auth * next
const char * rideshare_streamtype
LWS_VISIBLE LWS_EXTERN const lws_ss_auth_t * lws_ss_auth_get(struct lws_context *context)
LWS_VISIBLE LWS_EXTERN int lws_ss_policy_parse_begin(struct lws_context *context, int overlay)
const lws_retry_bo_t * retry_bo
int(* plugin_auth_status_cb)(struct lws_ss_handle *ss, int status)
const lws_ss_auth_t * auth
LWS_VISIBLE LWS_EXTERN const lws_ss_policy_t * lws_ss_policy_get(struct lws_context *context)
const uint8_t * ca_der
struct lws_ss_policy * next
LWS_VISIBLE LWS_EXTERN int lws_ss_policy_parse(struct lws_context *context, const uint8_t *buf, size_t len)
const struct lws_metric_policy * next