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

lws_system: auth token handling using buflist

This commit is contained in:
Andy Green 2019-10-10 11:14:38 +01:00
parent f9e9977534
commit 300e22c815
4 changed files with 82 additions and 19 deletions

View file

@ -81,16 +81,25 @@ typedef enum { /* keep system_state_names[] in sync in context.c */
* LWS_SYSTATE_POLICY_VALID */
} lws_system_states_t;
typedef enum {
LWSSYS_AUTH_GET,
LWSSYS_AUTH_TOTAL_LENGTH,
LWSSYS_AUTH_APPEND,
LWSSYS_AUTH_FREE,
} lws_system_auth_op_t;
typedef int (*lws_system_auth_cb_t)(struct lws_context *context, int idx,
size_t ofs, uint8_t *buf, size_t *plen,
lws_system_auth_op_t set);
typedef struct lws_system_ops {
int (*get_info)(lws_system_item_t i, lws_system_arg_t *arg);
int (*reboot)(void);
int (*set_clock)(lws_usec_t us);
int (*auth)(int idx, uint8_t *buf, size_t *plen, int set);
/**< Systemwide ephemeral auth tokens get or set... set *plen to max
* size for get, will be set to actual size on return of 0, return 1
* means token is too big for buffer. idx is token index if multiple.
* Auth tokens are potentially large, and should be stored as binary
* and converted to a transport format like hex. */
lws_system_auth_cb_t auth;
/**< Systemwide auth token management. For set, content may be appended
* incrementally safely. For get, content may be read out in arbitrary
* fragments using \p ofs. */
} lws_system_ops_t;
/**
@ -136,6 +145,7 @@ lws_system_get_info(struct lws_context *context, lws_system_item_t item,
*
* \param context: the lws_context
* \param idx: which auth token
* \param ofs: offset in source to copy from
* \param buf: where to store result, or NULL
* \param buflen: size of buf
* \param flags: how to write the result
@ -148,8 +158,8 @@ lws_system_get_info(struct lws_context *context, lws_system_item_t item,
* writing anything. *buflen is still set to the size of the auth token.
*/
LWS_EXTERN LWS_VISIBLE int
lws_system_get_auth(struct lws_context *context, int idx, uint8_t *buf,
size_t buflen, int flags);
lws_system_get_auth(struct lws_context *context, int idx, size_t ofs,
uint8_t *buf, size_t buflen, int flags);
/**
* lws_system_get_ops() - get ahold of the system ops struct from the context

View file

@ -309,6 +309,8 @@ struct lws_context {
lws_async_dns_t async_dns;
#endif
struct lws_buflist *auth_token[2];
#if defined(LWS_WITH_NETWORK)
lws_state_manager_t mgr_system;
lws_state_notify_link_t protocols_notify;

View file

@ -2310,7 +2310,7 @@ lws_h2_client_handshake(struct lws *wsi)
strcpy((char *)q, "bearer ");
n = lws_system_get_auth(wsi->context, 0, q + 7,
n = lws_system_get_auth(wsi->context, 0, 0, q + 7,
lws_ptr_diff(qend, q + 7),
wsi->flags & LCCSCF_H2_HEXIFY_AUTH_TOKEN ?
LWSSYSGAUTH_HEX : 0);

View file

@ -24,7 +24,9 @@
#include <private-lib-core.h>
#if defined(LWS_WITH_NETWORK)
static const char *hex = "0123456789ABCDEF";
#endif
int
lws_system_get_info(struct lws_context *context, lws_system_item_t item,
@ -42,20 +44,68 @@ lws_system_get_ops(struct lws_context *context)
return context->system_ops;
}
#if defined(LWS_WITH_NETWORK)
int
lws_system_get_auth(struct lws_context *context, int idx, uint8_t *buf,
size_t buflen, int flags)
lws_system_auth_default_cb(struct lws_context *context, int idx, size_t ofs,
uint8_t *buf, size_t *plen, lws_system_auth_op_t op)
{
int n;
if (idx >= (int)LWS_ARRAY_SIZE(context->auth_token))
return -1;
switch (op) {
case LWSSYS_AUTH_GET:
if (!context->auth_token[idx])
return -1;
if (!buf) /* we just need to tell him that it exists */
return -2;
n = lws_buflist_linear_copy(&context->auth_token[idx], ofs, buf,
*plen);
if (n < 0)
return -2;
*plen = (size_t)n;
return 0;
case LWSSYS_AUTH_TOTAL_LENGTH:
*plen = lws_buflist_total_len(&context->auth_token[idx]);
return 0;
case LWSSYS_AUTH_APPEND:
if (lws_buflist_append_segment(&context->auth_token[idx], buf,
*plen) < 0)
return -1;
return 0;
case LWSSYS_AUTH_FREE:
lws_buflist_destroy_all_segments(&context->auth_token[idx]);
return 0;
default:
break;
}
return -1;
}
int
lws_system_get_auth(struct lws_context *context, int idx, size_t ofs,
uint8_t *buf, size_t buflen, int flags)
{
size_t bl = buflen;
uint8_t *p, b;
int n;
if (!context->system_ops || !context->system_ops->auth) {
lwsl_err("%s: add auth system op\n", __func__);
return -1;
}
if (context->system_ops->auth(idx, buf, &buflen, 0) < 0) {
if (!context->system_ops || !context->system_ops->auth)
n = lws_system_auth_default_cb(context, idx, ofs, buf, &buflen, 0);
else
n = context->system_ops->auth(context, idx, ofs, buf, &buflen, 0);
if (n < 0) {
if (buf)
lwsl_err("%s: auth get failed\n", __func__);
return -1;
@ -63,7 +113,8 @@ lws_system_get_auth(struct lws_context *context, int idx, uint8_t *buf,
if (buf && (flags & LWSSYSGAUTH_HEX)) {
if (bl < (buflen * 2) + 1) {
lwsl_err("%s: auth in hex oversize %d\n", __func__, (int)bl);
lwsl_err("%s: auth in hex oversize %d\n", __func__,
(int)bl);
return -1;
}
@ -84,4 +135,4 @@ lws_system_get_auth(struct lws_context *context, int idx, uint8_t *buf,
return (int)buflen;
}
#endif