Skip to content

Commit 82aafbe

Browse files
author
Dylan Souza
committed
Strip token from upstream if conifigured and dynamically allocate string buffers
Adds a configuration option to strip uri signing tokens from both the cache key URL and the upstream URL. Additionally it was pointed out that some statically allocated buffers were too small in some of the string manipulating functions (normalize and strip token). These buffers are now dynamically allocated since the maximum buffer size is known for these.
1 parent 0b39c1d commit 82aafbe

File tree

9 files changed

+115
-26
lines changed

9 files changed

+115
-26
lines changed

plugins/experimental/uri_signing/common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
* limitations under the License.
1717
*/
1818

19+
#pragma once
20+
1921
#define PLUGIN_NAME "uri_signing"
2022

2123
#ifdef URI_SIGNING_UNIT_TEST
@@ -24,6 +26,8 @@
2426

2527
#define PluginDebug(fmt, ...) PrintToStdErr("(%s) %s:%d:%s() " fmt "\n", PLUGIN_NAME, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
2628
#define PluginError(fmt, ...) PrintToStdErr("(%s) %s:%d:%s() " fmt "\n", PLUGIN_NAME, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
29+
#define TSmalloc(x) malloc(x)
30+
#define TSfree(p) free(p)
2731
void PrintToStdErr(const char *fmt, ...);
2832

2933
#else

plugins/experimental/uri_signing/config.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
#include "timing.h"
2222
#include "jwt.h"
2323

24-
#include <ts/ts.h>
25-
2624
#include <cjose/cjose.h>
2725
#include <jansson.h>
2826

@@ -45,6 +43,7 @@ struct config {
4543
char **issuer_names;
4644
struct signer signer;
4745
struct auth_directive *auth_directives;
46+
bool strip_token;
4847
};
4948

5049
cjose_jwk_t **
@@ -80,6 +79,12 @@ find_key_by_kid(struct config *cfg, const char *issuer, const char *kid)
8079
return NULL;
8180
}
8281

82+
bool
83+
config_strip_token(struct config *cfg)
84+
{
85+
return cfg->strip_token;
86+
}
87+
8388
struct config *
8489
config_new(size_t n)
8590
{
@@ -106,6 +111,8 @@ config_new(size_t n)
106111

107112
cfg->auth_directives = NULL;
108113

114+
cfg->strip_token = false;
115+
109116
PluginDebug("New config object created at %p", cfg);
110117
return cfg;
111118
}
@@ -259,6 +266,11 @@ read_config(const char *path)
259266
renewal_kid = json_string_value(renewal_kid_json);
260267
}
261268

269+
json_t *strip_json = json_object_get(jwks, "strip_token");
270+
if (strip_json) {
271+
cfg->strip_token = json_boolean_value(strip_json);
272+
}
273+
262274
size_t jwks_ct = json_array_size(key_ary);
263275
cjose_jwk_t **jwks = (*jwkis++ = malloc((jwks_ct + 1) * sizeof *jwks));
264276
PluginDebug("Created table with size %d", cfg->issuers->size);

plugins/experimental/uri_signing/config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ struct signer *config_signer(struct config *);
3333
struct _cjose_jwk_int **find_keys(struct config *cfg, const char *issuer);
3434
struct _cjose_jwk_int *find_key_by_kid(struct config *cfg, const char *issuer, const char *kid);
3535
bool uri_matches_auth_directive(struct config *cfg, const char *uri, size_t uri_ct);
36+
bool config_strip_token(struct config *cfg);

plugins/experimental/uri_signing/cookie.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
#include "cookie.h"
2020
#include "common.h"
21-
#include <ts/ts.h>
2221
#include <string.h>
2322

2423
const char *

plugins/experimental/uri_signing/jwt.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#include "jwt.h"
2121
#include "match.h"
2222
#include "normalize.h"
23-
#include "ts/ts.h"
2423
#include <jansson.h>
2524
#include <cjose/cjose.h>
2625
#include <math.h>
@@ -173,41 +172,49 @@ jwt_check_uri(const char *cdniuc, const char *uri)
173172
int uri_ct = strlen(uri);
174173
int buff_ct = uri_ct + 2;
175174
int err;
176-
char normal_uri[buff_ct];
177-
175+
char *normal_uri = (char *)TSmalloc(buff_ct);
178176
memset(normal_uri, 0, buff_ct);
177+
179178
err = normalize_uri(uri, uri_ct, normal_uri, buff_ct);
180179

181180
if (err) {
182-
return false;
181+
goto fail_jwt;
183182
}
184183

185184
const char *kind = cdniuc, *container = cdniuc;
186185
while (*container && *container != ':') {
187186
++container;
188187
}
189188
if (!*container) {
190-
return false;
189+
goto fail_jwt;
191190
}
192191
++container;
193192

