1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-23 00:00:06 +01:00

ss: policy: add auth mapping section

This commit is contained in:
Andy Green 2020-08-19 11:21:58 +01:00
parent 692f269045
commit a204886eff
8 changed files with 204 additions and 20 deletions

View file

@ -163,6 +163,19 @@ typedef struct lws_ss_metadata {
uint8_t value_on_lws_heap; /* proxy does this */ uint8_t value_on_lws_heap; /* proxy does this */
} lws_ss_metadata_t; } lws_ss_metadata_t;
/*
* This is a mapping between an auth streamtype and a name and other information
* that can be independently instantiated. Other streamtypes can indicate they
* require this authentication on their connection.
*/
typedef struct lws_ss_auth {
struct lws_ss_auth *next;
const char *name;
const char *streamtype;
uint8_t blob_index;
} lws_ss_auth_t;
/** /**
* lws_ss_policy_t: policy database entry for a stream type * lws_ss_policy_t: policy database entry for a stream type
@ -188,6 +201,7 @@ typedef struct lws_ss_policy {
const char *payload_fmt; const char *payload_fmt;
const char *socks5_proxy; const char *socks5_proxy;
lws_ss_metadata_t *metadata; /* linked-list of metadata */ lws_ss_metadata_t *metadata; /* linked-list of metadata */
const lws_ss_auth_t *auth; /* NULL or auth object we bind to */
/* protocol-specific connection policy details */ /* protocol-specific connection policy details */
@ -308,10 +322,14 @@ LWS_VISIBLE LWS_EXTERN int
lws_ss_policy_overlay(struct lws_context *context, const char *overlay); lws_ss_policy_overlay(struct lws_context *context, const char *overlay);
/* /*
* You almost certainly don't want this, it returns the first policy object * You almost certainly don't want these, they return the first policy or auth
* in a linked-list of objects created by lws_ss_policy_parse above * object in a linked-list of objects created by lws_ss_policy_parse above,
* they are exported to generate static policy with
*/ */
LWS_VISIBLE LWS_EXTERN const lws_ss_policy_t * LWS_VISIBLE LWS_EXTERN const lws_ss_policy_t *
lws_ss_policy_get(struct lws_context *context); lws_ss_policy_get(struct lws_context *context);
LWS_VISIBLE LWS_EXTERN const lws_ss_auth_t *
lws_ss_auth_get(struct lws_context *context);
#endif #endif

View file

