1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * lws-minimal-secure-streams-policy2c 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Written in 2010-2021 by Andy Green <andy@warmcat.com> 5d4afb5ceSopenharmony_ci * 6d4afb5ceSopenharmony_ci * This file is made available under the Creative Commons CC0 1.0 7d4afb5ceSopenharmony_ci * Universal Public Domain Dedication. 8d4afb5ceSopenharmony_ci * 9d4afb5ceSopenharmony_ci * 10d4afb5ceSopenharmony_ci * This reads policy JSON on stdin and emits it as compileable 11d4afb5ceSopenharmony_ci * C structs. 12d4afb5ceSopenharmony_ci * 13d4afb5ceSopenharmony_ci * It's useful if your platform is too space-constrained for a 14d4afb5ceSopenharmony_ci * JSON policy and needs to build a static policy in C via 15d4afb5ceSopenharmony_ci * LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY... this way you can 16d4afb5ceSopenharmony_ci * still create and maintain the JSON policy but implement it directly 17d4afb5ceSopenharmony_ci * as C structs in your code. 18d4afb5ceSopenharmony_ci */ 19d4afb5ceSopenharmony_ci 20d4afb5ceSopenharmony_ci#include <libwebsockets.h> 21d4afb5ceSopenharmony_ci#include <string.h> 22d4afb5ceSopenharmony_ci#include <signal.h> 23d4afb5ceSopenharmony_ci#include <stdio.h> 24d4afb5ceSopenharmony_ci#include <assert.h> 25d4afb5ceSopenharmony_ci 26d4afb5ceSopenharmony_cistatic int interrupted, bad = 1; 27d4afb5ceSopenharmony_ci 28d4afb5ceSopenharmony_ci 29d4afb5ceSopenharmony_cistatic void 30d4afb5ceSopenharmony_cisigint_handler(int sig) 31d4afb5ceSopenharmony_ci{ 32d4afb5ceSopenharmony_ci interrupted = 1; 33d4afb5ceSopenharmony_ci} 34d4afb5ceSopenharmony_ci 35d4afb5ceSopenharmony_cistruct aggstr { 36d4afb5ceSopenharmony_ci struct aggstr *next; 37d4afb5ceSopenharmony_ci 38d4afb5ceSopenharmony_ci const char *orig; 39d4afb5ceSopenharmony_ci size_t offset; 40d4afb5ceSopenharmony_ci}; 41d4afb5ceSopenharmony_ci 42d4afb5ceSopenharmony_cistatic struct aggstr *rbomap, /* retry / backoff object map */ 43d4afb5ceSopenharmony_ci *trustmap, /* trust store map */ 44d4afb5ceSopenharmony_ci *certmap; /* x.509 cert map */ 45d4afb5ceSopenharmony_cistatic size_t last_offset; 46d4afb5ceSopenharmony_ci 47d4afb5ceSopenharmony_ci 48d4afb5ceSopenharmony_ci 49d4afb5ceSopenharmony_cistatic const char * 50d4afb5ceSopenharmony_cipurify_csymbol(const char *in, char *temp, size_t templen) 51d4afb5ceSopenharmony_ci{ 52d4afb5ceSopenharmony_ci const char *otemp = temp; 53d4afb5ceSopenharmony_ci 54d4afb5ceSopenharmony_ci assert (strlen(in) < templen); 55d4afb5ceSopenharmony_ci 56d4afb5ceSopenharmony_ci while (*in) { 57d4afb5ceSopenharmony_ci if ((*in >= 'a' && *in <= 'z') || (*in >= 'A' && *in <= 'Z') || 58d4afb5ceSopenharmony_ci (*in >= '0' && *in <= '9')) 59d4afb5ceSopenharmony_ci *temp++ = *in; 60d4afb5ceSopenharmony_ci else 61d4afb5ceSopenharmony_ci *temp++ = '_'; 62d4afb5ceSopenharmony_ci 63d4afb5ceSopenharmony_ci in++; 64d4afb5ceSopenharmony_ci } 65d4afb5ceSopenharmony_ci 66d4afb5ceSopenharmony_ci *temp = '\0'; 67d4afb5ceSopenharmony_ci 68d4afb5ceSopenharmony_ci return otemp; 69d4afb5ceSopenharmony_ci} 70d4afb5ceSopenharmony_ci 71d4afb5ceSopenharmony_ciint main(int argc, const char **argv) 72d4afb5ceSopenharmony_ci{ 73d4afb5ceSopenharmony_ci const lws_ss_policy_t *pol, *lastpol = NULL; 74d4afb5ceSopenharmony_ci struct lws_context_creation_info info; 75d4afb5ceSopenharmony_ci size_t json_size = 0, est = 0; 76d4afb5ceSopenharmony_ci struct lws_context *context; 77d4afb5ceSopenharmony_ci const lws_ss_auth_t *auth; 78d4afb5ceSopenharmony_ci char prev[128], curr[128]; 79d4afb5ceSopenharmony_ci int unique_rbo = 0, m, n; 80d4afb5ceSopenharmony_ci char buf[64], buf1[64]; 81d4afb5ceSopenharmony_ci lws_ss_metadata_t *md; 82d4afb5ceSopenharmony_ci struct aggstr *a, *a1; 83d4afb5ceSopenharmony_ci 84d4afb5ceSopenharmony_ci signal(SIGINT, sigint_handler); 85d4afb5ceSopenharmony_ci 86d4afb5ceSopenharmony_ci memset(&info, 0, sizeof info); 87d4afb5ceSopenharmony_ci lws_cmdline_option_handle_builtin(argc, argv, &info); 88d4afb5ceSopenharmony_ci 89d4afb5ceSopenharmony_ci lwsl_user("LWS secure streams policy2c [-d<verb>]\n"); 90d4afb5ceSopenharmony_ci 91d4afb5ceSopenharmony_ci info.fd_limit_per_thread = 1 + 6 + 1; 92d4afb5ceSopenharmony_ci info.port = CONTEXT_PORT_NO_LISTEN; 93d4afb5ceSopenharmony_ci 94d4afb5ceSopenharmony_ci info.options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS | 95d4afb5ceSopenharmony_ci LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; 96d4afb5ceSopenharmony_ci 97d4afb5ceSopenharmony_ci /* create the context */ 98d4afb5ceSopenharmony_ci 99d4afb5ceSopenharmony_ci context = lws_create_context(&info); 100d4afb5ceSopenharmony_ci if (!context) { 101d4afb5ceSopenharmony_ci lwsl_err("lws init failed\n"); 102d4afb5ceSopenharmony_ci return 1; 103d4afb5ceSopenharmony_ci } 104d4afb5ceSopenharmony_ci 105d4afb5ceSopenharmony_ci lws_ss_policy_parse_begin(context, 0); 106d4afb5ceSopenharmony_ci 107d4afb5ceSopenharmony_ci printf("/*\n * Autogenerated from the following JSON policy\n */\n\n#if 0\n"); 108d4afb5ceSopenharmony_ci 109d4afb5ceSopenharmony_ci do { 110d4afb5ceSopenharmony_ci int m, n = (int)read(0, buf, sizeof(buf)); 111d4afb5ceSopenharmony_ci 112d4afb5ceSopenharmony_ci if (n < 1) 113d4afb5ceSopenharmony_ci break; 114d4afb5ceSopenharmony_ci 115d4afb5ceSopenharmony_ci m = lws_ss_policy_parse(context, (uint8_t *)buf, (size_t)n); 116d4afb5ceSopenharmony_ci 117d4afb5ceSopenharmony_ci printf("%.*s", n, buf); 118d4afb5ceSopenharmony_ci json_size += (unsigned int)n; 119d4afb5ceSopenharmony_ci 120d4afb5ceSopenharmony_ci if (m < 0 && m != LEJP_CONTINUE) { 121d4afb5ceSopenharmony_ci lwsl_err("%s: policy parse failed... lws has WITH_ROLEs" 122d4afb5ceSopenharmony_ci "for what's in the JSON?\n", __func__); 123d4afb5ceSopenharmony_ci goto bail; 124d4afb5ceSopenharmony_ci } 125d4afb5ceSopenharmony_ci } while (1); 126d4afb5ceSopenharmony_ci 127d4afb5ceSopenharmony_ci printf("\n\n Original JSON size: %zu\n#endif\n\n", json_size); 128d4afb5ceSopenharmony_ci 129d4afb5ceSopenharmony_ci lwsl_notice("%s: parsed JSON\n", __func__); 130d4afb5ceSopenharmony_ci 131d4afb5ceSopenharmony_ci /* 132d4afb5ceSopenharmony_ci * Well, this is fun, isn't it... we have parsed the JSON into in-memory 133d4afb5ceSopenharmony_ci * policy objects, and it has set the context policy pointer to the head 134d4afb5ceSopenharmony_ci * of those but has not set the new policy (which would free the x.509). 135d4afb5ceSopenharmony_ci * 136d4afb5ceSopenharmony_ci * We want to walk the streamtype list first discovering unique objects 137d4afb5ceSopenharmony_ci * and strings referenced there and emitting them compactly as C data, 138d4afb5ceSopenharmony_ci * and then second to emit the streamtype linked-list referring to those 139d4afb5ceSopenharmony_ci * objects. 140d4afb5ceSopenharmony_ci * 141d4afb5ceSopenharmony_ci * For const strings, we aggregate them and avoid generating extra 142d4afb5ceSopenharmony_ci * pointers by encoding the reference as &_lws_ss_staticpol_str[xxx] 143d4afb5ceSopenharmony_ci * where xxx is the fixed offset in the aggregated monster-string. When 144d4afb5ceSopenharmony_ci * doing that, we keep a map of original pointers to offsets. 145d4afb5ceSopenharmony_ci * 146d4afb5ceSopenharmony_ci * Although we want to minimize memory used by the emitted C, we don't 147d4afb5ceSopenharmony_ci * have to sweat memory during this conversion since it's happening on a 148d4afb5ceSopenharmony_ci * PC 149d4afb5ceSopenharmony_ci */ 150d4afb5ceSopenharmony_ci 151d4afb5ceSopenharmony_ci pol = lws_ss_policy_get(context); 152d4afb5ceSopenharmony_ci 153d4afb5ceSopenharmony_ci while (pol) { 154d4afb5ceSopenharmony_ci 155d4afb5ceSopenharmony_ci /* 156d4afb5ceSopenharmony_ci * Walk the metadata list gathering strings and issuing the 157d4afb5ceSopenharmony_ci * C struct 158d4afb5ceSopenharmony_ci */ 159d4afb5ceSopenharmony_ci 160d4afb5ceSopenharmony_ci md = pol->metadata; 161d4afb5ceSopenharmony_ci 162d4afb5ceSopenharmony_ci if (md) { 163d4afb5ceSopenharmony_ci int idx = 0; 164d4afb5ceSopenharmony_ci 165d4afb5ceSopenharmony_ci printf("\nstatic const lws_ss_metadata_t "); 166d4afb5ceSopenharmony_ci 167d4afb5ceSopenharmony_ci prev[0] = '\0'; 168d4afb5ceSopenharmony_ci md = pol->metadata; 169d4afb5ceSopenharmony_ci while (md) { 170d4afb5ceSopenharmony_ci 171d4afb5ceSopenharmony_ci est += sizeof(lws_ss_metadata_t); 172d4afb5ceSopenharmony_ci 173d4afb5ceSopenharmony_ci lws_snprintf(curr, sizeof(curr), "_md_%s_%s", 174d4afb5ceSopenharmony_ci purify_csymbol(pol->streamtype, buf, 175d4afb5ceSopenharmony_ci sizeof(buf)), 176d4afb5ceSopenharmony_ci purify_csymbol(md->name, buf1, 177d4afb5ceSopenharmony_ci sizeof(buf1))); 178d4afb5ceSopenharmony_ci 179d4afb5ceSopenharmony_ci printf("%s = {\n", curr); 180d4afb5ceSopenharmony_ci if (prev[0]) 181d4afb5ceSopenharmony_ci printf("\t.next = (void *)&%s, \n", prev); 182d4afb5ceSopenharmony_ci 183d4afb5ceSopenharmony_ci printf("\t.name = \"%s\",\n", (const char *)md->name); 184d4afb5ceSopenharmony_ci if (md->value__may_own_heap) { 185d4afb5ceSopenharmony_ci printf("\t.value__may_own_heap = (void *)\"%s\",\n", 186d4afb5ceSopenharmony_ci (const char *)md->value__may_own_heap); 187d4afb5ceSopenharmony_ci printf("\t.value_length = 0x%x,\n", 188d4afb5ceSopenharmony_ci (unsigned int)strlen( 189d4afb5ceSopenharmony_ci (const char *)md->value__may_own_heap)); 190d4afb5ceSopenharmony_ci } 191d4afb5ceSopenharmony_ci 192d4afb5ceSopenharmony_ci printf("\t.length = %d,\n", idx++); // md->length); 193d4afb5ceSopenharmony_ci printf("\t.value_is_http_token = 0x%x,\n", 194d4afb5ceSopenharmony_ci (unsigned int)md->value_is_http_token); 195d4afb5ceSopenharmony_ci printf("}"); 196d4afb5ceSopenharmony_ci if (md->next) 197d4afb5ceSopenharmony_ci printf(",\n"); 198d4afb5ceSopenharmony_ci 199d4afb5ceSopenharmony_ci lws_strncpy(prev, curr, sizeof(prev)); 200d4afb5ceSopenharmony_ci 201d4afb5ceSopenharmony_ci md = md->next; 202d4afb5ceSopenharmony_ci } 203d4afb5ceSopenharmony_ci 204d4afb5ceSopenharmony_ci printf(";\n\n"); 205d4afb5ceSopenharmony_ci } 206d4afb5ceSopenharmony_ci 207d4afb5ceSopenharmony_ci /* 208d4afb5ceSopenharmony_ci * Create unique retry policies... have we seen this guy? 209d4afb5ceSopenharmony_ci */ 210d4afb5ceSopenharmony_ci 211d4afb5ceSopenharmony_ci if (pol->retry_bo) { 212d4afb5ceSopenharmony_ci a = rbomap; 213d4afb5ceSopenharmony_ci while (a) { 214d4afb5ceSopenharmony_ci if (a->orig == (const char *)pol->retry_bo) 215d4afb5ceSopenharmony_ci break; 216d4afb5ceSopenharmony_ci 217d4afb5ceSopenharmony_ci a = a->next; 218d4afb5ceSopenharmony_ci } 219d4afb5ceSopenharmony_ci 220d4afb5ceSopenharmony_ci if (!a) { 221d4afb5ceSopenharmony_ci 222d4afb5ceSopenharmony_ci /* We haven't seen it before and need to create it */ 223d4afb5ceSopenharmony_ci 224d4afb5ceSopenharmony_ci a = malloc(sizeof(*a)); 225d4afb5ceSopenharmony_ci if (!a) 226d4afb5ceSopenharmony_ci goto bail; 227d4afb5ceSopenharmony_ci a->next = rbomap; 228d4afb5ceSopenharmony_ci a->offset = (unsigned int)unique_rbo++; 229d4afb5ceSopenharmony_ci a->orig = (const char *)pol->retry_bo; 230d4afb5ceSopenharmony_ci rbomap = a; 231d4afb5ceSopenharmony_ci 232d4afb5ceSopenharmony_ci printf("static const uint32_t _rbo_bo_%zu[] = {\n", 233d4afb5ceSopenharmony_ci a->offset); 234d4afb5ceSopenharmony_ci for (n = 0; n < pol->retry_bo->retry_ms_table_count; n++) 235d4afb5ceSopenharmony_ci printf(" %u, ", (unsigned int) 236d4afb5ceSopenharmony_ci pol->retry_bo->retry_ms_table[n]); 237d4afb5ceSopenharmony_ci 238d4afb5ceSopenharmony_ci est += sizeof(uint32_t) * 239d4afb5ceSopenharmony_ci pol->retry_bo->retry_ms_table_count; 240d4afb5ceSopenharmony_ci 241d4afb5ceSopenharmony_ci printf("\n};\nstatic const " 242d4afb5ceSopenharmony_ci "lws_retry_bo_t _rbo_%zu = {\n", a->offset); 243d4afb5ceSopenharmony_ci 244d4afb5ceSopenharmony_ci printf("\t.retry_ms_table = _rbo_bo_%zu,\n", 245d4afb5ceSopenharmony_ci a->offset); 246d4afb5ceSopenharmony_ci printf("\t.retry_ms_table_count = %u,\n", 247d4afb5ceSopenharmony_ci pol->retry_bo->retry_ms_table_count); 248d4afb5ceSopenharmony_ci printf("\t.conceal_count = %u,\n", 249d4afb5ceSopenharmony_ci pol->retry_bo->conceal_count); 250d4afb5ceSopenharmony_ci printf("\t.secs_since_valid_ping = %u,\n", 251d4afb5ceSopenharmony_ci pol->retry_bo->secs_since_valid_ping); 252d4afb5ceSopenharmony_ci printf("\t.secs_since_valid_hangup = %u,\n", 253d4afb5ceSopenharmony_ci pol->retry_bo->secs_since_valid_hangup); 254d4afb5ceSopenharmony_ci printf("\t.jitter_percent = %u,\n", 255d4afb5ceSopenharmony_ci pol->retry_bo->jitter_percent); 256d4afb5ceSopenharmony_ci printf("};\n"); 257d4afb5ceSopenharmony_ci 258d4afb5ceSopenharmony_ci est += sizeof(lws_retry_bo_t); 259d4afb5ceSopenharmony_ci } 260d4afb5ceSopenharmony_ci } 261d4afb5ceSopenharmony_ci 262d4afb5ceSopenharmony_ci /* 263d4afb5ceSopenharmony_ci * How about his trust store, it's new to us? 264d4afb5ceSopenharmony_ci */ 265d4afb5ceSopenharmony_ci 266d4afb5ceSopenharmony_ci if (pol->trust.store) { 267d4afb5ceSopenharmony_ci a = trustmap; 268d4afb5ceSopenharmony_ci while (a) { 269d4afb5ceSopenharmony_ci if (a->orig == (const char *)pol->trust.store) 270d4afb5ceSopenharmony_ci break; 271d4afb5ceSopenharmony_ci 272d4afb5ceSopenharmony_ci a = a->next; 273d4afb5ceSopenharmony_ci } 274d4afb5ceSopenharmony_ci 275d4afb5ceSopenharmony_ci if (!a) { 276d4afb5ceSopenharmony_ci 277d4afb5ceSopenharmony_ci /* it's new to us... */ 278d4afb5ceSopenharmony_ci 279d4afb5ceSopenharmony_ci a = malloc(sizeof(*a)); 280d4afb5ceSopenharmony_ci if (!a) 281d4afb5ceSopenharmony_ci goto bail; 282d4afb5ceSopenharmony_ci a->next = trustmap; 283d4afb5ceSopenharmony_ci a->offset = 0; /* don't care, just track seen */ 284d4afb5ceSopenharmony_ci a->orig = (const char *)pol->trust.store; 285d4afb5ceSopenharmony_ci trustmap = a; 286d4afb5ceSopenharmony_ci 287d4afb5ceSopenharmony_ci /* 288d4afb5ceSopenharmony_ci * Have a look through his x.509 stack... 289d4afb5ceSopenharmony_ci * any that're new to us? 290d4afb5ceSopenharmony_ci */ 291d4afb5ceSopenharmony_ci 292d4afb5ceSopenharmony_ci for (n = 0; n < pol->trust.store->count; n++) { 293d4afb5ceSopenharmony_ci if (!pol->trust.store->ssx509[n]) 294d4afb5ceSopenharmony_ci continue; 295d4afb5ceSopenharmony_ci a1 = certmap; 296d4afb5ceSopenharmony_ci while (a1) { 297d4afb5ceSopenharmony_ci if (a1->orig == (const char *)pol->trust.store->ssx509[n]) 298d4afb5ceSopenharmony_ci break; 299d4afb5ceSopenharmony_ci a1 = a1->next; 300d4afb5ceSopenharmony_ci } 301d4afb5ceSopenharmony_ci 302d4afb5ceSopenharmony_ci if (!a1) { 303d4afb5ceSopenharmony_ci /* 304d4afb5ceSopenharmony_ci * This x.509 cert is new to us... 305d4afb5ceSopenharmony_ci * let's capture the DER 306d4afb5ceSopenharmony_ci */ 307d4afb5ceSopenharmony_ci 308d4afb5ceSopenharmony_ci a1 = malloc(sizeof(*a1)); 309d4afb5ceSopenharmony_ci if (!a1) 310d4afb5ceSopenharmony_ci goto bail; 311d4afb5ceSopenharmony_ci a1->next = certmap; 312d4afb5ceSopenharmony_ci a1->offset = 0; /* don't care, just track seen */ 313d4afb5ceSopenharmony_ci a1->orig = (const char *)pol->trust.store->ssx509[n]; 314d4afb5ceSopenharmony_ci certmap = a1; 315d4afb5ceSopenharmony_ci 316d4afb5ceSopenharmony_ci printf("static const uint8_t _ss_der_%s[] = {\n", 317d4afb5ceSopenharmony_ci purify_csymbol(pol->trust.store->ssx509[n]->vhost_name, 318d4afb5ceSopenharmony_ci buf, sizeof(buf))); 319d4afb5ceSopenharmony_ci 320d4afb5ceSopenharmony_ci for (m = 0; m < (int)pol->trust.store->ssx509[n]->ca_der_len; m++) { 321d4afb5ceSopenharmony_ci if ((m & 7) == 0) 322d4afb5ceSopenharmony_ci printf("\t/* 0x%3x */ ", m); 323d4afb5ceSopenharmony_ci 324d4afb5ceSopenharmony_ci printf("0x%02X, ", pol->trust.store->ssx509[n]->ca_der[m]); 325d4afb5ceSopenharmony_ci if ((m & 7) == 7) 326d4afb5ceSopenharmony_ci printf("\n"); 327d4afb5ceSopenharmony_ci } 328d4afb5ceSopenharmony_ci 329d4afb5ceSopenharmony_ci printf("\n};\nstatic const lws_ss_x509_t _ss_x509_%s = {\n", 330d4afb5ceSopenharmony_ci purify_csymbol(pol->trust.store->ssx509[n]->vhost_name, 331d4afb5ceSopenharmony_ci buf, sizeof(buf))); 332d4afb5ceSopenharmony_ci printf("\t.vhost_name = \"%s\",\n", pol->trust.store->ssx509[n]->vhost_name); 333d4afb5ceSopenharmony_ci printf("\t.ca_der = _ss_der_%s,\n", 334d4afb5ceSopenharmony_ci purify_csymbol(pol->trust.store->ssx509[n]->vhost_name, 335d4afb5ceSopenharmony_ci buf, sizeof(buf))); 336d4afb5ceSopenharmony_ci printf("\t.ca_der_len = %zu,\n", pol->trust.store->ssx509[n]->ca_der_len); 337d4afb5ceSopenharmony_ci printf("};\n"); 338d4afb5ceSopenharmony_ci 339d4afb5ceSopenharmony_ci est += sizeof(lws_ss_x509_t) + pol->trust.store->ssx509[n]->ca_der_len; 340d4afb5ceSopenharmony_ci } 341d4afb5ceSopenharmony_ci 342d4afb5ceSopenharmony_ci } 343d4afb5ceSopenharmony_ci 344d4afb5ceSopenharmony_ci 345d4afb5ceSopenharmony_ci printf("static const lws_ss_trust_store_t _ss_ts_%s = {\n", 346d4afb5ceSopenharmony_ci purify_csymbol(pol->trust.store->name, 347d4afb5ceSopenharmony_ci buf, sizeof(buf))); 348d4afb5ceSopenharmony_ci 349d4afb5ceSopenharmony_ci printf("\t.name = \"%s\",\n", pol->trust.store->name); 350d4afb5ceSopenharmony_ci printf("\t.count = %d,\n", pol->trust.store->count); 351d4afb5ceSopenharmony_ci printf("\t.ssx509 = {\n"); 352d4afb5ceSopenharmony_ci 353d4afb5ceSopenharmony_ci for (n = pol->trust.store->count - 1; n >= 0 ; n--) 354d4afb5ceSopenharmony_ci printf("\t\t&_ss_x509_%s,\n", 355d4afb5ceSopenharmony_ci pol->trust.store->ssx509[n]->vhost_name); 356d4afb5ceSopenharmony_ci 357d4afb5ceSopenharmony_ci printf("\t}\n};\n"); 358d4afb5ceSopenharmony_ci 359d4afb5ceSopenharmony_ci est += sizeof(lws_ss_trust_store_t); 360d4afb5ceSopenharmony_ci 361d4afb5ceSopenharmony_ci } 362d4afb5ceSopenharmony_ci } 363d4afb5ceSopenharmony_ci 364d4afb5ceSopenharmony_ci pol = pol->next; 365d4afb5ceSopenharmony_ci } 366d4afb5ceSopenharmony_ci 367d4afb5ceSopenharmony_ci 368d4afb5ceSopenharmony_ci /* dump any streamtype's http resp map */ 369d4afb5ceSopenharmony_ci 370d4afb5ceSopenharmony_ci pol = lws_ss_policy_get(context); 371d4afb5ceSopenharmony_ci m = 0; 372d4afb5ceSopenharmony_ci 373d4afb5ceSopenharmony_ci while (pol) { 374d4afb5ceSopenharmony_ci 375d4afb5ceSopenharmony_ci lws_snprintf(curr, sizeof(curr), "_ssp_%s", 376d4afb5ceSopenharmony_ci purify_csymbol(pol->streamtype, buf, sizeof(buf))); 377d4afb5ceSopenharmony_ci 378d4afb5ceSopenharmony_ci /* if relevant, dump http resp map */ 379d4afb5ceSopenharmony_ci 380d4afb5ceSopenharmony_ci switch (pol->protocol) { 381d4afb5ceSopenharmony_ci case LWSSSP_H1: 382d4afb5ceSopenharmony_ci case LWSSSP_H2: 383d4afb5ceSopenharmony_ci case LWSSSP_WS: 384d4afb5ceSopenharmony_ci 385d4afb5ceSopenharmony_ci if (!pol->u.http.count_respmap) 386d4afb5ceSopenharmony_ci break; 387d4afb5ceSopenharmony_ci 388d4afb5ceSopenharmony_ci if (!m) 389d4afb5ceSopenharmony_ci printf("\nstatic const lws_ss_http_respmap_t "); 390d4afb5ceSopenharmony_ci else 391d4afb5ceSopenharmony_ci printf(",\n"); 392d4afb5ceSopenharmony_ci m++; 393d4afb5ceSopenharmony_ci 394d4afb5ceSopenharmony_ci printf("%s_http_respmap[] = {\n", curr); 395d4afb5ceSopenharmony_ci for (n = 0; n < pol->u.http.count_respmap; n++) { 396d4afb5ceSopenharmony_ci printf("\t{ %d, 0x%x },\n", 397d4afb5ceSopenharmony_ci pol->u.http.respmap[n].resp, 398d4afb5ceSopenharmony_ci pol->u.http.respmap[n].state); 399d4afb5ceSopenharmony_ci 400d4afb5ceSopenharmony_ci est += sizeof(lws_ss_http_respmap_t); 401d4afb5ceSopenharmony_ci } 402d4afb5ceSopenharmony_ci printf("}"); 403d4afb5ceSopenharmony_ci break; 404d4afb5ceSopenharmony_ci } 405d4afb5ceSopenharmony_ci 406d4afb5ceSopenharmony_ci pol = pol->next; 407d4afb5ceSopenharmony_ci } 408d4afb5ceSopenharmony_ci 409d4afb5ceSopenharmony_ci if (m) 410d4afb5ceSopenharmony_ci printf(";\n"); 411d4afb5ceSopenharmony_ci 412d4afb5ceSopenharmony_ci /* 413d4afb5ceSopenharmony_ci * The auth map 414d4afb5ceSopenharmony_ci */ 415d4afb5ceSopenharmony_ci 416d4afb5ceSopenharmony_ci auth = lws_ss_auth_get(context); 417d4afb5ceSopenharmony_ci if (auth) 418d4afb5ceSopenharmony_ci printf("\nstatic const lws_ss_auth_t "); 419d4afb5ceSopenharmony_ci prev[0] = '\0'; 420d4afb5ceSopenharmony_ci 421d4afb5ceSopenharmony_ci while (auth) { 422d4afb5ceSopenharmony_ci lws_snprintf(curr, sizeof(curr), "_ssau_%s", 423d4afb5ceSopenharmony_ci purify_csymbol(auth->name, buf, sizeof(buf))); 424d4afb5ceSopenharmony_ci 425d4afb5ceSopenharmony_ci printf("%s = {\n", curr); 426d4afb5ceSopenharmony_ci if (prev[0]) 427d4afb5ceSopenharmony_ci printf("\t.next = (void *)&%s,\n", prev); 428d4afb5ceSopenharmony_ci 429d4afb5ceSopenharmony_ci printf("\t.name = \"%s\",\n", auth->name); 430d4afb5ceSopenharmony_ci printf("\t.type= \"%s\",\n", auth->type); 431d4afb5ceSopenharmony_ci printf("\t.streamtype = \"%s\",\n", auth->streamtype); 432d4afb5ceSopenharmony_ci printf("\t.blob_index = %d,\n", auth->blob_index); 433d4afb5ceSopenharmony_ci printf("}"); 434d4afb5ceSopenharmony_ci if (auth->next) 435d4afb5ceSopenharmony_ci printf(","); 436d4afb5ceSopenharmony_ci else 437d4afb5ceSopenharmony_ci printf(";"); 438d4afb5ceSopenharmony_ci printf("\n"); 439d4afb5ceSopenharmony_ci 440d4afb5ceSopenharmony_ci lws_strncpy(prev, curr, sizeof(prev)); 441d4afb5ceSopenharmony_ci 442d4afb5ceSopenharmony_ci auth = auth->next; 443d4afb5ceSopenharmony_ci } 444d4afb5ceSopenharmony_ci 445d4afb5ceSopenharmony_ci if (lws_ss_auth_get(context)) 446d4afb5ceSopenharmony_ci printf("\n"); 447d4afb5ceSopenharmony_ci 448d4afb5ceSopenharmony_ci /* 449d4afb5ceSopenharmony_ci * The streamtypes 450d4afb5ceSopenharmony_ci */ 451d4afb5ceSopenharmony_ci 452d4afb5ceSopenharmony_ci pol = lws_ss_policy_get(context); 453d4afb5ceSopenharmony_ci 454d4afb5ceSopenharmony_ci printf("\nstatic const lws_ss_policy_t "); 455d4afb5ceSopenharmony_ci prev[0] = '\0'; 456d4afb5ceSopenharmony_ci 457d4afb5ceSopenharmony_ci while (pol) { 458d4afb5ceSopenharmony_ci 459d4afb5ceSopenharmony_ci est += sizeof(*pol); 460d4afb5ceSopenharmony_ci 461d4afb5ceSopenharmony_ci lws_snprintf(curr, sizeof(curr), "_ssp_%s", 462d4afb5ceSopenharmony_ci purify_csymbol(pol->streamtype, buf, sizeof(buf))); 463d4afb5ceSopenharmony_ci 464d4afb5ceSopenharmony_ci printf("%s = {\n", curr); 465d4afb5ceSopenharmony_ci 466d4afb5ceSopenharmony_ci if (prev[0]) 467d4afb5ceSopenharmony_ci printf("\t.next = (void *)&%s,\n", prev); 468d4afb5ceSopenharmony_ci 469d4afb5ceSopenharmony_ci printf("\t.streamtype = \"%s\",\n", pol->streamtype); 470d4afb5ceSopenharmony_ci if (pol->endpoint) 471d4afb5ceSopenharmony_ci printf("\t.endpoint = \"%s\",\n", pol->endpoint); 472d4afb5ceSopenharmony_ci if (pol->rideshare_streamtype) 473d4afb5ceSopenharmony_ci printf("\t.rideshare_streamtype = \"%s\",\n", 474d4afb5ceSopenharmony_ci pol->rideshare_streamtype); 475d4afb5ceSopenharmony_ci if (pol->payload_fmt) 476d4afb5ceSopenharmony_ci printf("\t.payload_fmt = \"%s\",\n", 477d4afb5ceSopenharmony_ci pol->payload_fmt); 478d4afb5ceSopenharmony_ci if (pol->socks5_proxy) 479d4afb5ceSopenharmony_ci printf("\t.socks5_proxy = \"%s\",\n", 480d4afb5ceSopenharmony_ci pol->socks5_proxy); 481d4afb5ceSopenharmony_ci 482d4afb5ceSopenharmony_ci if (pol->auth) 483d4afb5ceSopenharmony_ci printf("\t.auth = &_ssau_%s,\n", 484d4afb5ceSopenharmony_ci purify_csymbol(pol->auth->name, buf, sizeof(buf))); 485d4afb5ceSopenharmony_ci 486d4afb5ceSopenharmony_ci { 487d4afb5ceSopenharmony_ci lws_ss_metadata_t *nv = pol->metadata, *last = NULL; 488d4afb5ceSopenharmony_ci 489d4afb5ceSopenharmony_ci while (nv) { 490d4afb5ceSopenharmony_ci last = nv; 491d4afb5ceSopenharmony_ci nv = nv->next; 492d4afb5ceSopenharmony_ci } 493d4afb5ceSopenharmony_ci if (pol->metadata) 494d4afb5ceSopenharmony_ci printf("\t.metadata = (void *)&_md_%s_%s,\n", 495d4afb5ceSopenharmony_ci purify_csymbol(pol->streamtype, buf, sizeof(buf)), 496d4afb5ceSopenharmony_ci purify_csymbol(last->name, buf1, sizeof(buf1))); 497d4afb5ceSopenharmony_ci } 498d4afb5ceSopenharmony_ci 499d4afb5ceSopenharmony_ci 500d4afb5ceSopenharmony_ci switch (pol->protocol) { 501d4afb5ceSopenharmony_ci case LWSSSP_H1: 502d4afb5ceSopenharmony_ci case LWSSSP_H2: 503d4afb5ceSopenharmony_ci case LWSSSP_WS: 504d4afb5ceSopenharmony_ci 505d4afb5ceSopenharmony_ci printf("\t.u = {\n\t\t.http = {\n"); 506d4afb5ceSopenharmony_ci 507d4afb5ceSopenharmony_ci if (pol->u.http.method) 508d4afb5ceSopenharmony_ci printf("\t\t\t.method = \"%s\",\n", 509d4afb5ceSopenharmony_ci pol->u.http.method); 510d4afb5ceSopenharmony_ci if (pol->u.http.url) 511d4afb5ceSopenharmony_ci printf("\t\t\t.url = \"%s\",\n", 512d4afb5ceSopenharmony_ci pol->u.http.url); 513d4afb5ceSopenharmony_ci if (pol->u.http.multipart_name) 514d4afb5ceSopenharmony_ci printf("\t\t\t.multipart_name = \"%s\",\n", 515d4afb5ceSopenharmony_ci pol->u.http.multipart_name); 516d4afb5ceSopenharmony_ci if (pol->u.http.multipart_filename) 517d4afb5ceSopenharmony_ci printf("\t\t\t.multipart_filename = \"%s\",\n", 518d4afb5ceSopenharmony_ci pol->u.http.multipart_filename); 519d4afb5ceSopenharmony_ci if (pol->u.http.multipart_content_type) 520d4afb5ceSopenharmony_ci printf("\t\t\t.multipart_content_type = \"%s\",\n", 521d4afb5ceSopenharmony_ci pol->u.http.multipart_content_type); 522d4afb5ceSopenharmony_ci if (pol->u.http.auth_preamble) 523d4afb5ceSopenharmony_ci printf("\t\t\t.auth_preamble = \"%s\",\n", 524d4afb5ceSopenharmony_ci pol->u.http.auth_preamble); 525d4afb5ceSopenharmony_ci 526d4afb5ceSopenharmony_ci if (pol->u.http.respmap) { 527d4afb5ceSopenharmony_ci printf("\t\t\t.respmap = (void *)&%s_http_respmap,\n", 528d4afb5ceSopenharmony_ci curr); 529d4afb5ceSopenharmony_ci printf("\t\t\t.count_respmap = %d,\n", 530d4afb5ceSopenharmony_ci pol->u.http.count_respmap); 531d4afb5ceSopenharmony_ci } 532d4afb5ceSopenharmony_ci 533d4afb5ceSopenharmony_ci if (pol->u.http.blob_header[0]) { 534d4afb5ceSopenharmony_ci printf("\t\t\t.blob_header = {\n"); 535d4afb5ceSopenharmony_ci for (n = 0; n < (int)LWS_ARRAY_SIZE(pol->u.http.blob_header); n++) 536d4afb5ceSopenharmony_ci if (pol->u.http.blob_header[n]) 537d4afb5ceSopenharmony_ci printf("\t\t\t\t\"%s\",\n", 538d4afb5ceSopenharmony_ci pol->u.http.blob_header[n]); 539d4afb5ceSopenharmony_ci 540d4afb5ceSopenharmony_ci printf("\t\t\t},\n"); 541d4afb5ceSopenharmony_ci } 542d4afb5ceSopenharmony_ci 543d4afb5ceSopenharmony_ci if (pol->protocol == LWSSSP_WS) { 544d4afb5ceSopenharmony_ci printf("\t\t\t.u = {\n\t\t\t\t.ws = {\n"); 545d4afb5ceSopenharmony_ci if (pol->u.http.u.ws.subprotocol) 546d4afb5ceSopenharmony_ci printf("\t\t\t\t\t.subprotocol = \"%s\",\n", 547d4afb5ceSopenharmony_ci pol->u.http.u.ws.subprotocol); 548d4afb5ceSopenharmony_ci printf("\t\t\t\t\t.binary = %u\n", pol->u.http.u.ws.binary); 549d4afb5ceSopenharmony_ci printf("\t\t\t\t}\n\t\t\t},\n"); 550d4afb5ceSopenharmony_ci } 551d4afb5ceSopenharmony_ci 552d4afb5ceSopenharmony_ci if (pol->u.http.resp_expect) 553d4afb5ceSopenharmony_ci printf("\t\t\t.resp_expect = %u,\n", pol->u.http.resp_expect); 554d4afb5ceSopenharmony_ci if (pol->u.http.fail_redirect) 555d4afb5ceSopenharmony_ci printf("\t\t\t.fail_redirect = %u,\n", pol->u.http.fail_redirect); 556d4afb5ceSopenharmony_ci 557d4afb5ceSopenharmony_ci printf("\t\t}\n\t},\n"); 558d4afb5ceSopenharmony_ci 559d4afb5ceSopenharmony_ci break; 560d4afb5ceSopenharmony_ci case LWSSSP_MQTT: 561d4afb5ceSopenharmony_ci 562d4afb5ceSopenharmony_ci printf("\t.u = {\n\t\t.mqtt = {\n"); 563d4afb5ceSopenharmony_ci 564d4afb5ceSopenharmony_ci if (pol->u.mqtt.topic) 565d4afb5ceSopenharmony_ci printf("\t\t\t.topic = \"%s\",\n", 566d4afb5ceSopenharmony_ci pol->u.mqtt.topic); 567d4afb5ceSopenharmony_ci if (pol->u.mqtt.subscribe) 568d4afb5ceSopenharmony_ci printf("\t\t\t.subscribe = \"%s\",\n", 569d4afb5ceSopenharmony_ci pol->u.mqtt.subscribe); 570d4afb5ceSopenharmony_ci if (pol->u.mqtt.will_topic) 571d4afb5ceSopenharmony_ci printf("\t\t\t.will_topic = \"%s\",\n", 572d4afb5ceSopenharmony_ci pol->u.mqtt.will_topic); 573d4afb5ceSopenharmony_ci if (pol->u.mqtt.will_message) 574d4afb5ceSopenharmony_ci printf("\t\t\t.will_message = \"%s\",\n", 575d4afb5ceSopenharmony_ci pol->u.mqtt.will_message); 576d4afb5ceSopenharmony_ci if (pol->u.mqtt.will_qos) 577d4afb5ceSopenharmony_ci printf("\t\t\t.will_qos = %u,\n", 578d4afb5ceSopenharmony_ci pol->u.mqtt.will_qos); 579d4afb5ceSopenharmony_ci if (pol->u.mqtt.will_retain) 580d4afb5ceSopenharmony_ci printf("\t\t\t.will_retain = %u,\n", 581d4afb5ceSopenharmony_ci pol->u.mqtt.will_retain); 582d4afb5ceSopenharmony_ci if (pol->u.mqtt.birth_topic) 583d4afb5ceSopenharmony_ci printf("\t\t\t.birth_topic = \"%s\",\n", 584d4afb5ceSopenharmony_ci pol->u.mqtt.birth_topic); 585d4afb5ceSopenharmony_ci if (pol->u.mqtt.birth_message) 586d4afb5ceSopenharmony_ci printf("\t\t\t.birth_message = \"%s\",\n", 587d4afb5ceSopenharmony_ci pol->u.mqtt.birth_message); 588d4afb5ceSopenharmony_ci if (pol->u.mqtt.birth_qos) 589d4afb5ceSopenharmony_ci printf("\t\t\t.birth_qos = %u,\n", 590d4afb5ceSopenharmony_ci pol->u.mqtt.birth_qos); 591d4afb5ceSopenharmony_ci if (pol->u.mqtt.birth_retain) 592d4afb5ceSopenharmony_ci printf("\t\t\t.birth_retain = %u,\n", 593d4afb5ceSopenharmony_ci pol->u.mqtt.birth_retain); 594d4afb5ceSopenharmony_ci if (pol->u.mqtt.keep_alive) 595d4afb5ceSopenharmony_ci printf("\t\t\t.keep_alive = %u,\n", 596d4afb5ceSopenharmony_ci pol->u.mqtt.keep_alive); 597d4afb5ceSopenharmony_ci if (pol->u.mqtt.qos) 598d4afb5ceSopenharmony_ci printf("\t\t\t.qos = %u,\n", 599d4afb5ceSopenharmony_ci pol->u.mqtt.qos); 600d4afb5ceSopenharmony_ci if (pol->u.mqtt.clean_start) 601d4afb5ceSopenharmony_ci printf("\t\t\t.clean_start = %u,\n", 602d4afb5ceSopenharmony_ci pol->u.mqtt.clean_start); 603d4afb5ceSopenharmony_ci if (pol->u.mqtt.aws_iot) 604d4afb5ceSopenharmony_ci printf("\t\t\t.aws_iot = %u,\n", 605d4afb5ceSopenharmony_ci pol->u.mqtt.aws_iot); 606d4afb5ceSopenharmony_ci if (pol->u.mqtt.retain) 607d4afb5ceSopenharmony_ci printf("\t\t\t.retain = %u,\n", 608d4afb5ceSopenharmony_ci pol->u.mqtt.retain); 609d4afb5ceSopenharmony_ci printf("\t\t}\n\t},\n"); 610d4afb5ceSopenharmony_ci 611d4afb5ceSopenharmony_ci break; 612d4afb5ceSopenharmony_ci default: 613d4afb5ceSopenharmony_ci lwsl_err("%s: unknown ss protocol index %d\n", __func__, 614d4afb5ceSopenharmony_ci pol->protocol); 615d4afb5ceSopenharmony_ci goto bail; 616d4afb5ceSopenharmony_ci } 617d4afb5ceSopenharmony_ci 618d4afb5ceSopenharmony_ci#if 0 619d4afb5ceSopenharmony_ci const lws_ss_trust_store_t *trust_store; /**< CA certs needed for conn 620d4afb5ceSopenharmony_ci validation, only set between policy parsing and vhost creation */ 621d4afb5ceSopenharmony_ci#endif 622d4afb5ceSopenharmony_ci 623d4afb5ceSopenharmony_ci if (pol->retry_bo) { 624d4afb5ceSopenharmony_ci a = rbomap; 625d4afb5ceSopenharmony_ci while (a) { 626d4afb5ceSopenharmony_ci if (a->orig == (const char *)pol->retry_bo) 627d4afb5ceSopenharmony_ci break; 628d4afb5ceSopenharmony_ci 629d4afb5ceSopenharmony_ci a = a->next; 630d4afb5ceSopenharmony_ci } 631d4afb5ceSopenharmony_ci if (!a) 632d4afb5ceSopenharmony_ci goto bail; 633d4afb5ceSopenharmony_ci 634d4afb5ceSopenharmony_ci printf("\t.retry_bo = &_rbo_%zu,\n", a->offset); 635d4afb5ceSopenharmony_ci } 636d4afb5ceSopenharmony_ci 637d4afb5ceSopenharmony_ci if (pol->timeout_ms) 638d4afb5ceSopenharmony_ci printf("\t.timeout_ms = %u,\n", pol->timeout_ms); 639d4afb5ceSopenharmony_ci if (pol->flags) 640d4afb5ceSopenharmony_ci printf("\t.flags = 0x%x,\n", pol->flags); 641d4afb5ceSopenharmony_ci if (pol->flags) 642d4afb5ceSopenharmony_ci printf("\t.priority = 0x%x,\n", (unsigned int)pol->priority); 643d4afb5ceSopenharmony_ci if (pol->port) 644d4afb5ceSopenharmony_ci printf("\t.port = %u,\n", pol->port); 645d4afb5ceSopenharmony_ci if (pol->metadata_count) 646d4afb5ceSopenharmony_ci printf("\t.metadata_count = %u,\n", pol->metadata_count); 647d4afb5ceSopenharmony_ci printf("\t.protocol = %u,\n", pol->protocol); 648d4afb5ceSopenharmony_ci if (pol->client_cert) 649d4afb5ceSopenharmony_ci printf("\t.client_cert = %u,\n", pol->client_cert); 650d4afb5ceSopenharmony_ci 651d4afb5ceSopenharmony_ci if (pol->trust.store) 652d4afb5ceSopenharmony_ci printf("\t.trust = {.store = &_ss_ts_%s},\n", 653d4afb5ceSopenharmony_ci purify_csymbol(pol->trust.store->name, 654d4afb5ceSopenharmony_ci buf, sizeof(buf))); 655d4afb5ceSopenharmony_ci#if defined(LWS_WITH_SECURE_STREAMS_AUTH_SIGV4) 656d4afb5ceSopenharmony_ci if (pol->aws_region) 657d4afb5ceSopenharmony_ci printf("\t.aws_region= \"%s\",\n", pol->aws_region); 658d4afb5ceSopenharmony_ci if (pol->aws_service) 659d4afb5ceSopenharmony_ci printf("\t.aws_service= \"%s\",\n", pol->aws_service); 660d4afb5ceSopenharmony_ci 661d4afb5ceSopenharmony_ci#endif 662d4afb5ceSopenharmony_ci 663d4afb5ceSopenharmony_ci 664d4afb5ceSopenharmony_ci printf("}"); 665d4afb5ceSopenharmony_ci if (pol->next) 666d4afb5ceSopenharmony_ci printf(",\n"); 667d4afb5ceSopenharmony_ci 668d4afb5ceSopenharmony_ci lws_strncpy(prev, curr, sizeof(prev)); 669d4afb5ceSopenharmony_ci 670d4afb5ceSopenharmony_ci lastpol = pol; 671d4afb5ceSopenharmony_ci 672d4afb5ceSopenharmony_ci pol = pol->next; 673d4afb5ceSopenharmony_ci } 674d4afb5ceSopenharmony_ci 675d4afb5ceSopenharmony_ci printf(";\n"); 676d4afb5ceSopenharmony_ci if (lastpol) 677d4afb5ceSopenharmony_ci printf("#define _ss_static_policy_entry _ssp_%s\n", 678d4afb5ceSopenharmony_ci purify_csymbol(lastpol->streamtype, buf, sizeof(buf))); 679d4afb5ceSopenharmony_ci 680d4afb5ceSopenharmony_ci est += last_offset; 681d4afb5ceSopenharmony_ci 682d4afb5ceSopenharmony_ci printf("/* estimated footprint %zu (when sizeof void * = %zu) */\n", 683d4afb5ceSopenharmony_ci est, sizeof(void *)); 684d4afb5ceSopenharmony_ci 685d4afb5ceSopenharmony_ci lws_ss_policy_parse_abandon(context); 686d4afb5ceSopenharmony_ci bad = 0; 687d4afb5ceSopenharmony_ci 688d4afb5ceSopenharmony_cibail: 689d4afb5ceSopenharmony_ci 690d4afb5ceSopenharmony_ci 691d4afb5ceSopenharmony_ci lws_context_destroy(context); 692d4afb5ceSopenharmony_ci 693d4afb5ceSopenharmony_ci lwsl_user("Completed: %s\n", bad ? "failed" : "OK"); 694d4afb5ceSopenharmony_ci 695d4afb5ceSopenharmony_ci return bad; 696d4afb5ceSopenharmony_ci} 697