cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

lws-secure-streams.h (31145B)


      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