xref: /aosp_15_r20/external/libwebsockets/lib/secure-streams/system/fetch-policy/fetch-policy.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker  * Policy fetching for Secure Streams
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * libwebsockets - small server side websockets and web server implementation
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * Copyright (C) 2019 - 2020 Andy Green <[email protected]>
7*1c60b9acSAndroid Build Coastguard Worker  *
8*1c60b9acSAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
9*1c60b9acSAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to
10*1c60b9acSAndroid Build Coastguard Worker  * deal in the Software without restriction, including without limitation the
11*1c60b9acSAndroid Build Coastguard Worker  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12*1c60b9acSAndroid Build Coastguard Worker  * sell copies of the Software, and to permit persons to whom the Software is
13*1c60b9acSAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
14*1c60b9acSAndroid Build Coastguard Worker  *
15*1c60b9acSAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
16*1c60b9acSAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
17*1c60b9acSAndroid Build Coastguard Worker  *
18*1c60b9acSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19*1c60b9acSAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20*1c60b9acSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21*1c60b9acSAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22*1c60b9acSAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23*1c60b9acSAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24*1c60b9acSAndroid Build Coastguard Worker  * IN THE SOFTWARE.
25*1c60b9acSAndroid Build Coastguard Worker  */
26*1c60b9acSAndroid Build Coastguard Worker 
27*1c60b9acSAndroid Build Coastguard Worker #include <private-lib-core.h>
28*1c60b9acSAndroid Build Coastguard Worker 
29*1c60b9acSAndroid Build Coastguard Worker typedef struct ss_fetch_policy {
30*1c60b9acSAndroid Build Coastguard Worker 	struct lws_ss_handle 	*ss;
31*1c60b9acSAndroid Build Coastguard Worker 	void			*opaque_data;
32*1c60b9acSAndroid Build Coastguard Worker 	/* ... application specific state ... */
33*1c60b9acSAndroid Build Coastguard Worker 
34*1c60b9acSAndroid Build Coastguard Worker 	lws_sorted_usec_list_t	sul;
35*1c60b9acSAndroid Build Coastguard Worker 
36*1c60b9acSAndroid Build Coastguard Worker 	uint8_t			partway;
37*1c60b9acSAndroid Build Coastguard Worker } ss_fetch_policy_t;
38*1c60b9acSAndroid Build Coastguard Worker 
39*1c60b9acSAndroid Build Coastguard Worker /* secure streams payload interface */
40*1c60b9acSAndroid Build Coastguard Worker 
41*1c60b9acSAndroid Build Coastguard Worker static lws_ss_state_return_t
ss_fetch_policy_rx(void * userobj,const uint8_t * buf,size_t len,int flags)42*1c60b9acSAndroid Build Coastguard Worker ss_fetch_policy_rx(void *userobj, const uint8_t *buf, size_t len, int flags)
43*1c60b9acSAndroid Build Coastguard Worker {
44*1c60b9acSAndroid Build Coastguard Worker 	ss_fetch_policy_t *m = (ss_fetch_policy_t *)userobj;
45*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context *context = (struct lws_context *)m->opaque_data;
46*1c60b9acSAndroid Build Coastguard Worker 
47*1c60b9acSAndroid Build Coastguard Worker 	if (flags & LWSSS_FLAG_SOM) {
48*1c60b9acSAndroid Build Coastguard Worker 		if (lws_ss_policy_parse_begin(context, 0))
49*1c60b9acSAndroid Build Coastguard Worker 			return LWSSSSRET_OK;
50*1c60b9acSAndroid Build Coastguard Worker 		m->partway = 1;
51*1c60b9acSAndroid Build Coastguard Worker 	}
52*1c60b9acSAndroid Build Coastguard Worker 
53*1c60b9acSAndroid Build Coastguard Worker 	if (len && lws_ss_policy_parse(context, buf, len) < 0)
54*1c60b9acSAndroid Build Coastguard Worker 		return LWSSSSRET_OK;
55*1c60b9acSAndroid Build Coastguard Worker 
56*1c60b9acSAndroid Build Coastguard Worker 	if (flags & LWSSS_FLAG_EOM)
57*1c60b9acSAndroid Build Coastguard Worker 		m->partway = 2;
58*1c60b9acSAndroid Build Coastguard Worker 
59*1c60b9acSAndroid Build Coastguard Worker 	return LWSSSSRET_OK;
60*1c60b9acSAndroid Build Coastguard Worker }
61*1c60b9acSAndroid Build Coastguard Worker 
62*1c60b9acSAndroid Build Coastguard Worker static lws_ss_state_return_t
ss_fetch_policy_tx(void * userobj,lws_ss_tx_ordinal_t ord,uint8_t * buf,size_t * len,int * flags)63*1c60b9acSAndroid Build Coastguard Worker ss_fetch_policy_tx(void *userobj, lws_ss_tx_ordinal_t ord, uint8_t *buf,
64*1c60b9acSAndroid Build Coastguard Worker 		   size_t *len, int *flags)
65*1c60b9acSAndroid Build Coastguard Worker {
66*1c60b9acSAndroid Build Coastguard Worker 	return LWSSSSRET_TX_DONT_SEND;
67*1c60b9acSAndroid Build Coastguard Worker }
68*1c60b9acSAndroid Build Coastguard Worker 
69*1c60b9acSAndroid Build Coastguard Worker static void
policy_set(lws_sorted_usec_list_t * sul)70*1c60b9acSAndroid Build Coastguard Worker policy_set(lws_sorted_usec_list_t *sul)
71*1c60b9acSAndroid Build Coastguard Worker {
72*1c60b9acSAndroid Build Coastguard Worker 	ss_fetch_policy_t *m = lws_container_of(sul, ss_fetch_policy_t, sul);
73*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context *context = (struct lws_context *)m->opaque_data;
74*1c60b9acSAndroid Build Coastguard Worker 
75*1c60b9acSAndroid Build Coastguard Worker 	/*
76*1c60b9acSAndroid Build Coastguard Worker 	 * We get called if the policy parse was successful, just after the
77*1c60b9acSAndroid Build Coastguard Worker 	 * ss connection close that was using the vhost from the old policy
78*1c60b9acSAndroid Build Coastguard Worker 	 */
79*1c60b9acSAndroid Build Coastguard Worker 
80*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_destroy(&m->ss);
81*1c60b9acSAndroid Build Coastguard Worker 
82*1c60b9acSAndroid Build Coastguard Worker 	if (lws_ss_policy_set(context, "updated"))
83*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: policy set failed\n", __func__);
84*1c60b9acSAndroid Build Coastguard Worker 	else {
85*1c60b9acSAndroid Build Coastguard Worker 		context->policy_updated = 1;
86*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_SYS_STATE)
87*1c60b9acSAndroid Build Coastguard Worker 		lws_state_transition_steps(&context->mgr_system,
88*1c60b9acSAndroid Build Coastguard Worker 					   LWS_SYSTATE_OPERATIONAL);
89*1c60b9acSAndroid Build Coastguard Worker #endif
90*1c60b9acSAndroid Build Coastguard Worker 	}
91*1c60b9acSAndroid Build Coastguard Worker }
92*1c60b9acSAndroid Build Coastguard Worker 
93*1c60b9acSAndroid Build Coastguard Worker static lws_ss_state_return_t
ss_fetch_policy_state(void * userobj,void * sh,lws_ss_constate_t state,lws_ss_tx_ordinal_t ack)94*1c60b9acSAndroid Build Coastguard Worker ss_fetch_policy_state(void *userobj, void *sh, lws_ss_constate_t state,
95*1c60b9acSAndroid Build Coastguard Worker 		      lws_ss_tx_ordinal_t ack)
96*1c60b9acSAndroid Build Coastguard Worker {
97*1c60b9acSAndroid Build Coastguard Worker 	ss_fetch_policy_t *m = (ss_fetch_policy_t *)userobj;
98*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context *context = (struct lws_context *)m->opaque_data;
99*1c60b9acSAndroid Build Coastguard Worker 
100*1c60b9acSAndroid Build Coastguard Worker 	lwsl_info("%s: %s, ord 0x%x\n", __func__, lws_ss_state_name((int)state),
101*1c60b9acSAndroid Build Coastguard Worker 		  (unsigned int)ack);
102*1c60b9acSAndroid Build Coastguard Worker 
103*1c60b9acSAndroid Build Coastguard Worker 	switch (state) {
104*1c60b9acSAndroid Build Coastguard Worker 	case LWSSSCS_CREATING:
105*1c60b9acSAndroid Build Coastguard Worker 		return lws_ss_request_tx(m->ss);
106*1c60b9acSAndroid Build Coastguard Worker 
107*1c60b9acSAndroid Build Coastguard Worker 	case LWSSSCS_CONNECTING:
108*1c60b9acSAndroid Build Coastguard Worker 		break;
109*1c60b9acSAndroid Build Coastguard Worker 
110*1c60b9acSAndroid Build Coastguard Worker 	case LWSSSCS_QOS_ACK_REMOTE:
111*1c60b9acSAndroid Build Coastguard Worker 		switch (m->partway) {
112*1c60b9acSAndroid Build Coastguard Worker 		case 2:
113*1c60b9acSAndroid Build Coastguard Worker 			lws_sul_schedule(context, 0, &m->sul, policy_set, 1);
114*1c60b9acSAndroid Build Coastguard Worker 			m->partway = 0;
115*1c60b9acSAndroid Build Coastguard Worker 			break;
116*1c60b9acSAndroid Build Coastguard Worker 		}
117*1c60b9acSAndroid Build Coastguard Worker 		break;
118*1c60b9acSAndroid Build Coastguard Worker 
119*1c60b9acSAndroid Build Coastguard Worker 	case LWSSSCS_DISCONNECTED:
120*1c60b9acSAndroid Build Coastguard Worker 		if (m->partway == 1) {
121*1c60b9acSAndroid Build Coastguard Worker 			lws_ss_policy_parse_abandon(context);
122*1c60b9acSAndroid Build Coastguard Worker 			break;
123*1c60b9acSAndroid Build Coastguard Worker 		}
124*1c60b9acSAndroid Build Coastguard Worker 		m->partway = 0;
125*1c60b9acSAndroid Build Coastguard Worker 		break;
126*1c60b9acSAndroid Build Coastguard Worker 
127*1c60b9acSAndroid Build Coastguard Worker 	default:
128*1c60b9acSAndroid Build Coastguard Worker 		break;
129*1c60b9acSAndroid Build Coastguard Worker 	}
130*1c60b9acSAndroid Build Coastguard Worker 
131*1c60b9acSAndroid Build Coastguard Worker 	return LWSSSSRET_OK;
132*1c60b9acSAndroid Build Coastguard Worker }
133*1c60b9acSAndroid Build Coastguard Worker 
134*1c60b9acSAndroid Build Coastguard Worker int
lws_ss_sys_fetch_policy(struct lws_context * context)135*1c60b9acSAndroid Build Coastguard Worker lws_ss_sys_fetch_policy(struct lws_context *context)
136*1c60b9acSAndroid Build Coastguard Worker {
137*1c60b9acSAndroid Build Coastguard Worker 	lws_ss_info_t ssi;
138*1c60b9acSAndroid Build Coastguard Worker 
139*1c60b9acSAndroid Build Coastguard Worker 	if (context->hss_fetch_policy) /* already exists */
140*1c60b9acSAndroid Build Coastguard Worker 		return 0;
141*1c60b9acSAndroid Build Coastguard Worker 
142*1c60b9acSAndroid Build Coastguard Worker 	/* We're making an outgoing secure stream ourselves */
143*1c60b9acSAndroid Build Coastguard Worker 
144*1c60b9acSAndroid Build Coastguard Worker 	memset(&ssi, 0, sizeof(ssi));
145*1c60b9acSAndroid Build Coastguard Worker 	ssi.handle_offset	    = offsetof(ss_fetch_policy_t, ss);
146*1c60b9acSAndroid Build Coastguard Worker 	ssi.opaque_user_data_offset = offsetof(ss_fetch_policy_t, opaque_data);
147*1c60b9acSAndroid Build Coastguard Worker 	ssi.rx			    = ss_fetch_policy_rx;
148*1c60b9acSAndroid Build Coastguard Worker 	ssi.tx			    = ss_fetch_policy_tx;
149*1c60b9acSAndroid Build Coastguard Worker 	ssi.state		    = ss_fetch_policy_state;
150*1c60b9acSAndroid Build Coastguard Worker 	ssi.user_alloc		    = sizeof(ss_fetch_policy_t);
151*1c60b9acSAndroid Build Coastguard Worker 	ssi.streamtype		    = "fetch_policy";
152*1c60b9acSAndroid Build Coastguard Worker 
153*1c60b9acSAndroid Build Coastguard Worker 	if (lws_ss_create(context, 0, &ssi, context, &context->hss_fetch_policy,
154*1c60b9acSAndroid Build Coastguard Worker 			  NULL, NULL)) {
155*1c60b9acSAndroid Build Coastguard Worker 		/*
156*1c60b9acSAndroid Build Coastguard Worker 		 * If there's no fetch_policy streamtype, it can just be we're
157*1c60b9acSAndroid Build Coastguard Worker 		 * running on a proxied client with no policy of its own,
158*1c60b9acSAndroid Build Coastguard Worker 		 * it's OK.
159*1c60b9acSAndroid Build Coastguard Worker 		 */
160*1c60b9acSAndroid Build Coastguard Worker 		lwsl_info("%s: Policy fetch ss failed (stub policy?)\n", __func__);
161*1c60b9acSAndroid Build Coastguard Worker 
162*1c60b9acSAndroid Build Coastguard Worker 		return 0;
163*1c60b9acSAndroid Build Coastguard Worker 	}
164*1c60b9acSAndroid Build Coastguard Worker 
165*1c60b9acSAndroid Build Coastguard Worker 	lwsl_info("%s: policy fetching ongoing\n", __func__);
166*1c60b9acSAndroid Build Coastguard Worker 
167*1c60b9acSAndroid Build Coastguard Worker 	/* fetching it is ongoing */
168*1c60b9acSAndroid Build Coastguard Worker 
169*1c60b9acSAndroid Build Coastguard Worker 	return 1;
170*1c60b9acSAndroid Build Coastguard Worker }
171