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 */
} 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
@ -188,6 +201,7 @@ typedef struct lws_ss_policy {
const char *payload_fmt;
const char *socks5_proxy;
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 */
@ -308,10 +322,14 @@ LWS_VISIBLE LWS_EXTERN int
lws_ss_policy_overlay(struct lws_context *context, const char *overlay);
/*
* You almost certainly don't want this, it returns the first policy object
* in a linked-list of objects created by lws_ss_policy_parse above
* You almost certainly don't want these, they return the first policy or auth
* 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_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

View file

@ -497,6 +497,7 @@ struct lws_context {
void *pol_args;
#endif
const lws_ss_policy_t *pss_policies;
const lws_ss_auth_t *pss_auths;
#if defined(LWS_WITH_SSPLUGINS)
const lws_ss_plugin_t **pss_plugins;
#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"
### `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`
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
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 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_retain",
"s[].*.swake_validity",
"s[].*.use_auth",
"s[].*",
"auth[].name",
"auth[].streamtype",
"auth[].blob",
"auth[]",
};
typedef enum {
@ -169,7 +174,12 @@ typedef enum {
LSSPPT_MQTT_WILL_QOS,
LSSPPT_MQTT_WILL_RETAIN,
LSSPPT_SWAKE_VALIDITY,
LSSPPT_USE_AUTH,
LSSPPT_STREAMTYPES,
LSSPPT_AUTH_NAME,
LSSPPT_AUTH_STREAMTYPE,
LSSPPT_AUTH_BLOB,
LSSPPT_AUTH,
} policy_token_t;
@ -182,9 +192,10 @@ static uint8_t sizes[] = {
sizeof(lws_ss_x509_t),
sizeof(lws_ss_trust_store_t),
sizeof(lws_ss_policy_t),
sizeof(lws_ss_auth_t),
};
static const char *protonames[] = {
static const char * const protonames[] = {
"h1", /* LWSSSP_H1 */
"h2", /* LWSSSP_H2 */
"ws", /* LWSSSP_WS */
@ -192,6 +203,24 @@ static const char *protonames[] = {
"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
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;
int n = -1;
lwsl_debug("%s: %d %d %s\n", __func__, reason, ctx->path_match - 1,
ctx->path);
// lwsl_debug("%s: %d %d %s\n", __func__, reason, ctx->path_match - 1,
// ctx->path);
switch (ctx->path_match - 1) {
case LSSPPT_RETRY:
@ -227,6 +256,9 @@ lws_ss_policy_parser_cb(struct lejp_ctx *ctx, char reason)
case LSSPPT_STREAMTYPES:
n = LTY_POLICY;
break;
case LSSPPT_AUTH:
n = LTY_AUTH;
break;
}
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))
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 &&
ctx->path_match - 1 == LSSPPT_TRUST_STORES_STACK && !a->count) {
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;
}
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;
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;
break;
case LSSPPT_AUTH_BLOB:
a->curr[LTY_AUTH].a->blob_index = atoi(ctx->buf);
break;
case LSSPPT_HTTP_EXPECT:
a->curr[LTY_POLICY].p->u.http.resp_expect = atoi(ctx->buf);
break;
@ -624,6 +672,16 @@ lws_ss_policy_parser_cb(struct lejp_ctx *ctx, char reason)
case LSSPPT_METADATA:
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:
pmd = a->curr[LTY_POLICY].p->metadata;
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;
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:
a->curr[LTY_POLICY].p->u.http.fail_redirect =
reason == LEJPCB_VAL_TRUE;
@ -894,3 +960,14 @@ lws_ss_policy_get(struct lws_context *context)
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

@ -296,10 +296,11 @@ typedef struct backoffs {
} backoff_t;
union u {
backoff_t *b;
lws_ss_x509_t *x;
lws_ss_trust_store_t *t;
lws_ss_policy_t *p;
backoff_t *b;
lws_ss_x509_t *x;
lws_ss_trust_store_t *t;
lws_ss_policy_t *p;
lws_ss_auth_t *a;
};
enum {
@ -307,6 +308,7 @@ enum {
LTY_X509,
LTY_TRUSTSTORE,
LTY_POLICY,
LTY_AUTH,
_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 */
"{\"api_amazon_com_auth\": {"
"{\"api_amazon_com_lwa\": {"
"\"endpoint\":" "\"api.amazon.com\","
"\"port\":" "443,"
"\"protocol\":" "\"h1\","
"\"http_method\":" "\"POST\","
"\"http_url\":" "\"auth/o2/token\","
"\"plugins\":" "[],"
"\"opportunistic\":" "true,"
"\"tls\":" "true,"
"\"h2q_oflow_txcr\":" "true,"
@ -200,6 +206,7 @@ static const char * const default_ss_policy =
"\"protocol\":" "\"h2\","
"\"http_method\":" "\"GET\","
"\"http_url\":" "\"v20160207/directives\","
"\"use_auth\":" "\"lwa\","
"\"h2q_oflow_txcr\":" "true,"
"\"http_auth_header\":" "\"authorization:\","
"\"http_auth_preamble\":" "\"Bearer \","
@ -207,7 +214,6 @@ static const char * const default_ss_policy =
"\"nailed_up\":" "true,"
"\"long_poll\":" "true,"
"\"retry\":" "\"default\","
"\"plugins\":" "[],"
"\"tls\":" "true,"
"\"tls_trust_store\":" "\"avs_via_starfield\""
"}},"
@ -223,6 +229,7 @@ static const char * const default_ss_policy =
"\"protocol\":" "\"h2\","
"\"http_method\":" "\"POST\","
"\"http_url\":" "\"v20160207/events\","
"\"use_auth\":" "\"lwa\","
"\"opportunistic\":" "true,"
"\"h2q_oflow_txcr\":" "true,"
"\"http_auth_header\":" "\"authorization:\","
@ -233,7 +240,6 @@ static const char * const default_ss_policy =
"\"http_multipart_ss_in\":" "true,"
"\"rideshare\":" "\"avs_audio\","
"\"retry\":" "\"default\","
"\"plugins\":" "[],"
"\"tls\":" "true,"
"\"tls_trust_store\":" "\"avs_via_starfield\""
"}},"
@ -243,7 +249,7 @@ static const char * const default_ss_policy =
"\"protocol\":" "\"h2\","
"\"http_method\":" "\"POST\","
"\"http_url\":" "\"v20160207/events\","
"\"plugins\":" "[],"
"\"use_auth\":" "\"lwa\","
"\"tls\":" "true,"
"\"h2q_oflow_txcr\":" "true,"
"\"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 */
"{\"api_amazon_com_auth\": {"
"{\"api_amazon_com_lwa\": {"
"\"endpoint\":" "\"api.amazon.com\","
"\"port\":" "443,"
"\"protocol\":" "\"h1\","
"\"http_method\":" "\"POST\","
"\"http_url\":" "\"auth/o2/token\","
"\"plugins\":" "[],"
"\"opportunistic\":" "true,"
"\"tls\":" "true,"
"\"h2q_oflow_txcr\":" "true,"
@ -176,10 +182,10 @@ static const char * const default_ss_policy =
"\"h2q_oflow_txcr\":" "true,"
"\"http_auth_header\":" "\"authorization:\","
"\"http_auth_preamble\":" "\"Bearer \","
"\"use_auth\":" "\"lwa\","
"\"nailed_up\":" "true,"
"\"long_poll\":" "true,"
"\"retry\":" "\"default\","
"\"plugins\":" "[],"
"\"tls\":" "true,"
"\"tls_trust_store\":" "\"avs_via_starfield\""
"}},"
@ -191,6 +197,7 @@ static const char * const default_ss_policy =
"\"http_url\":" "\"v20160207/events\","
"\"http_no_content_length\":" "true,"
"\"h2q_oflow_txcr\":" "true,"
"\"use_auth\":" "\"lwa\","
"\"http_auth_header\":" "\"authorization:\","
"\"http_auth_preamble\":" "\"Bearer \","
"\"http_multipart_name\":" "\"metadata\","
@ -200,7 +207,6 @@ static const char * const default_ss_policy =
#endif
"\"rideshare\":" "\"avs_audio\","
"\"retry\":" "\"default\","
"\"plugins\":" "[],"
"\"tls\":" "true,"
"\"tls_trust_store\":" "\"avs_via_starfield\""
"}},"
@ -211,12 +217,12 @@ static const char * const default_ss_policy =
"\"http_method\":" "\"POST\","
"\"http_url\":" "\"v20160207/events\","
"\"http_no_content_length\":" "true,"
"\"plugins\":" "[],"
"\"tls\":" "true,"
"\"h2q_oflow_txcr\":" "true,"
#if 1
"\"http_multipart_ss_in\":" "true,"
#endif
"\"use_auth\":" "\"lwa\","
"\"http_auth_header\":" "\"authorization:\","
"\"http_auth_preamble\":" "\"Bearer \","
"\"http_multipart_name\":" "\"audio\","
@ -345,6 +351,8 @@ int main(int argc, const char **argv)
nl.notify_cb = app_system_state_nf;
info.register_notifier_list = app_notifier_list;
puts(default_ss_policy);
context = lws_create_context(&info);
if (!context) {
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;
size_t json_size = 0, est = 0;
struct lws_context *context;
const lws_ss_auth_t *auth;
char prev[128], curr[128];
int unique_rbo = 0, m, n;
char buf[64], buf1[64];
@ -356,6 +357,40 @@ int main(int argc, const char **argv)
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",
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;