194193
size_t len = container - kind;
194+
bool status;
195195
PluginDebug("Comparing with match kind \"%.*s\" on \"%s\" to normalized URI \"%s\"", (int)len - 1, kind, container, normal_uri);
196196
switch (len) {
197197
case sizeof CONT_URI_HASH_STR:
198198
if (!strncmp(CONT_URI_HASH_STR, kind, len - 1)) {
199-
return match_hash(container, normal_uri);
199+
status = match_hash(container, normal_uri);
200+
TSfree(normal_uri);
201+
return status;
200202
}
201203
PluginDebug("Expected kind %s, but did not find it in \"%.*s\"", CONT_URI_HASH_STR, (int)len - 1, kind);
202204
break;
203205
case sizeof CONT_URI_REGEX_STR:
204206
if (!strncmp(CONT_URI_REGEX_STR, kind, len - 1)) {
205-
return match_regex(container, normal_uri);
207+
status = match_regex(container, normal_uri);
208+
TSfree(normal_uri);
209+
return status;
206210
}
207211
PluginDebug("Expected kind %s, but did not find it in \"%.*s\"", CONT_URI_REGEX_STR, (int)len - 1, kind);
208212
break;
209213
}
210214
PluginDebug("Unknown match kind \"%.*s\"", (int)len - 1, kind);
215+
216+
fail_jwt:
217+
TSfree(normal_uri);
211218
return false;
212219
}
213220

@@ -259,6 +266,7 @@ renew(struct jwt *jwt, const char *iss, cjose_jwk_t *jwk, const char *alg, const
259266
renew_copy_integer(new_json, "cdniv", jwt->cdniv);
260267
renew_copy_integer(new_json, "cdniets", jwt->cdniets);
261268
renew_copy_integer(new_json, "cdnistt", jwt->cdnistt);
269+
renew_copy_integer(new_json, "cdnistd", jwt->cdnistd);
262270

263271
char *pt = json_dumps(new_json, JSON_COMPACT);
264272

plugins/experimental/uri_signing/match.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
#include <regex.h>
2020
#include "common.h"
21-
#include "ts/ts.h"
2221
#include <stdbool.h>
2322
#include <string.h>
2423

plugins/experimental/uri_signing/parse.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include <cjose/cjose.h>
2626
#include <jansson.h>
2727
#include <string.h>
28-
#include <ts/ts.h>
2928
#include <inttypes.h>
3029

3130
cjose_jws_t *

plugins/experimental/uri_signing/unit_tests/uri_signing_test.cc

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,22 @@ normalize_uri_helper(const char *uri, const char *expected_normal)
5757
size_t uri_ct = strlen(uri);
5858
int buff_size = uri_ct + 2;
5959
int err;
60-
char uri_normal[buff_size];
60+
char *uri_normal = (char *)malloc(buff_size);
6161
memset(uri_normal, 0, buff_size);
6262

6363
err = normalize_uri(uri, uri_ct, uri_normal, buff_size);
6464

6565
if (err) {
66+
free(uri_normal);
6667
return false;
6768
}
6869

6970
if (expected_normal && strcmp(expected_normal, uri_normal) == 0) {
71+
free(uri_normal);
7072
return true;
7173
}
7274

75+
free(uri_normal);
7376
return false;
7477
}
7578

@@ -100,8 +103,10 @@ jws_parsing_helper(const char *uri, const char *paramName, const char *expected_
100103
bool resp;
101104
size_t uri_ct = strlen(uri);
102105
size_t strip_ct = 0;
103-
char uri_strip[uri_ct + 1];
104-
memset(uri_strip, 0, sizeof uri_strip);
106+
107+
char *uri_strip = (char *)malloc(uri_ct + 1);
108+
memset(uri_strip, 0, uri_ct + 1);
109+
105110
cjose_jws_t *jws = get_jws_from_uri(uri, uri_ct, paramName, uri_strip, uri_ct, &strip_ct);
106111
if (jws) {
107112
resp = true;
@@ -113,6 +118,7 @@ jws_parsing_helper(const char *uri, const char *paramName, const char *expected_
113118
resp = false;
114119
}
115120
cjose_jws_release(jws);
121+
free(uri_strip);
116122
return resp;
117123
}
118124

plugins/experimental/uri_signing/uri_signing.c

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
#include "jwt.h"
2323
#include "timing.h"
2424

25-
#include <ts/ts.h>
2625
#include <ts/remap.h>
2726

2827
#include <stdio.h>
28+
#include <stdlib.h>
2929
#include <string.h>
3030
#include <inttypes.h>
3131

@@ -157,6 +157,8 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
157157
int cpi = 0;
158158
int url_ct = 0;
159159
const char *url = NULL;
160+
char *strip_uri = NULL;
161+
TSRemapStatus status = TSREMAP_NO_REMAP;
160162

161163
const char *package = "URISigningPackage";
162164

@@ -176,16 +178,22 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
176178
checkpoints[cpi++] = mark_timer(&t);
177179
}
178180

179-
char strip_uri[2000] = {0};
181+
int strip_size = url_ct + 1;
182+
strip_uri = (char *)TSmalloc(strip_size);
183+
memset(strip_uri, 0, strip_size);
184+
180185
size_t strip_ct;
181-
cjose_jws_t *jws = get_jws_from_uri(url, url_ct, package, strip_uri, 2000, &strip_ct);
186+
cjose_jws_t *jws = get_jws_from_uri(url, url_ct, package, strip_uri, strip_size, &strip_ct);
182187

