cscg24-guacamole

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

lws-system.h (14570B)


      1 /*
      2 * libwebsockets - small server side websockets and web server implementation
      3 *
      4 * Copyright (C) 2010 - 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 * This provides a clean way to interface lws user code to be able to
     25 * work unchanged on different systems for fetching common system information,
     26 * and performing common system operations like reboot.
     27 */
     28
     29/*
     30 * Types of system blob that can be set and retreived
     31 */
     32
     33typedef enum {
     34	LWS_SYSBLOB_TYPE_AUTH,
     35	LWS_SYSBLOB_TYPE_CLIENT_CERT_DER = LWS_SYSBLOB_TYPE_AUTH + 2,
     36	LWS_SYSBLOB_TYPE_CLIENT_KEY_DER,
     37	LWS_SYSBLOB_TYPE_DEVICE_SERIAL,
     38	LWS_SYSBLOB_TYPE_DEVICE_FW_VERSION,
     39	LWS_SYSBLOB_TYPE_DEVICE_TYPE,
     40	LWS_SYSBLOB_TYPE_NTP_SERVER,
     41	LWS_SYSBLOB_TYPE_MQTT_CLIENT_ID,
     42	LWS_SYSBLOB_TYPE_MQTT_USERNAME,
     43	LWS_SYSBLOB_TYPE_MQTT_PASSWORD,
     44
     45#if defined(LWS_WITH_SECURE_STREAMS_AUTH_SIGV4)
     46	/* extend 4 more auth blobs, each has 2 slots */
     47	LWS_SYSBLOB_TYPE_EXT_AUTH1,
     48	LWS_SYSBLOB_TYPE_EXT_AUTH2 = LWS_SYSBLOB_TYPE_EXT_AUTH1 + 2,
     49	LWS_SYSBLOB_TYPE_EXT_AUTH3 = LWS_SYSBLOB_TYPE_EXT_AUTH2 + 2,
     50	LWS_SYSBLOB_TYPE_EXT_AUTH4 = LWS_SYSBLOB_TYPE_EXT_AUTH3 + 2,
     51	LWS_SYSBLOB_TYPE_EXT_AUTH4_1,
     52#endif
     53
     54	LWS_SYSBLOB_TYPE_COUNT /* ... always last */
     55} lws_system_blob_item_t;
     56
     57/* opaque generic blob whose content may be on-the-heap or pointed-to
     58 * directly case by case.  When it's on the heap, it can be produced by
     59 * appending (it's a buflist underneath).  Either way, it can be consumed by
     60 * copying out a given length from a given offset.
     61 */
     62
     63typedef struct lws_system_blob lws_system_blob_t;
     64
     65LWS_EXTERN LWS_VISIBLE void
     66lws_system_blob_direct_set(lws_system_blob_t *b, const uint8_t *ptr, size_t len);
     67
     68LWS_EXTERN LWS_VISIBLE void
     69lws_system_blob_heap_empty(lws_system_blob_t *b);
     70
     71LWS_EXTERN LWS_VISIBLE int
     72lws_system_blob_heap_append(lws_system_blob_t *b, const uint8_t *ptr, size_t len);
     73
     74LWS_EXTERN LWS_VISIBLE size_t
     75lws_system_blob_get_size(lws_system_blob_t *b);
     76
     77/* return 0 and sets *ptr to point to blob data if possible, nonzero = fail */
     78LWS_EXTERN LWS_VISIBLE int
     79lws_system_blob_get_single_ptr(lws_system_blob_t *b, const uint8_t **ptr);
     80
     81LWS_EXTERN LWS_VISIBLE int
     82lws_system_blob_get(lws_system_blob_t *b, uint8_t *ptr, size_t *len, size_t ofs);
     83
     84LWS_EXTERN LWS_VISIBLE void
     85lws_system_blob_destroy(lws_system_blob_t *b);
     86
     87/*
     88 * Get the opaque blob for index idx of various system blobs.  Returns 0 if
     89 * *b was set otherwise nonzero means out of range
     90 */
     91
     92LWS_EXTERN LWS_VISIBLE lws_system_blob_t *
     93lws_system_get_blob(struct lws_context *context, lws_system_blob_item_t type,
     94                    int idx);
     95
     96/*
     97 * Lws view of system state... normal operation from user code perspective is
     98 * dependent on implicit (eg, knowing the date for cert validation) and
     99 * explicit dependencies.
    100 *
    101 * Bit of lws and user code can register notification handlers that can enforce
    102 * dependent operations before state transitions can complete.
    103 */
    104
    105typedef enum { /* keep system_state_names[] in sync in context.c */
    106	LWS_SYSTATE_UNKNOWN,
    107
    108	LWS_SYSTATE_CONTEXT_CREATED,	 /* context was just created */
    109	LWS_SYSTATE_INITIALIZED,	 /* protocols initialized.  Lws itself
    110					  * can operate normally */
    111	LWS_SYSTATE_IFACE_COLDPLUG,	 /* existing net ifaces iterated */
    112	LWS_SYSTATE_DHCP,		 /* at least one net iface configured */
    113	LWS_SYSTATE_CPD_PRE_TIME,	 /* Captive portal detect without valid
    114					  * time, good for non-https tests... if
    115					  * you care about it, implement and
    116					  * call lws_system_ops_t
    117					  * .captive_portal_detect_request()
    118					  * and move the state forward according
    119					  * to the result. */
    120	LWS_SYSTATE_TIME_VALID,		 /* ntpclient ran, or hw time valid...
    121					  * tls cannot work until we reach here
    122					  */
    123	LWS_SYSTATE_CPD_POST_TIME,	 /* Captive portal detect after time was
    124					  * time, good for https tests... if
    125					  * you care about it, implement and
    126					  * call lws_system_ops_t
    127					  * .captive_portal_detect_request()
    128					  * and move the state forward according
    129					  * to the result. */
    130
    131	LWS_SYSTATE_POLICY_VALID,	 /* user code knows how to operate... */
    132	LWS_SYSTATE_REGISTERED,		 /* device has an identity... */
    133	LWS_SYSTATE_AUTH1,		 /* identity used for main auth token */
    134	LWS_SYSTATE_AUTH2,		 /* identity used for optional auth */
    135
    136	LWS_SYSTATE_OPERATIONAL,	 /* user code can operate normally */
    137
    138	LWS_SYSTATE_POLICY_INVALID,	 /* user code is changing its policies
    139					  * drop everything done with old
    140					  * policy, switch to new then enter
    141					  * LWS_SYSTATE_POLICY_VALID */
    142	LWS_SYSTATE_CONTEXT_DESTROYING,	 /* Context is being destroyed */
    143} lws_system_states_t;
    144
    145/* Captive Portal Detect -related */
    146
    147typedef enum {
    148	LWS_CPD_UNKNOWN = 0,	/* test didn't happen ince last DHCP acq yet */
    149	LWS_CPD_INTERNET_OK,	/* no captive portal: our CPD test passed OK,
    150				 * we can go out on the internet */
    151	LWS_CPD_CAPTIVE_PORTAL,	/* we inferred we're behind a captive portal */
    152	LWS_CPD_NO_INTERNET,	/* we couldn't touch anything */
    153} lws_cpd_result_t;
    154
    155typedef void (*lws_attach_cb_t)(struct lws_context *context, int tsi, void *opaque);
    156struct lws_attach_item;
    157
    158LWS_EXTERN LWS_VISIBLE int
    159lws_tls_jit_trust_got_cert_cb(struct lws_context *cx, void *got_opaque,
    160			      const uint8_t *skid, size_t skid_len,
    161			      const uint8_t *der, size_t der_len);
    162
    163typedef struct lws_system_ops {
    164	int (*reboot)(void);
    165	int (*set_clock)(lws_usec_t us);
    166	int (*attach)(struct lws_context *context, int tsi, lws_attach_cb_t cb,
    167		      lws_system_states_t state, void *opaque,
    168		      struct lws_attach_item **get);
    169	/**< if \p get is NULL, add an attach callback request to the pt for
    170	 * \p cb with arg \p opaque, that should be called when we're at or past
    171	 * system state \p state.
    172	 *
    173	 * If \p get is non-NULL, look for the first listed item on the pt whose
    174	 * state situation is ready, and set *get to point to it.  If no items,
    175	 * or none where the system state is right, set *get to NULL.
    176	 *
    177	 * It's done like this so (*attach) can perform system-specific
    178	 * locking outside of lws core, for both getting and adding items the
    179	 * same so it is thread-safe.  A non-threadsafe helper
    180	 * __lws_system_attach() is provided to do the actual work inside the
    181	 * system-specific locking.
    182	 */
    183	int (*captive_portal_detect_request)(struct lws_context *context);
    184	/**< Check if we can go out on the internet cleanly, or if we are being
    185	 * redirected or intercepted by a captive portal.
    186	 * Start the check that proceeds asynchronously, and report the results
    187	 * by calling lws_captive_portal_detect_result() api
    188	 */
    189
    190	int (*metric_report)(lws_metric_pub_t *mdata);
    191	/**< metric \p item is reporting an event of kind \p rpt,
    192	 * held in \p mdata... return 0 to leave the metric object as it is,
    193	 * or nonzero to reset it. */
    194
    195	int (*jit_trust_query)(struct lws_context *cx, const uint8_t *skid,
    196			       size_t skid_len, void *got_opaque);
    197	/**< user defined trust store search, if we do trust a cert with SKID
    198	 * matching skid / skid_len, then it should get hold of the DER for the
    199	 * matching root CA and call
    200	 * lws_tls_jit_trust_got_cert_cb(..., got_opaque) before cleaning up and
    201	 * returning.  The DER should be destroyed if in heap before returning.
    202	 */
    203
    204	uint32_t	wake_latency_us;
    205	/**< time taken for this device to wake from suspend, in us
    206	 */
    207} lws_system_ops_t;
    208
    209#if defined(LWS_WITH_SYS_STATE)
    210
    211/**
    212 * lws_system_get_state_manager() - return the state mgr object for system state
    213 *
    214 * \param context: the lws_context
    215 *
    216 * The returned pointer can be used with the lws_state_ apis
    217 */
    218
    219LWS_EXTERN LWS_VISIBLE lws_state_manager_t *
    220lws_system_get_state_manager(struct lws_context *context);
    221
    222#endif
    223
    224/* wrappers handle NULL members or no ops struct set at all cleanly */
    225
    226#define LWSSYSGAUTH_HEX (1 << 0)
    227
    228/**
    229 * lws_system_get_ops() - get ahold of the system ops struct from the context
    230 *
    231 * \param context: the lws_context
    232 *
    233 * Returns the system ops struct.  It may return NULL and if not, anything in
    234 * there may be NULL.
    235 */
    236LWS_EXTERN LWS_VISIBLE const lws_system_ops_t *
    237lws_system_get_ops(struct lws_context *context);
    238
    239#if defined(LWS_WITH_SYS_STATE)
    240
    241/**
    242 * lws_system_context_from_system_mgr() - return context from system state mgr
    243 *
    244 * \param mgr: pointer to specifically the system state mgr
    245 *
    246 * Returns the context from the system state mgr.  Helper since the lws_context
    247 * is opaque.
    248 */
    249LWS_EXTERN LWS_VISIBLE struct lws_context *
    250lws_system_context_from_system_mgr(lws_state_manager_t *mgr);
    251
    252#endif
    253
    254/**
    255 * __lws_system_attach() - get and set items on context attach list
    256 *
    257 * \param context: context to get or set attach items to
    258 * \param tsi: thread service index (normally 0)
    259 * \param cb: callback to call from context event loop thread
    260 * \param state: the lws_system state we have to be in or have passed through
    261 * \param opaque: optional pointer to user specific info given to callback
    262 * \param get: NULL, or pointer to pointer to take detached tail item on exit
    263 *
    264 * This allows other threads to enqueue callback requests to happen from a pt's
    265 * event loop thread safely.  The callback gets the context pointer and a user
    266 * opaque pointer that can be optionally given when the item is added to the
    267 * attach list.
    268 *
    269 * This api is the no-locking core function for getting and setting items on the
    270 * pt's attach list.  The lws_system operation (*attach) is the actual
    271 * api that user and internal code calls for this feature, it should perform
    272 * system-specific locking, call this helper, release the locking and then
    273 * return the result.  This api is public only so it can be used in the locked
    274 * implementation of (*attach).
    275 *
    276 * If get is NULL, then the call adds to the head of the pt attach list using
    277 * cb, state, and opaque; if get is non-NULL, then *get is set to the first
    278 * waiting attached item that meets the state criteria and that item is removed
    279 * from the list.
    280 *
    281 * This is a non-threadsafe helper only designed to be called from
    282 * implementations of struct lws_system's (*attach) operation where system-
    283 * specific locking has been applied around it, making it threadsafe.
    284 */
    285LWS_EXTERN LWS_VISIBLE int
    286__lws_system_attach(struct lws_context *context, int tsi, lws_attach_cb_t cb,
    287		    lws_system_states_t state, void *opaque,
    288		    struct lws_attach_item **get);
    289
    290
    291enum {
    292	LWSDH_IPV4_SUBNET_MASK		= 0,
    293	LWSDH_IPV4_BROADCAST,
    294	LWSDH_LEASE_SECS,
    295	LWSDH_REBINDING_SECS,
    296	LWSDH_RENEWAL_SECS,
    297
    298	_LWSDH_NUMS_COUNT,
    299
    300	LWSDH_SA46_IP			= 0,
    301	LWSDH_SA46_DNS_SRV_1,
    302	LWSDH_SA46_DNS_SRV_2,
    303	LWSDH_SA46_DNS_SRV_3,
    304	LWSDH_SA46_DNS_SRV_4,
    305	LWSDH_SA46_IPV4_ROUTER,
    306	LWSDH_SA46_NTP_SERVER,
    307	LWSDH_SA46_DHCP_SERVER,
    308
    309	_LWSDH_SA46_COUNT,
    310};
    311
    312typedef struct lws_dhcpc_ifstate {
    313	char				ifname[16];
    314	char				domain[64];
    315	uint8_t				mac[6];
    316	uint32_t			nums[_LWSDH_NUMS_COUNT];
    317	lws_sockaddr46			sa46[_LWSDH_SA46_COUNT];
    318} lws_dhcpc_ifstate_t;
    319
    320typedef int (*dhcpc_cb_t)(void *opaque, lws_dhcpc_ifstate_t *is);
    321
    322/**
    323 * lws_dhcpc_request() - add a network interface to dhcpc management
    324 *
    325 * \param c: the lws_context
    326 * \param i: the interface name, like "eth0"
    327 * \param af: address family
    328 * \param cb: the change callback
    329 * \param opaque: opaque pointer given to the callback
    330 *
    331 * Register a network interface as being managed by DHCP.  lws will proceed to
    332 * try to acquire an IP.  Requires LWS_WITH_SYS_DHCP_CLIENT at cmake.
    333 */
    334LWS_EXTERN LWS_VISIBLE int
    335lws_dhcpc_request(struct lws_context *c, const char *i, int af, dhcpc_cb_t cb,
    336		void *opaque);
    337
    338/**
    339 * lws_dhcpc_remove() - remove a network interface to dhcpc management
    340 *
    341 * \param context: the lws_context
    342 * \param iface: the interface name, like "eth0"
    343 *
    344 * Remove handling of the network interface from dhcp.
    345 */
    346LWS_EXTERN LWS_VISIBLE int
    347lws_dhcpc_remove(struct lws_context *context, const char *iface);
    348
    349/**
    350 * lws_dhcpc_status() - has any interface reached BOUND state
    351 *
    352 * \param context: the lws_context
    353 * \param sa46: set to a DNS server from a bound interface, or NULL
    354 *
    355 * Returns 1 if any network interface managed by dhcpc has reached the BOUND
    356 * state (has acquired an IP, gateway and DNS server), otherwise 0.
    357 */
    358LWS_EXTERN LWS_VISIBLE int
    359lws_dhcpc_status(struct lws_context *context, lws_sockaddr46 *sa46);
    360
    361/**
    362 * lws_system_cpd_start() - helper to initiate captive portal detection
    363 *
    364 * \param context: the lws_context
    365 *
    366 * Resets the context's captive portal state to LWS_CPD_UNKNOWN and calls the
    367 * lws_system_ops_t captive_portal_detect_request() implementation to begin
    368 * testing the captive portal state.
    369 */
    370LWS_EXTERN LWS_VISIBLE int
    371lws_system_cpd_start(struct lws_context *context);
    372
    373LWS_EXTERN LWS_VISIBLE void
    374lws_system_cpd_start_defer(struct lws_context *cx, lws_usec_t defer_us);
    375
    376
    377/**
    378 * lws_system_cpd_set() - report the result of the captive portal detection
    379 *
    380 * \param context: the lws_context
    381 * \param result: one of the LWS_CPD_ constants representing captive portal state
    382 *
    383 * Sets the context's captive portal detection state to result.  User captive
    384 * portal detection code would call this once it had a result from its test.
    385 */
    386LWS_EXTERN LWS_VISIBLE void
    387lws_system_cpd_set(struct lws_context *context, lws_cpd_result_t result);
    388
    389
    390/**
    391 * lws_system_cpd_state_get() - returns the last tested captive portal state
    392 *
    393 * \param context: the lws_context
    394 *
    395 * Returns one of the LWS_CPD_ constants indicating the system's understanding
    396 * of the current captive portal situation.
    397 */
    398LWS_EXTERN LWS_VISIBLE lws_cpd_result_t
    399lws_system_cpd_state_get(struct lws_context *context);