1/*
2 * libwebsockets - small server side websockets and web server implementation
3 *
4 * Copyright (C) 2019 - 2020 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 * Secure Streams is a *payload-only* client communication channel where all the
28 * details about the connection are held in a systemwide policy database and
29 * are keyed by the streamtype field... the user of the communication channel
30 * does not know or manage the choice of endpoint, tls CA, or even wire
31 * protocol. The advantage is he then does not have any dependency on any of
32 * those and they can be changed just by changing the policy database without
33 * touching the code using the stream.
34 *
35 * There are two ways secure streams interfaces to user code:
36 *
37 * 1) [Linux / RTOS] the natural, smallest interface is to call back to user
38 * code that only operates directly from the lws event loop thread context
39 * (direct callbacks from lws_ss_t)
40 *
41 * lws_thread( [user code] ---- lws )
42 *
43 * 2) [Linux] where the user code is in a different process and communicates
44 * asynchronously via a proxy socket
45 *
46 * user_process{ [user code] | shim | socket-}------ lws_process{ lws }
47 *
48 * In the second, IPC, case, all packets are prepended by one or more bytes
49 * indicating the packet type and serializing any associated data, known as
50 * Serialized Secure Streams or SSS.
51 *
52 * Serialized Secure Streams
53 * -------------------------
54 *
55 * On the transport, adjacent packets may be coalesced, that is, the original
56 * packet sizes are lost and two or more packets are combined. For that reason
57 * the serialization format always contains a 1-byte type and then a 2-byte
58 * frame length.
59 *
60 * Client to proxy
61 *
62 * - Proxied connection setup
63 *
64 * - 0: LWSSS_SER_TXPRE_STREAMTYPE
65 * - 1: 2-byte MSB-first rest-of-frame length
66 * - 3: 1-byte Client SSS protocol version (introduced in SSSv1)
67 * - 4: 4-byte Client PID (introduced in SSSv1)
68 * - 8: 4-byte MSB-first initial tx credit
69 * - 12: the streamtype name with no NUL
70 *
71 * - Proxied tx
72 *
73 * - 0: LWSSS_SER_TXPRE_TX_PAYLOAD
74 * - 1: 2 byte MSB-first rest-of-frame length
75 * - 3: 4-byte MSB-first flags
76 * - 7: 4-byte MSB-first us between client requested write and wrote to proxy
77 * - 11: 8-byte MSB-first us resolution unix time client wrote to proxy
78 * - 19: payload
79 *
80 * - Proxied secure stream destroy
81 *
82 * - 0: LWSSS_SER_TXPRE_DESTROYING
83 * - 1: 00, 00
84 *
85 * - Proxied metadata - sent when one metadata item set clientside
86 *
87 * - 0: LWSSS_SER_TXPRE_METADATA
88 * - 1: 2-byte MSB-first rest-of-frame length
89 * - 3: 1-byte metadata name length
90 * - 4: metadata name
91 * - ...: metadata value (for rest of packet)
92 *
93 * - TX credit management - sent when using tx credit apis, cf METADATA
94 *
95 * - 0: LWSSS_SER_TXPRE_TXCR_UPDATE
96 * - 1: 2-byte MSB-first rest-of-frame length 00, 04
97 * - 3: 4-byte additional tx credit adjust value
98 *
99 * - Stream timeout management - forwarded when user applying or cancelling t.o.
100 *
101 * - 0: LWSSS_SER_TXPRE_TIMEOUT_UPDATE
102 * - 1: 2-byte MSB-first rest-of-frame length 00, 04
103 * - 3: 4-byte MSB-first unsigned 32-bit timeout, 0 = use policy, -1 = cancel
104 *
105 * - Passing up payload length hint
106 *
107 * - 0: LWSSS_SER_TXPRE_PAYLOAD_LENGTH_HINT
108 * - 1: 2-byte MSB-first rest-of-frame length 00, 04
109 * - 3: 4-byte MSB-first unsigned 32-bit payload length hint
110 *
111 * Proxy to client
112 *
113 * - Proxied connection setup result
114 *
115 * - 0: LWSSS_SER_RXPRE_CREATE_RESULT
116 * - 1: 2 byte MSB-first rest-of-frame length (usually 00, 03)
117 * - 3: 1 byte result, 0 = success. On failure, proxy will close connection.
118 * - 4: 4 byte client dsh allocation recommended for stream type, from policy
119 * (introduced in SSSv1)
120 * - 8: 2 byte MSB-first initial tx credit
121 * - 10: if present, comma-sep list of rideshare types from policy
122 *
123 * - Proxied rx
124 *
125 * - 0: LWSSS_SER_RXPRE_RX_PAYLOAD
126 * - 1: 2 byte MSB-first rest-of-frame length
127 * - 3: 4-byte MSB-first flags
128 * - 7: 4-byte MSB-first us between inbound read and wrote to client
129 * - 11: 8-byte MSB-first us resolution unix time proxy wrote to client
130 * - 17: (rideshare name len + rideshare name if flags & LWSSS_FLAG_RIDESHARE)
131 * payload
132 *
133 * - Proxied tx credit
134 *
135 * - 0: LWSSS_SER_RXPRE_TXCR_UPDATE
136 * - 1: 00, 04
137 * - 3: 4-byte MSB-first addition tx credit bytes
138 *
139 * - Proxied rx metadata
140 *
141 * - 0: LWSSS_SER_RXPRE_METADATA
142 * - 1: 2-byte MSB-first rest-of-frame length
143 * - 3: 1-byte metadata name length
144 * - 4: metadata name
145 * - ...: metadata value (for rest of packet)
146 *
147 * - Proxied state (8 or 11 byte packet)
148 *
149 * - 0: LWSSS_SER_RXPRE_CONNSTATE
150 * - 1: 00, 05 if state < 256, else 00, 08
151 * - 3: 1 byte state index if state < 256, else 4-byte MSB-first state index
152 * - 4 or 7: 4-byte MSB-first ordinal
153 *
154 * - Proxied performance information
155 *
156 * - 0: LWSSS_SER_RXPRE_PERF
157 * - 1: 2-byte MSB-first rest-of-frame length
158 * - 3: ... performance JSON (for rest of packet)
159 *
160 * Proxied tx may be read by the proxy but rejected due to lack of buffer space
161 * at the proxy. For that reason, tx must be held at the sender until it has
162 * been acknowledged or denied.
163 *
164 * Sinks
165 * -----
166 *
167 * Sinks are logical "servers", you can register as a sink for a particular
168 * streamtype by using the lws_ss_create() api with ssi->register_sink set to 1.
169 *
170 * For directly fulfilled Secure Streams, new streams of that streamtype bind
171 * to the rx, tx and state handlers given when it was registered.
172 *
173 * - When new streams are created the registered sink handler for (*state) is
174 * called with event LWSSSCS_SINK_JOIN and the new client stream handle in
175 * the h_src parameter.
176 *
177 * - When the client stream sends something to the sink, it calls the sink's
178 * (*rx) with the client stream's
179 */
180
181/** \defgroup secstr Secure Streams
182* ##Secure Streams
183*
184* Secure Streams related apis
185*/
186///@{
187
188#define LWS_SS_MTU 1540
189
190struct lws_ss_handle;
191typedef uint32_t lws_ss_tx_ordinal_t;
192
193/*
194 * connection state events
195 *
196 * If you add states, take care about the state names and state transition
197 * validity enforcement tables too
198 */
199typedef enum {
200 /* zero means unset */
201 LWSSSCS_CREATING = 1,
202 LWSSSCS_DISCONNECTED,
203 LWSSSCS_UNREACHABLE, /* oridinal arg = 1 = caused by dns
204 * server reachability failure */
205 LWSSSCS_AUTH_FAILED,
206 LWSSSCS_CONNECTED,
207 LWSSSCS_CONNECTING,
208 LWSSSCS_DESTROYING,
209 LWSSSCS_POLL,
210 LWSSSCS_ALL_RETRIES_FAILED, /* all retries in bo policy failed */
211 LWSSSCS_QOS_ACK_REMOTE, /* remote peer received and acked tx */
212 LWSSSCS_QOS_NACK_REMOTE,
213 LWSSSCS_QOS_ACK_LOCAL, /* local proxy accepted our tx */
214 LWSSSCS_QOS_NACK_LOCAL, /* local proxy refused our tx */
215 LWSSSCS_TIMEOUT, /* optional timeout timer fired */
216
217 LWSSSCS_SERVER_TXN,
218 LWSSSCS_SERVER_UPGRADE, /* the server protocol upgraded */
219
220 LWSSSCS_EVENT_WAIT_CANCELLED, /* somebody called lws_cancel_service */
221
222 LWSSSCS_UPSTREAM_LINK_RETRY, /* if we are being proxied over some
223 * intermediate link, this transient
224 * state may be sent to indicate we are
225 * waiting to establish that link before
226 * creation can proceed.. ack is the
227 * number of ms we have been trying */
228
229 LWSSSCS_SINK_JOIN, /* sinks get this when a new source
230 * stream joins the sink */
231 LWSSSCS_SINK_PART, /* sinks get this when a new source
232 * stream leaves the sink */
233
234 LWSSSCS_USER_BASE = 1000
235} lws_ss_constate_t;
236
237enum {
238 LWSSS_FLAG_SOM = (1 << 0),
239 /* payload contains the start of new message */
240 LWSSS_FLAG_EOM = (1 << 1),
241 /* payload contains the end of message */
242 LWSSS_FLAG_POLL = (1 << 2),
243 /* Not a real transmit... poll for rx if protocol needs it */
244 LWSSS_FLAG_RELATED_START = (1 << 3),
245 /* Appears in a zero-length message indicating a message group of zero
246 * or more messages is now starting. */
247 LWSSS_FLAG_RELATED_END = (1 << 4),
248 /* Appears in a zero-length message indicating a message group of zero
249 * or more messages has now finished. */
250 LWSSS_FLAG_RIDESHARE = (1 << 5),
251 /* Serialized payload starts with non-default rideshare name length and
252 * name string without NUL, then payload */
253 LWSSS_FLAG_PERF_JSON = (1 << 6),
254 /* This RX is JSON performance data, only on streams with "perf" flag
255 * set */
256
257 /*
258 * In the case the secure stream is proxied across a process or thread
259 * boundary, eg by proxying through a socket for IPC, metadata must be
260 * carried in-band. A byte is prepended to each rx payload to
261 * differentiate what it is.
262 *
263 * Secure streams where the user is called back directly does not need
264 * any of this and only pure payloads are passed.
265 *
266 * rx (received by client) prepends for proxied connections
267 */
268
269 LWSSS_SER_RXPRE_RX_PAYLOAD = 0x55,
270 LWSSS_SER_RXPRE_CREATE_RESULT,
271 LWSSS_SER_RXPRE_CONNSTATE,
272 LWSSS_SER_RXPRE_TXCR_UPDATE,
273 LWSSS_SER_RXPRE_METADATA,
274 LWSSS_SER_RXPRE_TLSNEG_ENCLAVE_SIGN,
275 LWSSS_SER_RXPRE_PERF,
276
277 /* tx (send by client) prepends for proxied connections */
278
279 LWSSS_SER_TXPRE_STREAMTYPE = 0xaa,
280 LWSSS_SER_TXPRE_ONWARD_CONNECT,
281 LWSSS_SER_TXPRE_DESTROYING,
282 LWSSS_SER_TXPRE_TX_PAYLOAD,
283 LWSSS_SER_TXPRE_METADATA,
284 LWSSS_SER_TXPRE_TXCR_UPDATE,
285 LWSSS_SER_TXPRE_TIMEOUT_UPDATE,
286 LWSSS_SER_TXPRE_PAYLOAD_LENGTH_HINT,
287 LWSSS_SER_TXPRE_TLSNEG_ENCLAVE_SIGNED,
288};
289
290typedef enum {
291 LPCSPROX_WAIT_INITIAL_TX = 1, /* after connect, must send streamtype */
292 LPCSPROX_REPORTING_FAIL, /* stream creation failed, wait to to tell */
293 LPCSPROX_REPORTING_OK, /* stream creation succeeded, wait to to tell */
294 LPCSPROX_OPERATIONAL, /* ready for payloads */
295 LPCSPROX_DESTROYED,
296
297 LPCSCLI_SENDING_INITIAL_TX, /* after connect, must send streamtype */
298 LPCSCLI_WAITING_CREATE_RESULT, /* wait to hear if proxy ss create OK */
299 LPCSCLI_LOCAL_CONNECTED, /* we are in touch with the proxy */
300 LPCSCLI_ONWARD_CONNECT, /* request onward ss connection */
301 LPCSCLI_OPERATIONAL, /* ready for payloads */
302
303} lws_ss_conn_states_t;
304
305/*
306 * Returns from state() callback can tell the caller what the user code
307 * wants to do
308 */
309
310typedef enum lws_ss_state_return {
311 LWSSSSRET_TX_DONT_SEND = 1, /* (*tx) only, or failure */
312
313 LWSSSSRET_OK = 0, /* no error */
314 LWSSSSRET_DISCONNECT_ME = -1, /* caller should disconnect us */
315 LWSSSSRET_DESTROY_ME = -2, /* caller should destroy us */
316} lws_ss_state_return_t;
317
318/**
319 * lws_ss_info_t: information about stream to be created
320 *
321 * Prepare this struct with information about what the stream type is and how
322 * the stream should interface with your code, and pass it to lws_ss_create()
323 * to create the requested stream.
324 */
325
326enum {
327 LWSSSINFLAGS_REGISTER_SINK = (1 << 0),
328 /**< If set, we're not creating a specific stream, but registering
329 * ourselves as the "sink" for .streamtype. It's analogous to saying
330 * we want to be the many-to-one "server" for .streamtype; when other
331 * streams are created with that streamtype, they should be forwarded
332 * to this stream owner, where they join and part from the sink via
333 * (*state) LWSSSCS_SINK_JOIN / _PART events, the new client handle
334 * being provided in the h_src parameter.
335 */
336 LWSSSINFLAGS_PROXIED = (1 << 1),
337 /**< Set if the stream is being created as a stand-in at the proxy */
338 LWSSSINFLAGS_SERVER = (1 << 2),
339 /**< Set on the server object copy of the ssi / info to indicate that
340 * stream creation using this ssi is for Accepted connections belonging
341 * to a server */
342 LWSSSINFLAGS_ACCEPTED = (1 << 3),
343 /**< Set on the accepted object copy of the ssi / info to indicate that
344 * we are an accepted connection from a server's listening socket */
345};
346
347typedef lws_ss_state_return_t (*lws_sscb_rx)(void *userobj, const uint8_t *buf,
348 size_t len, int flags);
349typedef lws_ss_state_return_t (*lws_sscb_tx)(void *userobj,
350 lws_ss_tx_ordinal_t ord,
351 uint8_t *buf, size_t *len,
352 int *flags);
353typedef lws_ss_state_return_t (*lws_sscb_state)(void *userobj, void *h_src,
354 lws_ss_constate_t state,
355 lws_ss_tx_ordinal_t ack);
356
357#if defined(LWS_WITH_SECURE_STREAMS_BUFFER_DUMP)
358typedef void (*lws_ss_buffer_dump_cb)(void *userobj, const uint8_t *buf,
359 size_t len, int done);
360#endif
361
362struct lws_ss_policy;
363
364typedef struct lws_ss_info {
365 const char *streamtype; /**< type of stream we want to create */
366 size_t user_alloc; /**< size of user allocation */
367 size_t handle_offset; /**< offset of handle stg in user_alloc type,
368 set to offsetof(mytype, my_handle_member) */
369 size_t opaque_user_data_offset;
370 /**< offset of opaque user data ptr in user_alloc type, set to
371 offsetof(mytype, opaque_ud_member) */
372
373#if defined(LWS_WITH_SECURE_STREAMS_CPP)
374 const struct lws_ss_policy *policy;
375 /**< Normally NULL, or a locally-generated policy to apply to this
376 * connection instead of a named streamtype */
377#endif
378
379#if defined(LWS_WITH_SYS_FAULT_INJECTION)
380 lws_fi_ctx_t fic;
381 /**< Attach external Fault Injection context to the stream, hierarchy
382 * is ss->context */
383#endif
384
385 lws_sscb_rx rx;
386 /**< callback with rx payload for this stream */
387 lws_sscb_tx tx;
388 /**< callback to send payload on this stream... 0 = send as set in
389 * len and flags, 1 = do not send anything (ie, not even 0 len frame) */
390 lws_sscb_state state;
391 /**< advisory cb about state of stream and QoS status if applicable...
392 * h_src is only used with sinks and LWSSSCS_SINK_JOIN/_PART events.
393 * Return nonzero to indicate you want to destroy the stream. */
394#if defined(LWS_WITH_SECURE_STREAMS_BUFFER_DUMP)
395 lws_ss_buffer_dump_cb dump;
396 /**< cb to record needed protocol buffer data*/
397#endif
398 int manual_initial_tx_credit;
399 /**< 0 = manage any tx credit automatically, nonzero explicitly sets the
400 * peer stream to have the given amount of tx credit, if the protocol
401 * can support it.
402 *
403 * In the special case of _lws_smd streamtype, this is used to indicate
404 * the connection's rx class mask.
405 * */
406 uint32_t client_pid;
407 /**< used in proxy / serialization case to hold the client pid this
408 * proxied connection is to be tagged with
409 */
410 uint8_t flags;
411 uint8_t sss_protocol_version;
412 /**< used in proxy / serialization case to hold the SS serialization
413 * protocol level to use with this peer... clients automatically request
414 * the most recent version they were built with
415 * (LWS_SSS_CLIENT_PROTOCOL_VERSION) and the proxy stores the requested
416 * version in here
417 */
418
419} lws_ss_info_t;
420
421/**
422 * lws_ss_create() - Create secure stream
423 *
424 * \param context: the lws context to create this inside
425 * \param tsi: service thread index to create on (normally 0)
426 * \param ssi: pointer to lws_ss_info_t filled in with info about desired stream
427 * \param opaque_user_data: opaque data to set in the stream's user object
428 * \param ppss: pointer to secure stream handle pointer set on exit
429 * \param ppayload_fmt: NULL or pointer to a string ptr to take payload format
430 * name from the policy
431 *
432 * Requests a new secure stream described by \p ssi be created. If successful,
433 * the stream is created, its state callback called with LWSSSCS_CREATING, \p *ppss
434 * is set to point to the handle, and it returns 0. If it failed, it returns
435 * nonzero.
436 *
437 * Along with the opaque stream object, streams overallocate
438 *
439 * 1) a user data struct whose size is set in ssi
440 * 2) nauth plugin instantiation data (size set in the plugin struct)
441 * 3) sauth plugin instantiation data (size set in the plugin struct)
442 * 4) space for a copy of the stream type name
443 *
444 * The user data struct is initialized to all zeros, then the .handle_offset and
445 * .opaque_user_data_offset fields of the ssi are used to prepare the user data
446 * struct with the ss handle that was created, and a copy of the
447 * opaque_user_data pointer given as an argument.
448 *
449 * If you want to set up the stream with specific information, point to it in
450 * opaque_user_data and use the copy of that pointer in your user data member
451 * for it starting from the LWSSSCS_CREATING state call.
452 *
453 * Since different endpoints chosen by the policy may require different payload
454 * formats, \p ppayload_fmt is set to point to the name of the needed payload
455 * format from the policy database if non-NULL.
456 */
457LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
458lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi,
459 void *opaque_user_data, struct lws_ss_handle **ppss,
460 struct lws_sequencer *seq_owner, const char **ppayload_fmt);
461
462/**
463 * lws_ss_destroy() - Destroy secure stream
464 *
465 * \param ppss: pointer to lws_ss_t pointer to be destroyed
466 *
467 * Destroys the lws_ss_t pointed to by \p *ppss, and sets \p *ppss to NULL.
468 */
469LWS_VISIBLE LWS_EXTERN void
470lws_ss_destroy(struct lws_ss_handle **ppss);
471
472/**
473 * lws_ss_request_tx() - Schedule stream for tx
474 *
475 * \param pss: pointer to lws_ss_t representing stream that wants to transmit
476 *
477 * Schedules a write on the stream represented by \p pss. When it's possible to
478 * write on this stream, the \p *tx callback will occur with an empty buffer for
479 * the stream owner to fill in.
480 *
481 * Returns 0 or LWSSSSRET_DESTROY_ME
482 */
483LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT
484lws_ss_request_tx(struct lws_ss_handle *pss);
485
486/**
487 * lws_ss_request_tx() - Schedule stream for tx
488 *
489 * \param pss: pointer to lws_ss_t representing stream that wants to transmit
490 * \param len: the length of the write in bytes
491 *
492 * Schedules a write on the stream represented by \p pss. When it's possible to
493 * write on this stream, the \p *tx callback will occur with an empty buffer for
494 * the stream owner to fill in.
495 *
496 * This api variant should be used when it's possible the payload will go out
497 * over h1 with x-web-form-urlencoded or similar Content-Type.
498 */
499LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT
500lws_ss_request_tx_len(struct lws_ss_handle *pss, unsigned long len);
501
502/**
503 * lws_ss_client_connect() - Attempt the client connect
504 *
505 * \param h: secure streams handle
506 *
507 * Starts the connection process for the secure stream.
508 *
509 * Can return any of the lws_ss_state_return_t values depending on user
510 * state callback returns.
511 *
512 * LWSSSSRET_OK means the connection is ongoing.
513 *
514 */
515LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t LWS_WARN_UNUSED_RESULT
516lws_ss_client_connect(struct lws_ss_handle *h);
517
518/**
519 * lws_ss_get_sequencer() - Return parent sequencer pointer if any
520 *
521 * \param h: secure streams handle
522 *
523 * Returns NULL if the secure stream is not associated with a sequencer.
524 * Otherwise returns a pointer to the owning sequencer. You can use this to
525 * identify which sequencer to direct messages to, from the secure stream
526 * callback.
527 */
528LWS_VISIBLE LWS_EXTERN struct lws_sequencer *
529lws_ss_get_sequencer(struct lws_ss_handle *h);
530
531/**
532 * lws_ss_proxy_create() - Start a unix domain socket proxy for Secure Streams
533 *
534 * \param context: lws_context
535 * \param bind: if port is 0, unix domain path with leading @ for abstract.
536 * if port nonzero, NULL, or network interface to bind listen to
537 * \param port: tcp port to listen on
538 *
539 * Creates a vhost that listens either on an abstract namespace unix domain
540 * socket (port = 0) or a tcp listen socket (port nonzero). If bind is NULL
541 * and port is 0, the abstract unix domain socket defaults to "proxy.ss.lws".
542 *
543 * Client connections to this proxy to Secure Streams are fulfilled using the
544 * policy local to the proxy and the data passed between the client and the
545 * proxy using serialized Secure Streams protocol.
546 */
547LWS_VISIBLE LWS_EXTERN int
548lws_ss_proxy_create(struct lws_context *context, const char *bind, int port);
549
550/**
551 * lws_ss_state_name() - convenience helper to get a printable conn state name
552 *
553 * \param state: the connection state index
554 *
555 * Returns a printable name for the connection state index passed in.
556 */
557LWS_VISIBLE LWS_EXTERN const char *
558lws_ss_state_name(int state);
559
560/**
561 * lws_ss_get_context() - convenience helper to recover the lws context
562 *
563 * \param h: secure streams handle
564 *
565 * Returns the lws context. Dispenses with the need to pass a copy of it into
566 * your secure streams handler.
567 */
568LWS_VISIBLE LWS_EXTERN struct lws_context *
569lws_ss_get_context(struct lws_ss_handle *h);
570
571#define LWSSS_TIMEOUT_FROM_POLICY 0
572
573/**
574 * lws_ss_start_timeout() - start or restart the timeout on the stream
575 *
576 * \param h: secure streams handle
577 * \param timeout_ms: LWSSS_TIMEOUT_FROM_POLICY for policy value, else use timeout_ms
578 *
579 * Starts or restarts the stream's own timeout timer. If the specified time
580 * passes without lws_ss_cancel_timeout() being called on the stream, then the
581 * stream state callback receives LWSSSCS_TIMEOUT
582 *
583 * The process being protected by the timeout is up to the user code, it may be
584 * arbitrarily long and cross multiple protocol transactions or involve other
585 * streams. It's up to the user to decide when to start and when / if to cancel
586 * the stream timeout.
587 */
588LWS_VISIBLE LWS_EXTERN void
589lws_ss_start_timeout(struct lws_ss_handle *h, unsigned int timeout_ms);
590
591/**
592 * lws_ss_cancel_timeout() - remove any timeout on the stream
593 *
594 * \param h: secure streams handle
595 *
596 * Disable any timeout that was applied to the stream by lws_ss_start_timeout().
597 */
598LWS_VISIBLE LWS_EXTERN void
599lws_ss_cancel_timeout(struct lws_ss_handle *h);
600
601/**
602 * lws_ss_to_user_object() - convenience helper to get user object from handle
603 *
604 * \param h: secure streams handle
605 *
606 * Returns the user allocation related to the handle. Normally you won't need
607 * this since it's available in the rx, tx and state callbacks as "userdata"
608 * already.
609 */
610LWS_VISIBLE LWS_EXTERN void *
611lws_ss_to_user_object(struct lws_ss_handle *h);
612
613/**
614 * lws_ss_rideshare() - find the current streamtype when types rideshare
615 *
616 * \param h: the stream handle
617 *
618 * Under some conditions, the payloads may be structured using protocol-
619 * specific formatting, eg, http multipart mime. It's possible to map the
620 * logical partitions in the payload to different stream types using
621 * the policy "rideshare" feature.
622 *
623 * This api lets the callback code find out which rideshare stream type the
624 * current payload chunk belongs to.
625 */
626LWS_VISIBLE LWS_EXTERN const char *
627lws_ss_rideshare(struct lws_ss_handle *h);
628
629
630/**
631 * lws_ss_set_metadata() - allow user to bind external data to defined ss metadata
632 *
633 * \param h: secure streams handle
634 * \param name: metadata name from the policy
635 * \param value: pointer to user-managed data to bind to name
636 * \param len: length of the user-managed data in value
637 *
638 * Binds user-managed data to the named metadata item from the ss policy.
639 * If present, the metadata item is handled in a protocol-specific way using
640 * the associated policy information. For example, in the policy
641 *
642 * "\"metadata\":" "["
643 * "{\"uptag\":" "\"X-Upload-Tag:\"},"
644 * "{\"ctype\":" "\"Content-Type:\"},"
645 * "{\"xctype\":" "\"\"}"
646 * "],"
647 *
648 * when the policy is using h1 is interpreted to add h1 headers of the given
649 * name with the value of the metadata on the left.
650 *
651 * Return 0 if OK or nonzero if, eg, metadata name does not exist on the
652 * streamtype. You must check the result of this, eg, transient OOM can cause
653 * these to fail and you should retry later.
654 */
655LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
656lws_ss_set_metadata(struct lws_ss_handle *h, const char *name,
657 const void *value, size_t len);
658
659/**
660 * lws_ss_alloc_set_metadata() - copy data and bind to ss metadata
661 *
662 * \param h: secure streams handle
663 * \param name: metadata name from the policy
664 * \param value: pointer to user-managed data to bind to name
665 * \param len: length of the user-managed data in value
666 *
667 * Same as lws_ss_set_metadata(), but allocates a heap buffer for the data
668 * first and takes a copy of it, so the original can go out of scope
669 * immediately after.
670 */
671LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
672lws_ss_alloc_set_metadata(struct lws_ss_handle *h, const char *name,
673 const void *value, size_t len);
674
675/**
676 * lws_ss_get_metadata() - get current value of stream metadata item
677 *
678 * \param h: secure streams handle
679 * \param name: metadata name from the policy
680 * \param value: pointer to pointer to be set to point at the value
681 * \param len: pointer to size_t to set to the length of the value
682 *
683 * Binds user-managed data to the named metadata item from the ss policy.
684 * If present, the metadata item is handled in a protocol-specific way using
685 * the associated policy information. For example, in the policy
686 *
687 * "\"metadata\":" "["
688 * "{\"uptag\":" "\"X-Upload-Tag:\"},"
689 * "{\"ctype\":" "\"Content-Type:\"},"
690 * "{\"xctype\":" "\"\"}"
691 * "],"
692 *
693 * when the policy is using h1 is interpreted to add h1 headers of the given
694 * name with the value of the metadata on the left.
695 *
696 * Return 0 if \p *value and \p *len set OK, or nonzero if, eg, metadata \p name does
697 * not exist on the streamtype.
698 *
699 * The pointed-to values may only exist until the next time around the event
700 * loop.
701 */
702LWS_VISIBLE LWS_EXTERN int
703lws_ss_get_metadata(struct lws_ss_handle *h, const char *name,
704 const void **value, size_t *len);
705
706/**
707 * lws_ss_server_ack() - indicate how we feel about what the server has sent
708 *
709 * \param h: ss handle of accepted connection
710 * \param nack: 0 means we are OK with it, else some problem
711 *
712 * For SERVER secure streams
713 *
714 * Depending on the protocol, the server sending us something may be
715 * transactional, ie, built into it sending something is the idea we will
716 * respond somehow out-of-band; HTTP is like this with, eg, 200 response code.
717 *
718 * Calling this with nack=0 indicates that when we later respond, we want to
719 * acknowledge the transaction (eg, it means a 200 if http underneath), if
720 * nonzero that the transaction should act like it failed.
721 *
722 * If the underlying protocol doesn't understand transactions (eg, ws) then this
723 * has no effect either way.
724 */
725LWS_VISIBLE LWS_EXTERN void
726lws_ss_server_ack(struct lws_ss_handle *h, int nack);
727
728typedef void (*lws_sssfec_cb)(struct lws_ss_handle *h, void *arg);
729
730/**
731 * lws_ss_server_foreach_client() - callback for each live client connected to server
732 *
733 * \param h: server ss handle
734 * \param cb: the callback
735 * \param arg: arg passed to callback
736 *
737 * For SERVER secure streams
738 *
739 * Call the callback \p cb once for each client ss connected to the server,
740 * passing \p arg as an additional callback argument each time.
741 */
742LWS_VISIBLE LWS_EXTERN void
743lws_ss_server_foreach_client(struct lws_ss_handle *h, lws_sssfec_cb cb,
744 void *arg);
745
746/**
747 * lws_ss_change_handlers() - helper for dynamically changing stream handlers
748 *
749 * \param h: ss handle
750 * \param rx: the new RX handler
751 * \param tx: the new TX handler
752 * \param state: the new state handler
753 *
754 * Handlers set to NULL are left unchanged.
755 *
756 * This works on any handle, client or server and takes effect immediately.
757 *
758 * Depending on circumstances this may be helpful when
759 *
760 * a) a server stream undergoes an LWSSSCS_SERVER_UPGRADE (as in http -> ws) and
761 * the payloads in the new protocol have a different purpose that is best
762 * handled in their own rx and tx callbacks, and
763 *
764 * b) you may want to serve several different, possibly large things based on
765 * what was requested. Setting a customized handler allows clean encapsulation
766 * of the different serving strategies.
767 *
768 * If the stream is long-lived, like ws, you should set the changed handler back
769 * to the default when the transaction wanting it is completed.
770 */
771LWS_VISIBLE LWS_EXTERN void
772lws_ss_change_handlers(struct lws_ss_handle *h, lws_sscb_rx rx, lws_sscb_tx tx,
773 lws_sscb_state state);
774
775/**
776 * lws_ss_add_peer_tx_credit() - allow peer to transmit more to us
777 *
778 * \param h: secure streams handle
779 * \param add: additional tx credit (signed)
780 *
781 * Indicate to remote peer that we can accept \p add bytes more payload being
782 * sent to us.
783 */
784LWS_VISIBLE LWS_EXTERN int
785lws_ss_add_peer_tx_credit(struct lws_ss_handle *h, int32_t add);
786
787/**
788 * lws_ss_get_est_peer_tx_credit() - get our current estimate of peer's tx credit
789 *
790 * \param h: secure streams handle
791 *
792 * Based on what credit we gave it, and what we have received, report our
793 * estimate of peer's tx credit usable to transmit to us. This may be outdated
794 * in that some or all of its credit may already have been expended by sending
795 * stuff to us that is in flight already.
796 */
797LWS_VISIBLE LWS_EXTERN int
798lws_ss_get_est_peer_tx_credit(struct lws_ss_handle *h);
799
800LWS_VISIBLE LWS_EXTERN const char *
801lws_ss_tag(struct lws_ss_handle *h);
802
803
804#if defined(LWS_WITH_SECURE_STREAMS_AUTH_SIGV4)
805/**
806 * lws_ss_sigv4_set_aws_key() - set aws credential into system blob
807 *
808 * \param context: lws_context
809 * \param idx: the system blob index specified in the policy, currently
810 * up to 4 blobs.
811 * \param keyid: aws access keyid
812 * \param key: aws access key
813 *
814 * Return 0 if OK or nonzero if e.g. idx is invalid; system blob heap appending
815 * fails.
816 */
817
818LWS_VISIBLE LWS_EXTERN int
819lws_ss_sigv4_set_aws_key(struct lws_context* context, uint8_t idx,
820 const char * keyid, const char * key);
821
822/**
823 * lws_aws_filesystem_credentials_helper() - read aws credentials from file
824 *
825 * \param path: path to read, ~ at start is converted to $HOME contents if any
826 * \param kid: eg, "aws_access_key_id"
827 * \param ak: eg, "aws_secret_access_key"
828 * \param aws_keyid: pointer to pointer for allocated keyid from credentials file
829 * \param aws_key: pointer to pointer for allocated key from credentials file
830 *
831 * Return 0 if both *aws_keyid and *aws_key allocated from the config file, else
832 * nonzero, and neither *aws_keyid or *aws_key are allocated.
833 *
834 * If *aws_keyid and *aws_key are set, it's the user's responsibility to
835 * free() them when they are no longer needed.
836 */
837
838LWS_VISIBLE LWS_EXTERN int
839lws_aws_filesystem_credentials_helper(const char *path, const char *kid,
840 const char *ak, char **aws_keyid,
841 char **aws_key);
842
843#endif
844
845///@}
846
847