183188
if (cpi < max_cpi) {
184189
checkpoints[cpi++] = mark_timer(&t);
185190
}
186191
int checked_cookies = 0;
187192
if (!jws) {
188193
check_cookies:
194+
/* There is no valid token in the url */
195+
strncpy(strip_uri, url, url_ct);
196+
strip_ct = url_ct;
189197
++checked_cookies;
190198

191199
TSMLoc field;
@@ -218,6 +226,55 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
218226
checkpoints[cpi++] = mark_timer(&t);
219227
}
220228
jws = get_jws_from_cookie(&client_cookie, &client_cookie_sz_ct, package);
229+
} else {
230+
/* There has been a JWS found in the url */
231+
/* Strip the token from the URL for upstream if configured to do so */
232+
if (config_strip_token((struct config *)ih)) {
233+
if ((int)strip_ct != url_ct) {
234+
int map_url_ct = 0;
235+
char *map_url = NULL;
236+
char *map_strip_uri = NULL;
237+
map_url = TSUrlStringGet(rri->requestBufp, rri->requestUrl, &map_url_ct);
238+
239+
PluginDebug("Stripping Token from requestUrl: %s", map_url);
240+
241+
int map_strip_size = map_url_ct + 1;
242+
map_strip_uri = (char *)TSmalloc(map_strip_size);
243+
memset(map_strip_uri, 0, map_strip_size);
244+
size_t map_strip_ct = 0;
245+
246+
cjose_jws_t *map_jws = get_jws_from_uri(map_url, map_url_ct, package, map_strip_uri, map_strip_size, &map_strip_ct);
247+
cjose_jws_release(map_jws);
248+
249+
char *strip_uri_start = &map_strip_uri[0];
250+
char *strip_uri_end = &map_strip_uri[map_strip_ct];
251+
PluginDebug("Stripping token from upstream url to: %s", strip_uri_start);
252+
253+
TSParseResult parse_rc = TSUrlParse(rri->requestBufp, rri->requestUrl, (const char **)&strip_uri_start, strip_uri_end);
254+
if (map_url != NULL) {
255+
TSfree(map_url);
256+
}
257+
if (map_strip_uri != NULL) {
258+
TSfree(map_strip_uri);
259+
}
260+
261+
if (parse_rc != TS_PARSE_DONE) {
262+
PluginDebug("Error in TSUrlParse");
263+
goto fail;
264+
}
265+
status = TSREMAP_DID_REMAP;
266+
}
267+
}
268+
}
269+
/* Check auth_dir and pass through if configured */
270+
if (uri_matches_auth_directive((struct config *)ih, url, url_ct)) {
271+
if (url != NULL) {
272+
TSfree((void *)url);
273+
}
274+
if (strip_uri != NULL) {
275+
TSfree(strip_uri);
276+
}
277+
return TSREMAP_NO_REMAP;
221278
}
222279
if (!jws) {
223280
goto fail;
@@ -226,8 +283,10 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
226283
if (cpi < max_cpi) {
227284
checkpoints[cpi++] = mark_timer(&t);
228285
}
286+
229287
struct jwt *jwt = validate_jws(jws, (struct config *)ih, strip_uri, strip_ct);
230288
cjose_jws_release(jws);
289+
231290
if (cpi < max_cpi) {
232291
checkpoints[cpi++] = mark_timer(&t);
233292
}
@@ -239,6 +298,8 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
239298
}
240299
}
241300

301+
/* There has been a validated JWT found in either the cookie or url */
302+
242303
struct signer *signer = config_signer((struct config *)ih);
243304
char *cookie = renew(jwt, signer->issuer, signer->jwk, signer->alg, package);
244305
jwt_delete(jwt);
@@ -260,23 +321,23 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
260321
last_mark = checkpoints[i];
261322
}
262323
PluginDebug("Spent %" PRId64 " ns uri_signing verification of %.*s.", mark_timer(&t), url_ct, url);
324+
263325
TSfree((void *)url);
264-
return TSREMAP_NO_REMAP;
265-
fail:
266-
if (uri_matches_auth_directive((struct config *)ih, url, url_ct)) {
267-
if (url != NULL) {
268-
TSfree((void *)url);
269-
}
270-
return TSREMAP_NO_REMAP;
326+
if (strip_uri != NULL) {
327+
TSfree(strip_uri);
271328
}
272-
329+
return status;
330+
fail:
273331
PluginDebug("Invalid JWT for %.*s", url_ct, url);
274332
TSHttpTxnStatusSet(txnp, TS_HTTP_STATUS_FORBIDDEN);
275333
PluginDebug("Spent %" PRId64 " ns uri_signing verification of %.*s.", mark_timer(&t), url_ct, url);
276334

277335
if (url != NULL) {
278336
TSfree((void *)url);
279337
}
338+
if (strip_uri != NULL) {
339+
TSfree(strip_uri);
340+
}
280341

281342
return TSREMAP_DID_REMAP;
282343
}

0 commit comments

Comments
 (0)