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 
27 typedef 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 
56 typedef 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 
73 typedef struct lws_ss_x509 {
74  struct lws_ss_x509 *next;
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 
81 enum {
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 */
127  LWSSSPOLF_ATTR_HIGH_THROUGHPUT = (1 << 19),
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 */
137  LWSSSPOLF_HTTP_CACHE_COOKIES = (1 << 24),
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 
144 typedef 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 
152 enum {
158 
159 
164 
165  _LWSSS_HBI_COUNT /* always last */
166 };
167 
168 /*
169  * This does for both the static policy metadata entry, and the runtime metadata
170  * handling object.
171  */
172 
173 typedef 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 
190 typedef 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 
201 typedef struct lws_ss_auth {
202  struct lws_ss_auth *next;
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  */
223 typedef 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 
369 LWS_VISIBLE LWS_EXTERN int
370 lws_ss_policy_parse_begin(struct lws_context *context, int overlay);
371 
372 LWS_VISIBLE LWS_EXTERN int
373 lws_ss_policy_parse_abandon(struct lws_context *context);
374 
375 LWS_VISIBLE LWS_EXTERN int
376 lws_ss_policy_parse(struct lws_context *context, const uint8_t *buf, size_t len);
377 
378 LWS_VISIBLE LWS_EXTERN int
379 lws_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  */
386 LWS_VISIBLE LWS_EXTERN const lws_ss_policy_t *
387 lws_ss_policy_get(struct lws_context *context);
388 
389 LWS_VISIBLE LWS_EXTERN const lws_ss_auth_t *
390 lws_ss_auth_get(struct lws_context *context);
391 
392 #endif