tools: reimplement xmlURIEscapeStr to respect RFC3986 (#45581)

Bugfix by Emmanuel Dreyfus.

License: MIT
This commit is contained in:
Benjamin Dauvergne 2020-08-11 11:30:51 +02:00
parent 15b8cd7ab1
commit 0b742b1f6d
5 changed files with 64 additions and 11 deletions

View File

@ -21,6 +21,7 @@ Core
contributed under MIT license by XCG consulting
- Simo Sorce <simo@redhat.com>, code review using Coverity and related
bugfixes, contributed under MIT license by Redhat Inc.
- Emmanuel Dreyfus <manu@netbsd.org>, bug fixes, contributed under MIT license.
Unit Tests
==========

View File

@ -988,11 +988,11 @@ lasso_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_method)
}
b64_samlArt = xmlStrdup((xmlChar*)login->assertionArtifact);
relayState = xmlURIEscapeStr(
relayState = lasso_xmlURIEscapeStr(
(xmlChar*)LASSO_LIB_AUTHN_REQUEST(profile->request)->RelayState, NULL);
if (http_method == LASSO_HTTP_METHOD_REDIRECT) {
xmlChar *escaped_artifact = xmlURIEscapeStr(b64_samlArt, NULL);
xmlChar *escaped_artifact = lasso_xmlURIEscapeStr(b64_samlArt, NULL);
gchar *query = NULL;
if (relayState == NULL) {

View File

@ -287,6 +287,7 @@ gboolean lasso_eval_xpath_expression(xmlXPathContextPtr xpath_ctx, const char *e
char * lasso_get_relaystate_from_query(const char *query);
char * lasso_url_add_parameters(char *url, gboolean free, ...);
xmlChar * lasso_xmlURIEscapeStr(const xmlChar *from, const xmlChar *list);
xmlSecKey* lasso_xmlsec_load_private_key_from_buffer(const char *buffer, size_t length, const char *password, LassoSignatureMethod signature_method, const char *certificate);
xmlSecKey* lasso_xmlsec_load_private_key(const char *filename_or_buffer, const char *password,
LassoSignatureMethod signature_method, const char *certificate);

View File

@ -36,6 +36,7 @@
#define _BSD_SOURCE
#include "private.h"
#include <string.h>
#include <strings.h>
#include <time.h>
#include <ctype.h>
#include <stdarg.h>
@ -540,7 +541,7 @@ lasso_query_sign(char *query, LassoSignatureContext context)
}
{
const char *t = (char*)xmlURIEscapeStr(algo_href, NULL);
const char *t = (char*)lasso_xmlURIEscapeStr(algo_href, NULL);
new_query = g_strdup_printf("%s&SigAlg=%s", query, t);
xmlFree(BAD_CAST t);
}
@ -662,7 +663,7 @@ lasso_query_sign(char *query, LassoSignatureContext context)
/* Base64 encode the signature value */
b64_sigret = xmlSecBase64Encode(sigret, sigret_size, 0);
/* escape b64_sigret */
e_b64_sigret = xmlURIEscapeStr((xmlChar*)b64_sigret, NULL);
e_b64_sigret = lasso_xmlURIEscapeStr((xmlChar*)b64_sigret, NULL);
/* add signature */
switch (sign_method) {
@ -1307,7 +1308,7 @@ lasso_xmlnode_build_deflated_query(xmlNode *xmlnode)
b64_ret = xmlSecBase64Encode(ret, stream.total_out, 0);
lasso_release(ret);
ret = xmlURIEscapeStr(b64_ret, NULL);
ret = lasso_xmlURIEscapeStr(b64_ret, NULL);
rret = g_strdup((char*)ret);
xmlFree(b64_ret);
xmlFree(ret);
@ -2329,7 +2330,7 @@ lasso_url_add_parameters(char *url,
if (! key) {
break;
}
encoded_key = xmlURIEscapeStr((xmlChar*)key, NULL);
encoded_key = lasso_xmlURIEscapeStr((xmlChar*)key, NULL);
goto_cleanup_if_fail(encoded_key);
value = va_arg(ap, char*);
@ -2337,7 +2338,7 @@ lasso_url_add_parameters(char *url,
message(G_LOG_LEVEL_CRITICAL, "lasso_url_add_parameter: key without a value !!");
break;
}
encoded_value = xmlURIEscapeStr((xmlChar*)value, NULL);
encoded_value = lasso_xmlURIEscapeStr((xmlChar*)value, NULL);
goto_cleanup_if_fail(encoded_value);
if (old_url) {
@ -2480,6 +2481,56 @@ lasso_base64_decode(const char *from, char **buffer, int *buffer_len)
return TRUE;
}
/**
* lasso_xmlURIEscapeStr:
* @from: the source URI string
* @list: optional list of characters not to escape
*
* Drop-in replacement for libxml2 xmlURIEscapeStr(), but encoding
* everything but [A-Za-z0-9._~-] which are the unreserved chartacters
* for RFC3986 section 2.3
*
* Return value: a buffer containing the URL-encoded string or NULL on error
*/
xmlChar *
lasso_xmlURIEscapeStr(const xmlChar *from, const xmlChar *list)
{
size_t len = 0;
const xmlChar *fp;
xmlChar *result;
int ri;
if (list == NULL)
list = "";
for (fp = from; *fp; fp++) {
if (isalnum(*fp) || index("._~-", *fp) || index(list, *fp))
len++;
else
len += 3;
}
result = g_malloc0(len + 1);
ri = 0;
for (fp = from; *fp; fp++) {
if (isalnum(*fp) || index("._~-", *fp) || index(list, *fp)) {
result[ri++] = *fp;
} else {
int msb = (*fp & 0xf0) >> 4;
int lsb = *fp & 0x0f;
result[ri++] = '%';
result[ri++] = (msb > 9) ? 'A' + msb - 10 : '0' + msb;
result[ri++] = (lsb > 9) ? 'A' + lsb - 10 : '0' + lsb;
}
}
result[ri++] = '\0';
return result;
}
/**
* lasso_xmlsec_load_private_key_from_buffer:
* @buffer: a buffer containing a key in any format

View File

@ -3120,7 +3120,7 @@ get_value_by_path(LassoNode *node, char *path, struct XmlSnippet *xml_snippet)
s = xmlGetProp(t, a->name);
g_string_append(result, a->name);
g_string_append(result, "=");
s2 = xmlURIEscapeStr(s, NULL);
s2 = lasso_xmlURIEscapeStr(s, NULL);
g_string_append(result, s2);
xmlFree(s2);
xmlFree(s);
@ -3140,7 +3140,7 @@ get_value_by_path(LassoNode *node, char *path, struct XmlSnippet *xml_snippet)
g_string_append(result, (char*)c->name);
g_string_append(result, "=");
s = xmlNodeGetContent(c);
s2 = xmlURIEscapeStr(s, NULL);
s2 = lasso_xmlURIEscapeStr(s, NULL);
g_string_append(result, (char*)s2);
xmlFree(s2);
xmlFree(s);
@ -3263,7 +3263,7 @@ lasso_node_build_query_from_snippets(LassoNode *node)
g_string_append(s, "&");
g_string_append(s, field_name);
g_string_append(s, "=");
t = xmlURIEscapeStr((xmlChar*)v, NULL);
t = lasso_xmlURIEscapeStr((xmlChar*)v, NULL);
g_string_append(s, (char*)t);
xmlFree(t);
}
@ -3634,7 +3634,7 @@ lasso_node_export_to_saml2_query(LassoNode *node, const char *param_name, const
value = lasso_node_build_deflated_query(node);
if (! value)
goto cleanup;
encoded_param = xmlURIEscapeStr(BAD_CAST param_name, NULL);
encoded_param = lasso_xmlURIEscapeStr(BAD_CAST param_name, NULL);
if (! encoded_param)
goto cleanup;
query = g_strdup_printf("%s=%s", encoded_param, value);