diff --git a/CMakeLists.txt b/CMakeLists.txt index 77d8de81c..6c26feb2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -997,6 +997,7 @@ set(SOURCES lib/core/lws_dll2.c lib/core/libwebsockets.c lib/core/logs.c + lib/system/system.c lib/misc/base64-decode.c lib/misc/lws-ring.c ) diff --git a/READMEs/README.lws_system.md b/READMEs/README.lws_system.md index a3b2769d3..44890524d 100644 --- a/READMEs/README.lws_system.md +++ b/READMEs/README.lws_system.md @@ -15,6 +15,7 @@ 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); } lws_system_ops_t; ``` @@ -38,6 +39,11 @@ Reboots the device Set the system clock to us-resolution Unix time in seconds +### `auth` + +Get and set generic binary auth blobs so the rest of lws can access them +independently. + ## System state and notifiers Lws implements a state in the context that reflects the readiness of the system diff --git a/include/libwebsockets/lws-system.h b/include/libwebsockets/lws-system.h index 14ec62bb4..0c4ad74a8 100644 --- a/include/libwebsockets/lws-system.h +++ b/include/libwebsockets/lws-system.h @@ -85,6 +85,12 @@ 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_ops_t; /** @@ -123,6 +129,24 @@ lws_system_get_info(struct lws_context *context, lws_system_item_t item, lws_system_arg_t *arg); +#define LWSSYSGAUTH_HEX (1 << 0) + +/** + * lws_system_get_auth() - retreive system auth token helper + * + * \param context: the lws_context + * \param idx: which auth token + * \param buf: where to store result + * \param buflen: size of buf + * \param flags: how to write the result + * + * Attempts to fill buf with the requested system auth token. If flags has + * LWSSYSGAUTH_HEX set, then the auth token is written as pairs of hex chars + * for each byte. If not set, written as 1 byte per byte binary. + */ +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_ops() - get ahold of the system ops struct from the context * diff --git a/lib/core/libwebsockets.c b/lib/core/libwebsockets.c index 79c55b8f9..cafde9e27 100644 --- a/lib/core/libwebsockets.c +++ b/lib/core/libwebsockets.c @@ -1077,18 +1077,4 @@ lws_humanize(char *p, int len, uint64_t v, const lws_humanize_unit_t *schema) return 0; } -int -lws_system_get_info(struct lws_context *context, lws_system_item_t item, - lws_system_arg_t *arg) -{ - if (!context->system_ops || !context->system_ops->get_info) - return 1; - return context->system_ops->get_info(item, arg); -} - -const lws_system_ops_t * -lws_system_get_ops(struct lws_context *context) -{ - return context->system_ops; -} diff --git a/lib/system/system.c b/lib/system/system.c new file mode 100644 index 000000000..920ca4511 --- /dev/null +++ b/lib/system/system.c @@ -0,0 +1,85 @@ +/* + * libwebsockets - small server side websockets and web server implementation + * + * Copyright (C) 2010 - 2019 Andy Green + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include + +static const char *hex = "0123456789ABCDEF"; + +int +lws_system_get_info(struct lws_context *context, lws_system_item_t item, + lws_system_arg_t *arg) +{ + if (!context->system_ops || !context->system_ops->get_info) + return 1; + + return context->system_ops->get_info(item, arg); +} + +const lws_system_ops_t * +lws_system_get_ops(struct lws_context *context) +{ + return context->system_ops; +} + +int +lws_system_get_auth(struct lws_context *context, int idx, 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)) { + lwsl_err("%s: auth get failed\n", __func__); + return -1; + } + + if (flags & LWSSYSGAUTH_HEX) { + if (bl < (buflen * 2) + 1) { + lwsl_err("%s: auth in hex oversize\n", __func__); + return -1; + } + + /* convert to ascii hex inplace, backwards */ + + p = buf + (buflen * 2); + *p = '\0'; /* terminating NUL */ + + for (n = (int)buflen - 1; n >= 0; n--) { + p -= 2; + b = buf[n]; + p[0] = hex[(b >> 4) & 0xf]; + p[1] = hex[b & 0xf]; + } + + buflen = (buflen * 2); + } + + return (int)buflen; +} +