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:
parent
692f269045
commit
a204886eff
8 changed files with 204 additions and 20 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
@ -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:\","
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue