cscg24-guacamole

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

lws-secure-streams-policy.h (13887B)


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