Skip to content

Commit

Permalink
Fix escaping of URI strings passed to %{rest:}
Browse files Browse the repository at this point in the history
  • Loading branch information
arr2036 committed Mar 24, 2014
1 parent 9a84859 commit d4a1e05
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 16 deletions.
76 changes: 66 additions & 10 deletions src/modules/rlm_rest/rest.c
Expand Up @@ -2104,7 +2104,7 @@ int rest_response_decode(rlm_rest_t *instance, UNUSED rlm_rest_section_t *sectio
* @param[in] section configuration data.
* @param[in] handle to cleanup.
*/
void rest_request_cleanup(UNUSED rlm_rest_t *instance, UNUSED rlm_rest_section_t *section,void *handle)
void rest_request_cleanup(UNUSED rlm_rest_t *instance, UNUSED rlm_rest_section_t *section, void *handle)
{
rlm_rest_handle_t *randle = handle;
rlm_rest_curl_context_t *ctx = randle->ctx;
Expand Down Expand Up @@ -2145,7 +2145,7 @@ void rest_request_cleanup(UNUSED rlm_rest_t *instance, UNUSED rlm_rest_section_t
* @param[in] arg pointer, gives context for escaping.
* @return length of data written to out (excluding NULL).
*/
static size_t rest_uri_escape(UNUSED REQUEST *request, char *out, size_t outlen, char const *raw, UNUSED void *arg)
size_t rest_uri_escape(UNUSED REQUEST *request, char *out, size_t outlen, char const *raw, UNUSED void *arg)
{
char *escaped;

Expand All @@ -2171,13 +2171,13 @@ static size_t rest_uri_escape(UNUSED REQUEST *request, char *out, size_t outlen,
*/
ssize_t rest_uri_build(char **out, UNUSED rlm_rest_t *instance, REQUEST *request, char const *uri)
{
char const *p;
char *path_exp = NULL;
char const *p;
char *path_exp = NULL;

char *scheme;
char const *path;
char *scheme;
char const *path;

ssize_t len, outlen;
ssize_t len;

p = uri;

Expand Down Expand Up @@ -2212,7 +2212,6 @@ ssize_t rest_uri_build(char **out, UNUSED rlm_rest_t *instance, REQUEST *request

return 0;
}
outlen = len;

len = radius_axlat(&path_exp, request, path, rest_uri_escape, NULL);
if (len < 0) {
Expand All @@ -2221,8 +2220,65 @@ ssize_t rest_uri_build(char **out, UNUSED rlm_rest_t *instance, REQUEST *request
return 0;
}

*out = talloc_strdup_append(*out, path_exp);
MEM(*out = talloc_strdup_append(*out, path_exp));
talloc_free(path_exp);

return outlen += len;
return talloc_array_length(*out) - 1; /* array_length includes \0 */
}

/** Unescapes the host portion of a URI string
*
* This is required because the xlat functions which operate on the input string
* cannot distinguish between host and path components.
*
* @param[out] out Where to write the pointer to the new buffer containing the escaped URI.
* @param[in] instance configuration data.
* @param[in] uri configuration data.
* @param[in] request Current request
* @return length of data written to buffer (excluding NULL) or < 0 if an error
* occurred.
*/
ssize_t rest_uri_host_unescape(char **out, UNUSED rlm_rest_t *instance, REQUEST *request,
void *handle, char const *uri)
{
rlm_rest_handle_t *randle = handle;
CURL *candle = randle->handle;

char const *p;

char *scheme;

ssize_t len;

p = uri;

/*
* All URLs must contain at least <scheme>://<server>/
*/
p = strchr(p, ':');
if (!p || (*++p != '/') || (*++p != '/')) {
malformed:
REDEBUG("Error URI is malformed, can't find start of path");
return -1;
}
p = strchr(p + 1, '/');
if (!p) {
goto malformed;
}

len = (p - uri);

/*
* Unescape any special sequences in the first part of the URI
*/
scheme = curl_easy_unescape(candle, uri, len, NULL);
if (!scheme) {
REDEBUG("Error unescaping host");
return -1;
}

MEM(*out = talloc_asprintf(request, "%s%s", scheme, p));
curl_free(scheme);

return talloc_array_length(*out) - 1; /* array_length includes \0 */
}
3 changes: 3 additions & 0 deletions src/modules/rlm_rest/rest.h
Expand Up @@ -264,4 +264,7 @@ size_t rest_get_handle_data(char const **out, rlm_rest_handle_t *handle);
/*
* Helper functions
*/
size_t rest_uri_escape(UNUSED REQUEST *request, char *out, size_t outlen, char const *raw, UNUSED void *arg);
ssize_t rest_uri_build(char **out, rlm_rest_t *instance, REQUEST *request, char const *uri);
ssize_t rest_uri_host_unescape(char **out, UNUSED rlm_rest_t *instance, REQUEST *request,
void *handle, char const *uri);
15 changes: 9 additions & 6 deletions src/modules/rlm_rest/rlm_rest.c
Expand Up @@ -161,18 +161,21 @@ static ssize_t rest_xlat(void *instance, REQUEST *request,

RDEBUG("Expanding URI components");

handle = fr_connection_get(inst->conn_pool);
if (!handle) return -1;

/*
* Build xlat'd URI, this allows REST servers to be specified by
* request attributes.
*/
len = rest_uri_build(&uri, instance, request, fmt);
if (len <= 0) return -1;
len = rest_uri_host_unescape(&uri, instance, request, handle, fmt);
if (len <= 0) {
outlen = -1;
goto end;
}

RDEBUG("Sending HTTP %s to \"%s\"", fr_int2str(http_method_table, section.method, NULL), uri);

handle = fr_connection_get(inst->conn_pool);
if (!handle) return -1;

/*
* Configure various CURL options, and initialise the read/write
* context data.
Expand Down Expand Up @@ -539,7 +542,7 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance)
/*
* Register the rest xlat function
*/
xlat_register(inst->xlat_name, rest_xlat, NULL, inst);
xlat_register(inst->xlat_name, rest_xlat, rest_uri_escape, inst);

/*
* Parse sub-section configs.
Expand Down

0 comments on commit d4a1e05

Please sign in to comment.