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

ss: add set_metadata that takes a heap copy and make ss-h1 use it

Until now we set metadata value pointers into the onward wsi ah data
area... that's OK until we get a situation the wsi has gone away before we
have a chance to deliver the metadata over the proxy link.

Add a variant lws_ss_alloc_set_metadata() that allocates space on the heap
and takes a copy of the input metadata.  Change ss-h1 to alloc copies of
its metadata so we no longer race the wsi ah lifetime.
This commit is contained in:
Andy Green 2021-03-14 10:44:41 +00:00
parent 4804624905
commit 546c151555
5 changed files with 92 additions and 30 deletions

View file

@ -629,6 +629,22 @@ LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_ss_set_metadata(struct lws_ss_handle *h, const char *name,
const void *value, size_t len);
/**
* lws_ss_alloc_set_metadata() - copy data and bind to ss metadata
*
* \param h: secure streams handle
* \param name: metadata name from the policy
* \param value: pointer to user-managed data to bind to name
* \param len: length of the user-managed data in value
*
* Same as lws_ss_set_metadata(), but allocates a heap buffer for the data
* first and takes a copy of it, so the original can go out of scope
* immediately after.
*/
LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT
lws_ss_alloc_set_metadata(struct lws_ss_handle *h, const char *name,
const void *value, size_t len);
/**
* lws_ss_get_metadata() - get current value of stream metadata item
*

View file

@ -93,6 +93,49 @@ lws_ss_set_metadata(struct lws_ss_handle *h, const char *name,
return _lws_ss_set_metadata(omd, name, value, len);
}
int
_lws_ss_alloc_set_metadata(lws_ss_metadata_t *omd, const char *name,
const void *value, size_t len)
{
uint8_t *p;
int n;
if (omd->value_on_lws_heap) {
lws_free_set_NULL(omd->value__may_own_heap);
omd->value_on_lws_heap = 0;
}
p = lws_malloc(len, __func__);
if (!p)
return 1;
n = _lws_ss_set_metadata(omd, name, p, len);
if (n) {
lws_free(p);
return n;
}
memcpy(p, value, len);
omd->value_on_lws_heap = 1;
return 0;
}
int
lws_ss_alloc_set_metadata(struct lws_ss_handle *h, const char *name,
const void *value, size_t len)
{
lws_ss_metadata_t *omd = lws_ss_get_handle_metadata(h, name);
if (!omd) {
lwsl_info("%s: unknown metadata %s\n", __func__, name);
return 1;
}
return _lws_ss_alloc_set_metadata(omd, name, value, len);
}
int
lws_ss_get_metadata(struct lws_ss_handle *h, const char *name,
const void **value, size_t *len)

View file

@ -468,6 +468,10 @@ int
_lws_ss_set_metadata(lws_ss_metadata_t *omd, const char *name,
const void *value, size_t len);
int
_lws_ss_alloc_set_metadata(lws_ss_metadata_t *omd, const char *name,
const void *value, size_t len);
lws_ss_state_return_t
_lws_ss_client_connect(lws_ss_handle_t *h, int is_retry, void *conn_if_sspc_onw);

View file

@ -303,7 +303,8 @@ lws_extract_metadata(lws_ss_handle_t *h, struct lws *wsi)
* set the related metadata name to it then
*/
_lws_ss_set_metadata(omd, polmd->name, cp, (unsigned int)n);
_lws_ss_alloc_set_metadata(omd, polmd->name, cp,
(unsigned int)n);
#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
/*
@ -363,8 +364,8 @@ lws_extract_metadata(lws_ss_handle_t *h, struct lws *wsi)
omd = lws_ss_get_handle_metadata(h,
polmd->name);
_lws_ss_set_metadata(omd, polmd->name,
p, (size_t)n);
_lws_ss_set_metadata(omd,
polmd->name, p, (size_t)n);
omd->value_on_lws_heap = 1;
#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
@ -962,12 +963,12 @@ malformed:
#if defined(LWS_ROLE_H2)
m = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_METHOD);
if (m) {
if (lws_ss_set_metadata(h, "method",
if (lws_ss_alloc_set_metadata(h, "method",
lws_hdr_simple_ptr(wsi,
WSI_TOKEN_HTTP_COLON_METHOD), (unsigned int)m))
return -1;
m = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH);
if (lws_ss_set_metadata(h, "path",
if (lws_ss_alloc_set_metadata(h, "path",
lws_hdr_simple_ptr(wsi,
WSI_TOKEN_HTTP_COLON_PATH), (unsigned int)m))
return -1;
@ -976,20 +977,20 @@ malformed:
{
m = lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI);
if (m) {
if (lws_ss_set_metadata(h, "path",
if (lws_ss_alloc_set_metadata(h, "path",
lws_hdr_simple_ptr(wsi,
WSI_TOKEN_GET_URI), (unsigned int)m))
return -1;
if (lws_ss_set_metadata(h, "method", "GET", 3))
if (lws_ss_alloc_set_metadata(h, "method", "GET", 3))
return -1;
} else {
m = lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI);
if (m) {
if (lws_ss_set_metadata(h, "path",
if (lws_ss_alloc_set_metadata(h, "path",
lws_hdr_simple_ptr(wsi,
WSI_TOKEN_POST_URI), (unsigned int)m))
return -1;
if (lws_ss_set_metadata(h, "method", "POST", 4))
if (lws_ss_alloc_set_metadata(h, "method", "POST", 4))
return -1;
}
}

View file

@ -146,34 +146,32 @@ ss_s3_state(void *userobj, void *sh, lws_ss_constate_t state,
switch (state) {
case LWSSSCS_CREATING:
lws_ss_set_metadata(m->ss, "s3bucket",
s3bucketName, strlen(s3bucketName));
lws_ss_set_metadata(m->ss, "s3Obj",
s3ObjName, strlen(s3ObjName));
lws_ss_set_metadata(m->ss, "ctype",
"text/plain", strlen("text/plain"));
create_payload(jpl, sizeof(jpl));
m->buf = (uint8_t *)jpl;
m->total = sizeof(jpl);
lws_ss_set_metadata(m->ss, "region",
awsRegion, strlen(awsRegion));
lws_ss_set_metadata(m->ss, "service",
awsService, strlen(awsService));
lws_ss_set_metadata(m->ss, "xacl",
"bucket-owner-full-control",
strlen("bucket-owner-full-control"));
sigv4_sha256hash_payload(m->buf, m->total, payload_hash);
lws_ss_set_metadata(m->ss, "xcsha256",
payload_hash, strlen(payload_hash));
memset(timestamp, 0, sizeof(timestamp));
set_time(timestamp);
lws_ss_set_metadata(m->ss, "xdate",
timestamp, strlen(timestamp));
if (lws_ss_set_metadata(m->ss, "s3bucket",
s3bucketName, strlen(s3bucketName)) ||
lws_ss_set_metadata(m->ss, "s3Obj",
s3ObjName, strlen(s3ObjName)) ||
lws_ss_set_metadata(m->ss, "ctype",
"text/plain", strlen("text/plain")) ||
lws_ss_set_metadata(m->ss, "region",
awsRegion, strlen(awsRegion)) ||
lws_ss_set_metadata(m->ss, "service",
awsService, strlen(awsService)) ||
lws_ss_set_metadata(m->ss, "xacl",
"bucket-owner-full-control",
strlen("bucket-owner-full-control")) ||
lws_ss_set_metadata(m->ss, "xcsha256",
payload_hash, strlen(payload_hash)) ||
lws_ss_set_metadata(m->ss, "xdate",
timestamp, strlen(timestamp)))
return LWSSSSRET_DESTROY_ME;
lws_ss_request_tx_len(m->ss, m->total);
break;