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