private-lib-secure-streams.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2019 - 2020 Andy Green <[email protected]>
  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. /*
  25. * Secure Stream state
  26. */
  27. typedef enum {
  28. SSSEQ_IDLE,
  29. SSSEQ_TRY_CONNECT,
  30. SSSEQ_TRY_CONNECT_NAUTH,
  31. SSSEQ_TRY_CONNECT_SAUTH,
  32. SSSEQ_RECONNECT_WAIT,
  33. SSSEQ_DO_RETRY,
  34. SSSEQ_CONNECTED,
  35. } lws_ss_seq_state_t;
  36. /**
  37. * lws_ss_handle_t: publicly-opaque secure stream object implementation
  38. */
  39. typedef struct lws_ss_handle {
  40. lws_ss_info_t info; /**< copy of stream creation info */
  41. struct lws_dll2 list; /**< pt lists active ss */
  42. struct lws_dll2 to_list; /**< pt lists ss with pending to-s */
  43. struct lws_dll2_owner src_list; /**< sink's list of bound sources */
  44. struct lws_context *context; /**< lws context we are created on */
  45. const lws_ss_policy_t *policy; /**< system policy for stream */
  46. struct lws_sequencer *seq; /**< owning sequencer if any */
  47. struct lws *wsi; /**< the stream wsi if any */
  48. #if defined(LWS_WITH_SSPLUGINS)
  49. void *nauthi; /**< the nauth plugin instance data */
  50. void *sauthi; /**< the sauth plugin instance data */
  51. #endif
  52. lws_ss_metadata_t *metadata;
  53. const lws_ss_policy_t *rideshare;
  54. //struct lws_ss_handle *h_sink; /**< sink we are bound to, or NULL */
  55. //void *sink_obj;/**< sink's private object representing us */
  56. lws_sorted_usec_list_t sul_timeout;
  57. lws_sorted_usec_list_t sul;
  58. lws_ss_tx_ordinal_t txord;
  59. /* protocol-specific connection helpers */
  60. union {
  61. /* ...for http-related protocols... */
  62. struct {
  63. /* common to all http-related protocols */
  64. /* incoming multipart parsing */
  65. char boundary[24]; /* --boundary from headers */
  66. uint8_t boundary_len; /* length of --boundary */
  67. uint8_t boundary_seq; /* current match amount */
  68. uint8_t boundary_dashes; /* check for -- after */
  69. uint8_t boundary_post; /* swallow post CRLF */
  70. uint8_t som:1; /* SOM has been sent */
  71. uint8_t any:1; /* any content has been sent */
  72. uint8_t good_respcode:1; /* 200 type response code */
  73. union {
  74. struct { /* LWSSSP_H1 */
  75. #if defined(WIN32)
  76. uint8_t dummy;
  77. #endif
  78. } h1;
  79. struct { /* LWSSSP_H2 */
  80. #if defined(WIN32)
  81. uint8_t dummy;
  82. #endif
  83. } h2;
  84. struct { /* LWSSSP_WS */
  85. #if defined(WIN32)
  86. uint8_t dummy;
  87. #endif
  88. } ws;
  89. } u;
  90. } http;
  91. /* details for non-http related protocols... */
  92. #if defined(LWS_ROLE_MQTT)
  93. struct {
  94. lws_mqtt_topic_elem_t topic_qos;
  95. lws_mqtt_topic_elem_t sub_top;
  96. lws_mqtt_subscribe_param_t sub_info;
  97. /* allocation that must be destroyed with conn */
  98. void *heap_baggage;
  99. const char *subscribe_to;
  100. size_t subscribe_to_len;
  101. } mqtt;
  102. #endif
  103. #if defined(LWS_WITH_SYS_SMD)
  104. struct {
  105. struct lws_smd_peer *smd_peer;
  106. lws_sorted_usec_list_t sul_write;
  107. } smd;
  108. #endif
  109. } u;
  110. unsigned long writeable_len;
  111. lws_ss_constate_t connstate;/**< public connection state */
  112. lws_ss_seq_state_t seqstate; /**< private connection state */
  113. #if defined(LWS_WITH_SERVER)
  114. int txn_resp;
  115. #endif
  116. uint16_t retry; /**< retry / backoff tracking */
  117. int16_t temp16;
  118. uint8_t tsi; /**< service thread idx, usually 0 */
  119. uint8_t subseq; /**< emulate SOM tracking */
  120. uint8_t txn_ok; /**< 1 = transaction was OK */
  121. uint8_t txn_resp_set:1; /**< user code set one */
  122. uint8_t txn_resp_pending:1; /**< we have yet to send */
  123. uint8_t hanging_som:1;
  124. uint8_t inside_msg:1;
  125. uint8_t being_serialized:1; /* we are not the consumer */
  126. uint8_t destroying:1;
  127. } lws_ss_handle_t;
  128. /* connection helper that doesn't need to hang around after connection starts */
  129. union lws_ss_contemp {
  130. #if defined(LWS_ROLE_MQTT)
  131. lws_mqtt_client_connect_param_t ccp;
  132. #else
  133. #if defined(WIN32)
  134. uint8_t dummy;
  135. #endif
  136. #endif
  137. };
  138. /*
  139. * When allocating the opaque handle, we overallocate for:
  140. *
  141. * 1) policy->nauth_plugin->alloc (.nauthi) if any
  142. * 2) policy->sauth_plugin->alloc (.sauthi) if any
  143. * 3) copy of creation info stream type pointed to by info.streamtype... this
  144. * may be arbitrarily long and since it may be coming from socket ipc and be
  145. * temporary at creation time, we need a place for the copy to stay in scope
  146. * 4) copy of info->streamtype contents
  147. */
  148. /* the user object allocation is immediately after the ss object allocation */
  149. #define ss_to_userobj(ss) ((void *)&(ss)[1])
  150. /*
  151. * serialization parser state
  152. */
  153. enum {
  154. KIND_C_TO_P,
  155. KIND_SS_TO_P,
  156. };
  157. struct lws_ss_serialization_parser {
  158. char streamtype[32];
  159. char rideshare[32];
  160. char metadata_name[32];
  161. uint64_t ust_pwait;
  162. lws_ss_metadata_t *ssmd;
  163. int ps;
  164. int ctr;
  165. uint32_t usd_phandling;
  166. uint32_t flags;
  167. int32_t temp32;
  168. int32_t txcr_out;
  169. int32_t txcr_in;
  170. uint16_t rem;
  171. uint8_t type;
  172. uint8_t frag1;
  173. uint8_t slen;
  174. uint8_t rsl_pos;
  175. uint8_t rsl_idx;
  176. };
  177. /*
  178. * Unlike locally-fulfilled SS, SSS doesn't have to hold metadata on client side
  179. * but pass it through to the proxy. The client side doesn't know the real
  180. * metadata names that are available in the policy (since it's hardcoded in code
  181. * no point passing them back to the client from the policy). Because of that,
  182. * it doesn't know how many to allocate when we create the sspc_handle either.
  183. *
  184. * So we use a linked-list of changed-but-not-yet-proxied metadata allocated
  185. * on the heap and items removed as they are proxied out. Anything on the list
  186. * is sent to the proxy before any requested tx is handled.
  187. *
  188. * This is also used to queue tx credit changes
  189. */
  190. typedef struct lws_sspc_metadata {
  191. lws_dll2_t list;
  192. char name[32]; /* empty string, then actually TCXR */
  193. size_t len;
  194. int tx_cr_adjust;
  195. /* the value of length .len is overallocated after this */
  196. } lws_sspc_metadata_t;
  197. /* state of the upstream proxy onward connection */
  198. enum {
  199. LWSSSPC_ONW_NONE,
  200. LWSSSPC_ONW_REQ,
  201. LWSSSPC_ONW_ONGOING,
  202. LWSSSPC_ONW_CONN,
  203. };
  204. typedef struct lws_sspc_handle {
  205. char rideshare_list[128];
  206. lws_ss_info_t ssi;
  207. lws_sorted_usec_list_t sul_retry;
  208. struct lws_ss_serialization_parser parser;
  209. lws_dll2_owner_t metadata_owner;
  210. struct lws_dll2 client_list;
  211. struct lws_tx_credit txc;
  212. struct lws *cwsi;
  213. struct lws_dsh *dsh;
  214. struct lws_context *context;
  215. lws_usec_t us_earliest_write_req;
  216. unsigned long writeable_len;
  217. lws_ss_conn_states_t state;
  218. uint32_t timeout_ms;
  219. uint32_t ord;
  220. int16_t temp16;
  221. uint8_t rideshare_ofs[4];
  222. uint8_t rsidx;
  223. uint8_t conn_req_state:2;
  224. uint8_t destroying:1;
  225. uint8_t non_wsi:1;
  226. uint8_t ignore_txc:1;
  227. uint8_t pending_timeout_update:1;
  228. uint8_t pending_writeable_len:1;
  229. uint8_t creating_cb_done:1;
  230. } lws_sspc_handle_t;
  231. typedef struct backoffs {
  232. struct backoffs *next;
  233. const char *name;
  234. lws_retry_bo_t r;
  235. } backoff_t;
  236. union u {
  237. backoff_t *b;
  238. lws_ss_x509_t *x;
  239. lws_ss_trust_store_t *t;
  240. lws_ss_policy_t *p;
  241. };
  242. enum {
  243. LTY_BACKOFF,
  244. LTY_X509,
  245. LTY_TRUSTSTORE,
  246. LTY_POLICY,
  247. _LTY_COUNT /* always last */
  248. };
  249. struct policy_cb_args {
  250. struct lejp_ctx jctx;
  251. struct lws_context *context;
  252. struct lwsac *ac;
  253. const char *socks5_proxy;
  254. struct lws_b64state b64;
  255. union u heads[_LTY_COUNT];
  256. union u curr[_LTY_COUNT];
  257. uint8_t *p;
  258. int count;
  259. };
  260. #if defined(LWS_WITH_SYS_SMD)
  261. extern const lws_ss_policy_t pol_smd;
  262. #endif
  263. /*
  264. * returns one of
  265. *
  266. * LWSSSSRET_OK
  267. * LWSSSSRET_DISCONNECT_ME
  268. * LWSSSSRET_DESTROY_ME
  269. */
  270. int
  271. lws_ss_deserialize_parse(struct lws_ss_serialization_parser *par,
  272. struct lws_context *context,
  273. struct lws_dsh *dsh, const uint8_t *cp, size_t len,
  274. lws_ss_conn_states_t *state, void *parconn,
  275. lws_ss_handle_t **pss, lws_ss_info_t *ssi, char client);
  276. int
  277. lws_ss_serialize_rx_payload(struct lws_dsh *dsh, const uint8_t *buf,
  278. size_t len, int flags, const char *rsp);
  279. int
  280. lws_ss_deserialize_tx_payload(struct lws_dsh *dsh, struct lws *wsi,
  281. lws_ss_tx_ordinal_t ord, uint8_t *buf,
  282. size_t *len, int *flags);
  283. int
  284. lws_ss_serialize_state(struct lws_dsh *dsh, lws_ss_constate_t state,
  285. lws_ss_tx_ordinal_t ack);
  286. void
  287. lws_ss_serialize_state_transition(lws_ss_conn_states_t *state, int new_state);
  288. const lws_ss_policy_t *
  289. lws_ss_policy_lookup(const struct lws_context *context, const char *streamtype);
  290. /* can be used as a cb from lws_dll2_foreach_safe() to destroy ss */
  291. int
  292. lws_ss_destroy_dll(struct lws_dll2 *d, void *user);
  293. int
  294. lws_sspc_destroy_dll(struct lws_dll2 *d, void *user);
  295. int
  296. lws_ss_policy_set(struct lws_context *context, const char *name);
  297. int
  298. lws_ss_sys_fetch_policy(struct lws_context *context);
  299. lws_ss_state_return_t
  300. lws_ss_event_helper(lws_ss_handle_t *h, lws_ss_constate_t cs);
  301. lws_ss_state_return_t
  302. lws_ss_backoff(lws_ss_handle_t *h);
  303. int
  304. _lws_ss_handle_state_ret(lws_ss_state_return_t r, struct lws *wsi,
  305. lws_ss_handle_t **ph);
  306. int
  307. lws_ss_set_timeout_us(lws_ss_handle_t *h, lws_usec_t us);
  308. void
  309. ss_proxy_onward_txcr(void *userobj, int bump);
  310. int
  311. lws_ss_serialize_txcr(struct lws_dsh *dsh, int txcr);
  312. int
  313. lws_ss_sys_auth_api_amazon_com(struct lws_context *context);
  314. lws_ss_metadata_t *
  315. lws_ss_get_handle_metadata(struct lws_ss_handle *h, const char *name);
  316. lws_ss_metadata_t *
  317. lws_ss_policy_metadata_index(const lws_ss_policy_t *p, size_t index);
  318. lws_ss_metadata_t *
  319. lws_ss_policy_metadata(const lws_ss_policy_t *p, const char *name);
  320. int
  321. lws_ss_exp_cb_metadata(void *priv, const char *name, char *out, size_t *pos,
  322. size_t olen, size_t *exp_ofs);
  323. int
  324. _lws_ss_client_connect(lws_ss_handle_t *h, int is_retry);
  325. struct lws_vhost *
  326. lws_ss_policy_ref_trust_store(struct lws_context *context,
  327. const lws_ss_policy_t *pol, char doref);
  328. #if defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
  329. int
  330. lws_ss_policy_unref_trust_store(struct lws_context *context,
  331. const lws_ss_policy_t *pol);
  332. #endif
  333. int
  334. lws_ss_sys_cpd(struct lws_context *cx);
  335. typedef int (* const secstream_protocol_connect_munge_t)(lws_ss_handle_t *h,
  336. char *buf, size_t len, struct lws_client_connect_info *i,
  337. union lws_ss_contemp *ct);
  338. typedef int (* const secstream_protocol_add_txcr_t)(lws_ss_handle_t *h, int add);
  339. typedef int (* const secstream_protocol_get_txcr_t)(lws_ss_handle_t *h);
  340. struct ss_pcols {
  341. const char *name;
  342. const char *alpn;
  343. const struct lws_protocols *protocol;
  344. secstream_protocol_connect_munge_t munge;
  345. secstream_protocol_add_txcr_t tx_cr_add;
  346. secstream_protocol_get_txcr_t tx_cr_est;
  347. };
  348. extern const struct ss_pcols ss_pcol_h1;
  349. extern const struct ss_pcols ss_pcol_h2;
  350. extern const struct ss_pcols ss_pcol_ws;
  351. extern const struct ss_pcols ss_pcol_mqtt;
  352. extern const struct ss_pcols ss_pcol_raw;
  353. extern const struct lws_protocols protocol_secstream_h1;
  354. extern const struct lws_protocols protocol_secstream_h2;
  355. extern const struct lws_protocols protocol_secstream_ws;
  356. extern const struct lws_protocols protocol_secstream_mqtt;
  357. extern const struct lws_protocols protocol_secstream_raw;