@ -497,6 +497,7 @@ struct lws_context {
void *pol_args; void *pol_args;
#endif #endif
const lws_ss_policy_t *pss_policies; const lws_ss_policy_t *pss_policies;
const lws_ss_auth_t *pss_auths;
#if defined(LWS_WITH_SSPLUGINS) #if defined(LWS_WITH_SSPLUGINS)
const lws_ss_plugin_t **pss_plugins; const lws_ss_plugin_t **pss_plugins;
#endif #endif

View file

@ -195,6 +195,34 @@ with one of these to enforce validity checking of the remote server.
Entries should be named using "name" and the stack array defined using "stack" Entries should be named using "name" and the stack array defined using "stack"
### `auth`
Optional section describing a map of available authentication streamtypes to
auth token blob indexes.
```
...
"auth": [{"name":"lwa","streamtype":"api_amazon_com_lwa","blob":0}]
...
```
Streams can indicate they depend on a valid auth token from one of these schemes
by using the `"use_auth": "name"` member in the streamtype definition, where name
is, eg, "lwa" in the example above.
### `auth[].name`
This is the name of the authentication scheme used by other streamtypes
### `auth[].streamtype`
This is the auth streamtype to be used to refresh the authentication token
### `auth[].blob`
This is the auth blob index the authentication token is stored into and retreived
from
### `s` ### `s`
These are an array of policies for the supported stream type names. These are an array of policies for the supported stream type names.
@ -293,6 +321,11 @@ policy is applied.
The name of the trust store described in the `trust_stores` section to apply The name of the trust store described in the `trust_stores` section to apply
to validate the remote server cert. to validate the remote server cert.
### `use_auth`
Indicate that the streamtype should use the named auth type from the `auth`
array in the policy
### `server_cert` ### `server_cert`
**SERVER ONLY**: subject to change... the name of the x.509 cert that is the **SERVER ONLY**: subject to change... the name of the x.509 cert that is the

View file

@ -97,7 +97,12 @@ static const char * const lejp_tokens_policy[] = {
"s[].*.mqtt_will_qos", "s[].*.mqtt_will_qos",
"s[].*.mqtt_will_retain", "s[].*.mqtt_will_retain",
"s[].*.swake_validity", "s[].*.swake_validity",
"s[].*.use_auth",
"s[].*", "s[].*",
"auth[].name",
"auth[].streamtype",
"auth[].blob",
"auth[]",
}; };
typedef enum { typedef enum {
@ -169,7 +174,12 @@ typedef enum {
LSSPPT_MQTT_WILL_QOS, LSSPPT_MQTT_WILL_QOS,
LSSPPT_MQTT_WILL_RETAIN, LSSPPT_MQTT_WILL_RETAIN,
LSSPPT_SWAKE_VALIDITY, LSSPPT_SWAKE_VALIDITY,
LSSPPT_USE_AUTH,
LSSPPT_STREAMTYPES, LSSPPT_STREAMTYPES,
LSSPPT_AUTH_NAME,
LSSPPT_AUTH_STREAMTYPE,
LSSPPT_AUTH_BLOB,
LSSPPT_AUTH,
} policy_token_t; } policy_token_t;
@ -182,9 +192,10 @@ static uint8_t sizes[] = {
sizeof(lws_ss_x509_t), sizeof(lws_ss_x509_t),
sizeof(lws_ss_trust_store_t), sizeof(lws_ss_trust_store_t),
sizeof(lws_ss_policy_t), sizeof(lws_ss_policy_t),
sizeof(lws_ss_auth_t),
}; };
static const char *protonames[] = { static const char * const protonames[] = {
"h1", /* LWSSSP_H1 */ "h1", /* LWSSSP_H1 */
"h2", /* LWSSSP_H2 */ "h2", /* LWSSSP_H2 */
"ws", /* LWSSSP_WS */ "ws", /* LWSSSP_WS */
@ -192,6 +203,24 @@ static const char *protonames[] = {
"raw", /* LWSSSP_RAW */ "raw", /* LWSSSP_RAW */
}; };
static const lws_ss_auth_t *
lws_ss_policy_find_auth_by_name(struct policy_cb_args *a,
const char *name, size_t len)
{
const lws_ss_auth_t *auth = a->heads[LTY_AUTH].a;
while (auth) {
if (auth->name &&
len == strlen(auth->name) &&
!strncmp(auth->name, name, len))
return auth;
auth = auth->next;
}
return NULL;
}
static signed char static signed char
lws_ss_policy_parser_cb(struct lejp_ctx *ctx, char reason) lws_ss_policy_parser_cb(struct lejp_ctx *ctx, char reason)
{ {
@ -210,8 +239,8 @@ lws_ss_policy_parser_cb(struct lejp_ctx *ctx, char reason)
backoff_t *bot; backoff_t *bot;
int n = -1; int n = -1;
lwsl_debug("%s: %d %d %s\n", __func__, reason, ctx->path_match - 1, // lwsl_debug("%s: %d %d %s\n", __func__, reason, ctx->path_match - 1,
ctx->path); // ctx->path);
switch (ctx->path_match - 1) { switch (ctx->path_match - 1) {
case LSSPPT_RETRY: case LSSPPT_RETRY:
@ -227,6 +256,9 @@ lws_ss_policy_parser_cb(struct lejp_ctx *ctx, char reason)
case LSSPPT_STREAMTYPES: case LSSPPT_STREAMTYPES:
n = LTY_POLICY; n = LTY_POLICY;
break; break;
case LSSPPT_AUTH:
n = LTY_AUTH;
break;
} }
if (reason == LEJPCB_ARRAY_START && if (reason == LEJPCB_ARRAY_START &&
@ -234,6 +266,17 @@ lws_ss_policy_parser_cb(struct lejp_ctx *ctx, char reason)
ctx->path_match - 1 == LSSPPT_METADATA)) ctx->path_match - 1 == LSSPPT_METADATA))
a->count = 0; a->count = 0;
if (reason == LEJPCB_OBJECT_START && n == LTY_AUTH) {
a->curr[n].b = lwsac_use_zero(&a->ac, sizes[n], POL_AC_GRAIN);
if (!a->curr[n].b)
goto oom;
a->curr[n].b->next = a->heads[n].b;
a->heads[n].b = a->curr[n].b;
return 0;
}
if (reason == LEJPCB_ARRAY_END && if (reason == LEJPCB_ARRAY_END &&
ctx->path_match - 1 == LSSPPT_TRUST_STORES_STACK && !a->count) { ctx->path_match - 1 == LSSPPT_TRUST_STORES_STACK && !a->count) {
lwsl_err("%s: at least one cert required in trust store\n", lwsl_err("%s: at least one cert required in trust store\n",
@ -264,7 +307,8 @@ lws_ss_policy_parser_cb(struct lejp_ctx *ctx, char reason)
return 0; return 0;
} }
if (reason == LEJPCB_PAIR_NAME && n != -1 && n != LTY_TRUSTSTORE) { if (reason == LEJPCB_PAIR_NAME && n != -1 &&
(n != LTY_TRUSTSTORE && n != LTY_AUTH)) {
p2 = NULL; p2 = NULL;
if (n == LTY_POLICY) { if (n == LTY_POLICY) {
@ -543,6 +587,10 @@ lws_ss_policy_parser_cb(struct lejp_ctx *ctx, char reason)
a->curr[LTY_POLICY].p->client_cert = atoi(ctx->buf) + 1; a->curr[LTY_POLICY].p->client_cert = atoi(ctx->buf) + 1;
break; break;
case LSSPPT_AUTH_BLOB:
a->curr[LTY_AUTH].a->blob_index = atoi(ctx->buf);
break;
case LSSPPT_HTTP_EXPECT: case LSSPPT_HTTP_EXPECT:
a->curr[LTY_POLICY].p->u.http.resp_expect = atoi(ctx->buf); a->curr[LTY_POLICY].p->u.http.resp_expect = atoi(ctx->buf);
break; break;
@ -624,6 +672,16 @@ lws_ss_policy_parser_cb(struct lejp_ctx *ctx, char reason)
case LSSPPT_METADATA: case LSSPPT_METADATA:
break; break;
case LSSPPT_USE_AUTH:
a->curr[LTY_POLICY].p->auth =
lws_ss_policy_find_auth_by_name(a, ctx->buf, ctx->npos);
if (!a->curr[LTY_POLICY].p->auth) {
lws_strnncpy(dotstar, ctx->buf, ctx->npos, sizeof(dotstar));
lwsl_err("%s: unknown auth '%s'\n", __func__, dotstar);
return -1;
}
break;
case LSSPPT_METADATA_ITEM: case LSSPPT_METADATA_ITEM:
pmd = a->curr[LTY_POLICY].p->metadata; pmd = a->curr[LTY_POLICY].p->metadata;
a->curr[LTY_POLICY].p->metadata = lwsac_use_zero(&a->ac, a->curr[LTY_POLICY].p->metadata = lwsac_use_zero(&a->ac,
@ -688,6 +746,14 @@ lws_ss_policy_parser_cb(struct lejp_ctx *ctx, char reason)
pp = (char **)&a->curr[LTY_POLICY].p->u.http.multipart_content_type; pp = (char **)&a->curr[LTY_POLICY].p->u.http.multipart_content_type;
goto string2; goto string2;
case LSSPPT_AUTH_NAME:
pp = (char **)&a->curr[LTY_AUTH].a->name;
goto string2;
case LSSPPT_AUTH_STREAMTYPE:
pp = (char **)&a->curr[LTY_AUTH].a->streamtype;
goto string2;
case LSSPPT_HTTP_FAIL_REDIRECT: case LSSPPT_HTTP_FAIL_REDIRECT:
a->curr[LTY_POLICY].p->u.http.fail_redirect = a->curr[LTY_POLICY].p->u.http.fail_redirect =
reason == LEJPCB_VAL_TRUE; reason == LEJPCB_VAL_TRUE;
@ -894,3 +960,14 @@ lws_ss_policy_get(struct lws_context *context)
return args->heads[LTY_POLICY].p; return args->heads[LTY_POLICY].p;
} }
const lws_ss_auth_t *
lws_ss_auth_get(struct lws_context *context)
{
struct policy_cb_args *args = (struct policy_cb_args *)context->pol_args;
if (!args)
return NULL;
return args->heads[LTY_AUTH].a;
}

View file

@ -300,6 +300,7 @@ union u {
lws_ss_x509_t *x; lws_ss_x509_t *x;
lws_ss_trust_store_t *t; lws_ss_trust_store_t *t;
lws_ss_policy_t *p; lws_ss_policy_t *p;
lws_ss_auth_t *a;
}; };
enum { enum {
@ -307,6 +308,7 @@ enum {
LTY_X509, LTY_X509,
LTY_TRUSTSTORE, LTY_TRUSTSTORE,
LTY_POLICY, LTY_POLICY,
LTY_AUTH,
_LTY_COUNT /* always last */ _LTY_COUNT /* always last */
}; };

View file

@ -175,14 +175,20 @@ static const char * const default_ss_policy =
"]" "]"
"}" "}"
"]," "],"
"\"auth\": [" /* available auth type bindings */
"{"
"\"name\":" "\"lwa\","
"\"streamtype\":" "\"api_amazon_com_lwa\","
"\"blob\":" "0"
"}"
"],"
"\"s\": [" /* the supported stream types */ "\"s\": [" /* the supported stream types */
"{\"api_amazon_com_auth\": {" "{\"api_amazon_com_lwa\": {"
"\"endpoint\":" "\"api.amazon.com\"," "\"endpoint\":" "\"api.amazon.com\","
"\"port\":" "443," "\"port\":" "443,"
"\"protocol\":" "\"h1\"," "\"protocol\":" "\"h1\","
"\"http_method\":" "\"POST\"," "\"http_method\":" "\"POST\","
"\"http_url\":" "\"auth/o2/token\"," "\"http_url\":" "\"auth/o2/token\","
"\"plugins\":" "[],"
"\"opportunistic\":" "true," "\"opportunistic\":" "true,"
"\"tls\":" "true," "\"tls\":" "true,"
"\"h2q_oflow_txcr\":" "true," "\"h2q_oflow_txcr\":" "true,"
@ -200,6 +206,7 @@ static const char * const default_ss_policy =
"\"protocol\":" "\"h2\"," "\"protocol\":" "\"h2\","
"\"http_method\":" "\"GET\"," "\"http_method\":" "\"GET\","
"\"http_url\":" "\"v20160207/directives\"," "\"http_url\":" "\"v20160207/directives\","
"\"use_auth\":" "\"lwa\","
"\"h2q_oflow_txcr\":" "true," "\"h2q_oflow_txcr\":" "true,"
"\"http_auth_header\":" "\"authorization:\"," "\"http_auth_header\":" "\"authorization:\","
"\"http_auth_preamble\":" "\"Bearer \"," "\"http_auth_preamble\":" "\"Bearer \","
@ -207,7 +214,6 @@ static const char * const default_ss_policy =
"\"nailed_up\":" "true," "\"nailed_up\":" "true,"
"\"long_poll\":" "true," "\"long_poll\":" "true,"
"\"retry\":" "\"default\"," "\"retry\":" "\"default\","
"\"plugins\":" "[],"
"\"tls\":" "true," "\"tls\":" "true,"
"\"tls_trust_store\":" "\"avs_via_starfield\"" "\"tls_trust_store\":" "\"avs_via_starfield\""
"}}," "}},"
@ -223,6 +229,7 @@ static const char * const default_ss_policy =
"\"protocol\":" "\"h2\"," "\"protocol\":" "\"h2\","
"\"http_method\":" "\"POST\"," "\"http_method\":" "\"POST\","
"\"http_url\":" "\"v20160207/events\"," "\"http_url\":" "\"v20160207/events\","
"\"use_auth\":" "\"lwa\","
"\"opportunistic\":" "true," "\"opportunistic\":" "true,"
"\"h2q_oflow_txcr\":" "true," "\"h2q_oflow_txcr\":" "true,"
"\"http_auth_header\":" "\"authorization:\"," "\"http_auth_header\":" "\"authorization:\","
@ -233,7 +240,6 @@ static const char * const default_ss_policy =
"\"http_multipart_ss_in\":" "true," "\"http_multipart_ss_in\":" "true,"
"\"rideshare\":" "\"avs_audio\"," "\"rideshare\":" "\"avs_audio\","
"\"retry\":" "\"default\"," "\"retry\":" "\"default\","
"\"plugins\":" "[],"
"\"tls\":" "true," "\"tls\":" "true,"
"\"tls_trust_store\":" "\"avs_via_starfield\"" "\"tls_trust_store\":" "\"avs_via_starfield\""
"}}," "}},"
@ -243,7 +249,7 @@ static const char * const default_ss_policy =
"\"protocol\":" "\"h2\"," "\"protocol\":" "\"h2\","
"\"http_method\":" "\"POST\"," "\"http_method\":" "\"POST\","
"\"http_url\":" "\"v20160207/events\"," "\"http_url\":" "\"v20160207/events\","
"\"plugins\":" "[]," "\"use_auth\":" "\"lwa\","
"\"tls\":" "true," "\"tls\":" "true,"
"\"h2q_oflow_txcr\":" "true," "\"h2q_oflow_txcr\":" "true,"
"\"http_auth_header\":" "\"authorization:\"," "\"http_auth_header\":" "\"authorization:\","

View file

@ -151,14 +151,20 @@ static const char * const default_ss_policy =
"]" "]"
"}" "}"
"]," "],"
"\"auth\": [" /* available auth type bindings */
"{"
"\"name\":" "\"lwa\","
"\"streamtype\":" "\"api_amazon_com_lwa\","
"\"blob\":" "0"
"}"
"],"
"\"s\": [" /* the supported stream types */ "\"s\": [" /* the supported stream types */
"{\"api_amazon_com_auth\": {" "{\"api_amazon_com_lwa\": {"
"\"endpoint\":" "\"api.amazon.com\"," "\"endpoint\":" "\"api.amazon.com\","
"\"port\":" "443," "\"port\":" "443,"
"\"protocol\":" "\"h1\"," "\"protocol\":" "\"h1\","
"\"http_method\":" "\"POST\"," "\"http_method\":" "\"POST\","
"\"http_url\":" "\"auth/o2/token\"," "\"http_url\":" "\"auth/o2/token\","
"\"plugins\":" "[],"
"\"opportunistic\":" "true," "\"opportunistic\":" "true,"
"\"tls\":" "true," "\"tls\":" "true,"
"\"h2q_oflow_txcr\":" "true," "\"h2q_oflow_txcr\":" "true,"
@ -176,10 +182,10 @@ static const char * const default_ss_policy =
"\"h2q_oflow_txcr\":" "true," "\"h2q_oflow_txcr\":" "true,"
"\"http_auth_header\":" "\"authorization:\"," "\"http_auth_header\":" "\"authorization:\","
"\"http_auth_preamble\":" "\"Bearer \"," "\"http_auth_preamble\":" "\"Bearer \","
"\"use_auth\":" "\"lwa\","
"\"nailed_up\":" "true," "\"nailed_up\":" "true,"
"\"long_poll\":" "true," "\"long_poll\":" "true,"
"\"retry\":" "\"default\"," "\"retry\":" "\"default\","
"\"plugins\":" "[],"
"\"tls\":" "true," "\"tls\":" "true,"
"\"tls_trust_store\":" "\"avs_via_starfield\"" "\"tls_trust_store\":" "\"avs_via_starfield\""
"}}," "}},"
@ -191,6 +197,7 @@ static const char * const default_ss_policy =
"\"http_url\":" "\"v20160207/events\"," "\"http_url\":" "\"v20160207/events\","
"\"http_no_content_length\":" "true," "\"http_no_content_length\":" "true,"
"\"h2q_oflow_txcr\":" "true," "\"h2q_oflow_txcr\":" "true,"
"\"use_auth\":" "\"lwa\","
"\"http_auth_header\":" "\"authorization:\"," "\"http_auth_header\":" "\"authorization:\","
"\"http_auth_preamble\":" "\"Bearer \"," "\"http_auth_preamble\":" "\"Bearer \","
"\"http_multipart_name\":" "\"metadata\"," "\"http_multipart_name\":" "\"metadata\","
@ -200,7 +207,6 @@ static const char * const default_ss_policy =
#endif #endif
"\"rideshare\":" "\"avs_audio\"," "\"rideshare\":" "\"avs_audio\","
"\"retry\":" "\"default\"," "\"retry\":" "\"default\","
"\"plugins\":" "[],"
"\"tls\":" "true," "\"tls\":" "true,"
"\"tls_trust_store\":" "\"avs_via_starfield\"" "\"tls_trust_store\":" "\"avs_via_starfield\""
"}}," "}},"
@ -211,12 +217,12 @@ static const char * const default_ss_policy =
"\"http_method\":" "\"POST\"," "\"http_method\":" "\"POST\","
"\"http_url\":" "\"v20160207/events\"," "\"http_url\":" "\"v20160207/events\","
"\"http_no_content_length\":" "true," "\"http_no_content_length\":" "true,"
"\"plugins\":" "[],"
"\"tls\":" "true," "\"tls\":" "true,"
"\"h2q_oflow_txcr\":" "true," "\"h2q_oflow_txcr\":" "true,"
#if 1 #if 1
"\"http_multipart_ss_in\":" "true," "\"http_multipart_ss_in\":" "true,"
#endif #endif
"\"use_auth\":" "\"lwa\","
"\"http_auth_header\":" "\"authorization:\"," "\"http_auth_header\":" "\"authorization:\","
"\"http_auth_preamble\":" "\"Bearer \"," "\"http_auth_preamble\":" "\"Bearer \","
"\"http_multipart_name\":" "\"audio\"," "\"http_multipart_name\":" "\"audio\","
@ -345,6 +351,8 @@ int main(int argc, const char **argv)
nl.notify_cb = app_system_state_nf; nl.notify_cb = app_system_state_nf;
info.register_notifier_list = app_notifier_list; info.register_notifier_list = app_notifier_list;
puts(default_ss_policy);
context = lws_create_context(&info); context = lws_create_context(&info);
if (!context) { if (!context) {
lwsl_err("lws init failed\n"); lwsl_err("lws init failed\n");

View file

@ -74,6 +74,7 @@ int main(int argc, const char **argv)
struct lws_context_creation_info info; struct lws_context_creation_info info;
size_t json_size = 0, est = 0; size_t json_size = 0, est = 0;
struct lws_context *context; struct lws_context *context;
const lws_ss_auth_t *auth;
char prev[128], curr[128]; char prev[128], curr[128];
int unique_rbo = 0, m, n; int unique_rbo = 0, m, n;
char buf[64], buf1[64]; char buf[64], buf1[64];
@ -356,6 +357,40 @@ int main(int argc, const char **argv)
pol = pol->next; pol = pol->next;
} }
/*
* The auth map
*/
auth = lws_ss_auth_get(context);
if (auth)
printf("\nstatic const lws_ss_auth_t ");
prev[0] = '\0';
while (auth) {
lws_snprintf(curr, sizeof(curr), "_ssau_%s",
purify_csymbol(auth->name, buf, sizeof(buf)));
printf("%s = {\n", curr);
if (prev[0])
printf("\t.next = (void *)&%s,\n", prev);
printf("\t.name = \"%s\",\n", auth->name);
printf("\t.streamtype = \"%s\",\n", auth->streamtype);
printf("\t.blob = %d,\n", auth->blob_index);
printf("}");
if (auth->next)
printf(",");
else
printf(";");
printf("\n");
lws_strncpy(prev, curr, sizeof(prev));
auth = auth->next;
}
if (lws_ss_auth_get(context))
printf("\n");
/* /*
@ -392,6 +427,10 @@ int main(int argc, const char **argv)
printf("\t.socks5_proxy = \"%s\",\n", printf("\t.socks5_proxy = \"%s\",\n",
pol->socks5_proxy); pol->socks5_proxy);
if (pol->auth)
printf("\t.auth = &_ssau_%s,\n",
purify_csymbol(pol->auth->name, buf, sizeof(buf)));
{ {
lws_ss_metadata_t *nv = pol->metadata, *last = NULL; lws_ss_metadata_t *nv = pol->metadata, *last = NULL;