xml: handle failure of xmlSecBase64Decode() (fixes #8070)

Thanks to fpeters for the patch.
This commit is contained in:
Benjamin Dauvergne 2015-08-24 09:52:41 +02:00
parent 6e8326293d
commit 9854cd50f3
4 changed files with 78 additions and 24 deletions

View File

@ -1363,6 +1363,11 @@ lasso_node_init_from_deflated_query_part(LassoNode *node, char *deflate_string)
zre = xmlMalloc(len*4);
len = xmlSecBase64Decode(b64_zre, zre, len*4);
xmlFree(b64_zre);
if (len == -1) {
message(G_LOG_LEVEL_CRITICAL, "Failed to base64-decode query");
xmlFree(zre);
return FALSE;
}
re = lasso_inflate(zre, len);
xmlFree(zre);

View File

@ -213,6 +213,26 @@ START_TEST(wrong_endpoint_index_in_artifacts)
}
END_TEST
START_TEST(malformed_logout_request)
{
/* Sent by Songling Han on 2015-08-08 */
LassoServer *server = NULL;
LassoLogout *logout = NULL;
char *msg = "SAMLRequest=lZJRS8MwFIX/SsnrSJOmmWlCLQz3UpgKTnzwZaRZugW6pPam6s+3WxFRRPAp5HJPznfuTQn61PVqEw5hjA/2ZbQQk3p9jXb8SgrJucRUXi0xp7nAUi8zXEgjZZ43hSwMSp7sAC74a8RSipIaYLS1h6h9nEo0W2JaYCoeWaZYobhIRbZ8Rsl6cnFex4vyGGMPipBMsJTlac7TQpLFm21ee78g87nrLoDpMZ46lNwED/bsMA5eBQ0OlNcnCyoatV3dbtQEo8zcpEYPvTWudXaPkrsQ7/39sGqjHX4C5vkX4Pup86Aus/nbpR9CDCZ0qCov4YdZ+rdIA9jhHB5V5/BT9jfnJxiGWWocmJB2weiO6H0LZGp9dcYCicMIsSSzTVXeTc/W6//aQfCHzvmSzPKqnPe/tXBeY+339r3aZQ3XVlCOdcZbzDPW4ELsp2tLBWXcSslESX5Rfha/fafqAw==tLBWXcSslESX5Rfha%2ffafqAw%3d%3d&Signature=a3Pm6zoaMTJDv8cDOOa+u1BEBvFuAtUmcqsUIUGkOIkCswlq44VNvAJ1NaHZfk8uf+q1KEfl8CLASjL1Rgjzc6JjzRv0U4qRPeF9U5D07W1G+f9AZWMat6AHAwXoAq42B5fdJJtDhCXjEYQRoWKMzJQzn/6QFezUMbErPz3gzku384+RBTrlTpNYdEoC4j2YOGiTBvlZAUdmDNpCkKeEVUOKZhe7V5u8nqOK2F+WhLlCU8g5EIvoEeIXpmY4rn4h2lRsLKJTKLB2RNJoE3U7lBkUzObHmmt0gfiFxGOuL0vxmfrKt/psvZsRMOsVzmZrUW7BVaCw2j0uB7X9njbDiA==0uB7X9njbDiA%3d%3d&SigAlg=http://www.w3.org/2000/09/xmldsig#rsa-sha1sig%23rsa-sha1";
check_not_null(server = lasso_server_new(TESTSDATADIR "/idp5-saml2/metadata.xml",
TESTSDATADIR "/idp5-saml2/private-key.pem", NULL, NULL));
check_good_rc(lasso_server_add_provider(server, LASSO_PROVIDER_ROLE_SP,
TESTSDATADIR "/sp5-saml2/metadata.xml", NULL, NULL));
check_not_null(logout = lasso_logout_new(server));
block_lasso_logs;
check_equals(lasso_logout_process_request_msg(logout, msg), LASSO_PROFILE_ERROR_INVALID_MSG);
unblock_lasso_logs;
lasso_release_gobject(logout);
lasso_release_gobject(server);
}
END_TEST
struct {
char *name;
void *function;
@ -221,6 +241,7 @@ struct {
{ "Wrong assertionConsumer ordering on 08-10-2010", indexed_endpoints_20101008},
{ "Warning when parsing AttributeValue node containing unknown namespace nodes", remove_warning_when_parssing_unknown_SNIPPET_LIST_NODES_20111007 },
{ "Wrong endpoint index in artifacts", wrong_endpoint_index_in_artifacts },
{ "Malformed logout request", malformed_logout_request },
};
Suite*

View File

@ -26,6 +26,7 @@
#include <check.h>
#include <glib.h>
#include <tests.h>
#include "../lasso/lasso.h"
#include "../lasso/lasso_config.h"
@ -55,7 +56,15 @@ SuiteFunction suites[] = {
#endif
NULL
};
void error_logger(const gchar *log_domain, GLogLevelFlags log_level,
void
mute_logger(G_GNUC_UNUSED const gchar *domain,
G_GNUC_UNUSED GLogLevelFlags log_level, G_GNUC_UNUSED const gchar *message,
G_GNUC_UNUSED gpointer user_data) {
}
void
fail_logger(const gchar *log_domain, GLogLevelFlags log_level,
const gchar *message, G_GNUC_UNUSED gpointer user_data)
{
fail("No logging output expected: message «%s» was emitted for domain «%s» at the level"
@ -77,7 +86,7 @@ main(int argc, char *argv[])
}
lasso_init();
g_log_set_default_handler(error_logger, NULL);
unblock_lasso_logs;
sr = srunner_create(suites[0]());

View File

@ -73,21 +73,24 @@
fail_unless(g_strcmp0(__tmp, to) != 0, "%s:%i: " #what " is equal to %s", __func__, __LINE__, to); \
}
static inline void mute_logger(G_GNUC_UNUSED const gchar *domain,
void mute_logger(G_GNUC_UNUSED const gchar *domain,
G_GNUC_UNUSED GLogLevelFlags log_level, G_GNUC_UNUSED const gchar *message,
G_GNUC_UNUSED gpointer user_data) {
}
G_GNUC_UNUSED static guint mute_log_handler = 0;
G_GNUC_UNUSED gpointer user_data);
#define block_lasso_logs mute_log_handler = g_log_set_handler(LASSO_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \
mute_logger, NULL)
void fail_logger(const gchar *log_domain, GLogLevelFlags log_level,
const gchar *message, G_GNUC_UNUSED gpointer user_data);
#define unblock_lasso_logs g_log_remove_handler(LASSO_LOG_DOMAIN, mute_log_handler)
#define block_lasso_logs g_log_set_default_handler(mute_logger, NULL);
#define unblock_lasso_logs g_log_set_default_handler(fail_logger, NULL);
#define CHECKING_LOG_HANDLER_SIZE 30
struct CheckingLogHandlerUserData {
GLogLevelFlags log_level;
const char *message;
gboolean endswith;
GLogLevelFlags log_levels[CHECKING_LOG_HANDLER_SIZE];
const char *messages[CHECKING_LOG_HANDLER_SIZE];
gboolean endswith[CHECKING_LOG_HANDLER_SIZE];
GLogLevelFlags log_level_found;
char *message_found;
};
@ -108,24 +111,40 @@ static inline void checking_logger(G_GNUC_UNUSED const gchar *domain,
G_GNUC_UNUSED GLogLevelFlags log_level, G_GNUC_UNUSED const gchar *message,
G_GNUC_UNUSED gpointer user_data) {
struct CheckingLogHandlerUserData *ck_user_data = user_data;
if (log_level == ck_user_data->log_level && check_message(message, ck_user_data->message,
ck_user_data->endswith)) {
} else {
g_log_default_handler(domain, log_level, message, user_data);
checking_log_handler_flag = 0;
int i = 0;
for (i = 0; i < CHECKING_LOG_HANDLER_SIZE; i++) {
if (log_level == ck_user_data->log_levels[i] && check_message(message, ck_user_data->messages[i],
ck_user_data->endswith[i])) {
ck_user_data->log_level_found = log_level;
ck_user_data->message_found = g_strdup(message);
return;
}
}
ck_user_data->log_level_found = log_level;
ck_user_data->message_found = g_strdup(message);
g_log_default_handler(domain, log_level, message, user_data);
checking_log_handler_flag = 0;
}
static inline void add_check_log(GLogLevelFlags log_level, const char *message, gboolean endswith) {
int i = 0;
for (i = 0; i < CHECKING_LOG_HANDLER_SIZE-1; i++) {
if (! checking_logger_user_data.messages[i]) {
checking_logger_user_data.log_levels[i] = log_level;
checking_logger_user_data.messages[i] = message;
checking_logger_user_data.endswith[i] = endswith;
return;
}
}
g_assert_not_reached();
}
/* begin_check_do_log(level, message, endswith)/end_check_do_log() with check that the only
* message emitted between the two macros is one equals to message at the level level,
* or ending with message if endswith is True.
*/
static inline void begin_check_do_log(GLogLevelFlags level, const char *message, gboolean endswith) {
memset(&checking_logger_user_data, 0, sizeof(struct CheckingLogHandlerUserData));
checking_logger_user_data.log_level = level;
checking_logger_user_data.message = message;
checking_logger_user_data.endswith = endswith;
add_check_log(level, message, endswith);
checking_log_handler = g_log_set_handler(LASSO_LOG_DOMAIN, level, checking_logger, &checking_logger_user_data);
checking_log_handler_flag = 1;
}
@ -134,8 +153,8 @@ static inline void end_check_do_log() {
g_log_remove_handler(LASSO_LOG_DOMAIN, checking_log_handler);
checking_log_handler = 0;
fail_unless(checking_log_handler_flag, "Logging failure: expected log level %d and message «%s», got %d and «%s»",
checking_logger_user_data.log_level,
checking_logger_user_data.message,
checking_logger_user_data.log_levels[0],
checking_logger_user_data.messages[0],
checking_logger_user_data.log_level_found,
checking_logger_user_data.message_found);
if (checking_logger_user_data.message_found) {