summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-07-12 14:09:17 +0000
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-07-12 14:09:17 +0000
commit9d9cf60aca91d028e929c642121254ae2e8b6ab9 (patch)
treed8ffcea3726ed8c3bc061659232e98387861dfe3
parent98445777b902f5319fba99149a09bf7eab0e0b74 (diff)
downloadlasso-9d9cf60aca91d028e929c642121254ae2e8b6ab9.tar.gz
lasso-9d9cf60aca91d028e929c642121254ae2e8b6ab9.tar.xz
lasso-9d9cf60aca91d028e929c642121254ae2e8b6ab9.zip
[Core] extract signature adding into base class method lasso_node_get_xmlNode
In order to permit subclass to modify the base xmlNode created by lasso_node_impl_get_xmlNode we must defer the concrete to the virtual method wrapper, lasso_node_get_xmlNode. To do that it whas needed to make id_attribute another virtual field of LassoNode subclasses (it can be accessed through an offset registered in the class object). This commit solves signature validation error since the patch for managing more than one SessionIndex element in samlp2:LogoutRequest. It also factorize the creation of signatures in one place.
-rw-r--r--lasso/xml/private.h6
-rw-r--r--lasso/xml/saml-2.0/saml2_assertion.c20
-rw-r--r--lasso/xml/saml-2.0/samlp2_request_abstract.c32
-rw-r--r--lasso/xml/saml-2.0/samlp2_status_response.c31
-rw-r--r--lasso/xml/saml_assertion.c20
-rw-r--r--lasso/xml/samlp_request_abstract.c32
-rw-r--r--lasso/xml/samlp_response_abstract.c32
-rw-r--r--lasso/xml/tools.c29
-rw-r--r--lasso/xml/xml.c31
9 files changed, 78 insertions, 155 deletions
diff --git a/lasso/xml/private.h b/lasso/xml/private.h
index cfaf016d..bcde4cfb 100644
--- a/lasso/xml/private.h
+++ b/lasso/xml/private.h
@@ -88,6 +88,8 @@ struct _LassoNodeClassData
struct QuerySnippet *query_snippets;
char *node_name;
xmlNs *ns;
+ char *id_attribute_name;
+ int id_attribute_offset;
int sign_type_offset;
int sign_method_offset;
int private_key_file_offset;
@@ -191,6 +193,10 @@ void lasso_set_string_from_prop(char **str, xmlNode *node, xmlChar *name, xmlCha
void lasso_node_add_custom_namespace(LassoNode *node, const char *prefix, const char *href);
+void lasso_apply_signature(LassoNode *node, gboolean lasso_dump,
+ xmlNode **xmlnode, char *id_attribute, char *id_value, LassoSignatureType sign_type,
+ char *private_key_file, char *certificate_file);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/lasso/xml/saml-2.0/saml2_assertion.c b/lasso/xml/saml-2.0/saml2_assertion.c
index 5bf46b6f..b3e728f3 100644
--- a/lasso/xml/saml-2.0/saml2_assertion.c
+++ b/lasso/xml/saml-2.0/saml2_assertion.c
@@ -118,9 +118,7 @@ static LassoNodeClass *parent_class = NULL;
static xmlNode*
get_xmlNode(LassoNode *node, gboolean lasso_dump)
{
- LassoSaml2Assertion *assertion = LASSO_SAML2_ASSERTION(node);
xmlNode *xmlnode, *original_xmlnode;
- int rc = 0;
/* If assertion has been deserialized and contain a signature, dump it from the
* original xmlnode. */
@@ -140,22 +138,6 @@ get_xmlNode(LassoNode *node, gboolean lasso_dump)
xmlnode = parent_class->get_xmlNode(node, lasso_dump);
- if (lasso_dump == FALSE && assertion->sign_type) {
- if (assertion->private_key_file == NULL) {
- message(G_LOG_LEVEL_WARNING,
- "No Private Key set for signing saml2:Assertion");
- } else {
- rc = lasso_sign_node(xmlnode, "ID", assertion->ID,
- assertion->private_key_file, assertion->certificate_file);
- if (rc != 0) {
- message(G_LOG_LEVEL_WARNING, "Signing of saml2:Assertion failed: %s", lasso_strerror(rc));
- }
- }
- if (rc != 0) {
- lasso_release_xml_node(xmlnode);
- }
- }
-
return xmlnode;
}
@@ -183,6 +165,8 @@ class_init(LassoSaml2AssertionClass *klass)
lasso_node_class_set_ns(nclass, LASSO_SAML2_ASSERTION_HREF, LASSO_SAML2_ASSERTION_PREFIX);
lasso_node_class_add_snippets(nclass, schema_snippets);
+ nclass->node_data->id_attribute_name = "ID";
+ nclass->node_data->id_attribute_offset = G_STRUCT_OFFSET(LassoSaml2Assertion, ID);
nclass->node_data->sign_type_offset = G_STRUCT_OFFSET(
LassoSaml2Assertion, sign_type);
nclass->node_data->sign_method_offset = G_STRUCT_OFFSET(
diff --git a/lasso/xml/saml-2.0/samlp2_request_abstract.c b/lasso/xml/saml-2.0/samlp2_request_abstract.c
index 9eaa187f..ba43b63e 100644
--- a/lasso/xml/saml-2.0/samlp2_request_abstract.c
+++ b/lasso/xml/saml-2.0/samlp2_request_abstract.c
@@ -112,35 +112,6 @@ build_query(LassoNode *node)
return ret;
}
-static xmlNode*
-get_xmlNode(LassoNode *node, gboolean lasso_dump)
-{
- LassoSamlp2RequestAbstract *request = LASSO_SAMLP2_REQUEST_ABSTRACT(node);
- xmlNode *xmlnode;
- int rc = -1;
-
- xmlnode = parent_class->get_xmlNode(node, lasso_dump);
-
- if (lasso_dump == FALSE && request->sign_type) {
- if (request->private_key_file == NULL) {
- message(G_LOG_LEVEL_WARNING,
- "No Private Key set for signing samlp2:RequestAbstract");
- } else {
- rc = lasso_sign_node(xmlnode, "ID", request->ID,
- request->private_key_file, request->certificate_file);
- if (rc != 0) {
- message(G_LOG_LEVEL_WARNING, "Signing of samlp2:RequestAbstract failed: %s", lasso_strerror(rc));
- }
- }
- if (rc != 0) {
- lasso_release_xml_node(xmlnode);
- }
- }
-
- return xmlnode;
-}
-
-
/*****************************************************************************/
/* instance and class init functions */
/*****************************************************************************/
@@ -159,13 +130,14 @@ class_init(LassoSamlp2RequestAbstractClass *klass)
parent_class = g_type_class_peek_parent(klass);
nclass->build_query = build_query;
nclass->init_from_query = init_from_query;
- nclass->get_xmlNode = get_xmlNode;
nclass->node_data = g_new0(LassoNodeClassData, 1);
nclass->node_data->keep_xmlnode = TRUE;
lasso_node_class_set_nodename(nclass, "RequestAbstract");
lasso_node_class_set_ns(nclass, LASSO_SAML2_PROTOCOL_HREF, LASSO_SAML2_PROTOCOL_PREFIX);
lasso_node_class_add_snippets(nclass, schema_snippets);
+ nclass->node_data->id_attribute_name = "ID";
+ nclass->node_data->id_attribute_offset = G_STRUCT_OFFSET(LassoSamlp2RequestAbstract, ID);
nclass->node_data->sign_type_offset = G_STRUCT_OFFSET(
LassoSamlp2RequestAbstract, sign_type);
nclass->node_data->sign_method_offset = G_STRUCT_OFFSET(
diff --git a/lasso/xml/saml-2.0/samlp2_status_response.c b/lasso/xml/saml-2.0/samlp2_status_response.c
index 9cf004f8..e8c9b74e 100644
--- a/lasso/xml/saml-2.0/samlp2_status_response.c
+++ b/lasso/xml/saml-2.0/samlp2_status_response.c
@@ -117,34 +117,6 @@ init_from_query(LassoNode *node, char **query_fields)
return lasso_node_init_from_saml2_query_fields(node, query_fields, NULL);
}
-static xmlNode*
-get_xmlNode(LassoNode *node, gboolean lasso_dump)
-{
- LassoSamlp2StatusResponse *response = LASSO_SAMLP2_STATUS_RESPONSE(node);
- xmlNode *xmlnode;
- int rc = -1;
-
- xmlnode = parent_class->get_xmlNode(node, lasso_dump);
-
- if (lasso_dump == FALSE && response->sign_type) {
- if (response->private_key_file == NULL) {
- message(G_LOG_LEVEL_WARNING,
- "No Private Key set for signing samlp2:StatusResponse");
- } else {
- rc = lasso_sign_node(xmlnode, "ID", response->ID,
- response->private_key_file, response->certificate_file);
- if (rc != 0) {
- message(G_LOG_LEVEL_WARNING, "Signing of samlp2:StatusResponse failed: %s", lasso_strerror(rc));
- }
- }
- if (rc != 0) {
- lasso_release_xml_node(xmlnode);
- }
- }
-
- return xmlnode;
-}
-
/*****************************************************************************/
/* instance and class init functions */
/*****************************************************************************/
@@ -163,12 +135,13 @@ class_init(LassoSamlp2StatusResponseClass *klass)
parent_class = g_type_class_peek_parent(klass);
nclass->build_query = build_query;
nclass->init_from_query = init_from_query;
- nclass->get_xmlNode = get_xmlNode;
nclass->node_data = g_new0(LassoNodeClassData, 1);
lasso_node_class_set_nodename(nclass, "StatusResponse");
lasso_node_class_set_ns(nclass, LASSO_SAML2_PROTOCOL_HREF, LASSO_SAML2_PROTOCOL_PREFIX);
lasso_node_class_add_snippets(nclass, schema_snippets);
+ nclass->node_data->id_attribute_name = "ID";
+ nclass->node_data->id_attribute_offset = G_STRUCT_OFFSET(LassoSamlp2StatusResponse, ID);
nclass->node_data->sign_type_offset = G_STRUCT_OFFSET(
LassoSamlp2StatusResponse, sign_type);
nclass->node_data->sign_method_offset = G_STRUCT_OFFSET(
diff --git a/lasso/xml/saml_assertion.c b/lasso/xml/saml_assertion.c
index 2e3afcc7..82f7db53 100644
--- a/lasso/xml/saml_assertion.c
+++ b/lasso/xml/saml_assertion.c
@@ -150,31 +150,13 @@ insure_namespace(xmlNode *xmlnode, xmlNs *ns)
static xmlNode*
get_xmlNode(LassoNode *node, gboolean lasso_dump)
{
- LassoSamlAssertion *assertion = LASSO_SAML_ASSERTION(node);
xmlNode *xmlnode;
xmlNs *ns;
- int rc = -1;
xmlnode = parent_class->get_xmlNode(node, lasso_dump);
ns = xmlSearchNs(NULL, xmlnode, (xmlChar*)"saml");
insure_namespace(xmlnode, ns);
- if (lasso_dump == FALSE && assertion->sign_type) {
- if (assertion->private_key_file == NULL) {
- message(G_LOG_LEVEL_WARNING,
- "No Private Key set for signing saml:Assertion");
- } else {
- rc = lasso_sign_node(xmlnode, "AssertionID", assertion->AssertionID,
- assertion->private_key_file, assertion->certificate_file);
- if (rc != 0) {
- message(G_LOG_LEVEL_WARNING, "Signing of saml:Assertion failed: %s", lasso_strerror(rc));
- }
- }
- if (rc != 0) {
- lasso_release_xml_node(xmlnode);
- }
- }
-
return xmlnode;
}
@@ -193,6 +175,8 @@ class_init(LassoSamlAssertionClass *klass)
lasso_node_class_set_nodename(nclass, "Assertion");
lasso_node_class_set_ns(nclass, LASSO_SAML_ASSERTION_HREF, LASSO_SAML_ASSERTION_PREFIX);
lasso_node_class_add_snippets(nclass, schema_snippets);
+ nclass->node_data->id_attribute_name = "AssertionID";
+ nclass->node_data->id_attribute_offset = G_STRUCT_OFFSET(LassoSamlAssertion, AssertionID);
nclass->node_data->sign_type_offset = G_STRUCT_OFFSET(LassoSamlAssertion, sign_type);
nclass->node_data->sign_method_offset = G_STRUCT_OFFSET(LassoSamlAssertion, sign_method);
nclass->node_data->private_key_file_offset = G_STRUCT_OFFSET(LassoSamlAssertion,
diff --git a/lasso/xml/samlp_request_abstract.c b/lasso/xml/samlp_request_abstract.c
index 1e0a5f6e..05e7499d 100644
--- a/lasso/xml/samlp_request_abstract.c
+++ b/lasso/xml/samlp_request_abstract.c
@@ -78,34 +78,6 @@ static struct XmlSnippet schema_snippets[] = {
static LassoNodeClass *parent_class = NULL;
-static xmlNode*
-get_xmlNode(LassoNode *node, gboolean lasso_dump)
-{
- LassoSamlpRequestAbstract *request = LASSO_SAMLP_REQUEST_ABSTRACT(node);
- xmlNode *xmlnode;
- int rc = -1;
-
- xmlnode = parent_class->get_xmlNode(node, lasso_dump);
-
- if (lasso_dump == FALSE && request->sign_type) {
- if (request->private_key_file == NULL) {
- message(G_LOG_LEVEL_WARNING,
- "No Private Key set for signing samlp:RequestAbstract");
- } else {
- rc = lasso_sign_node(xmlnode, "RequestID", request->RequestID,
- request->private_key_file, request->certificate_file);
- if (rc != 0) {
- message(G_LOG_LEVEL_WARNING, "Signing of samlp:RequestAbstract failed: %s", lasso_strerror(rc));
- }
- }
- if (rc != 0) {
- lasso_release_xml_node(xmlnode);
- }
- }
-
- return xmlnode;
-}
-
/*****************************************************************************/
/* instance and class init functions */
/*****************************************************************************/
@@ -122,11 +94,13 @@ class_init(LassoSamlpRequestAbstractClass *klass)
LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
parent_class = g_type_class_peek_parent(klass);
- nclass->get_xmlNode = get_xmlNode;
nclass->node_data = g_new0(LassoNodeClassData, 1);
lasso_node_class_set_nodename(nclass, "RequestAbstract");
lasso_node_class_set_ns(nclass, LASSO_SAML_PROTOCOL_HREF, LASSO_SAML_PROTOCOL_PREFIX);
lasso_node_class_add_snippets(nclass, schema_snippets);
+ nclass->node_data->id_attribute_name = "RequestID";
+ nclass->node_data->id_attribute_offset = G_STRUCT_OFFSET(LassoSamlpRequestAbstract,
+ RequestID);
nclass->node_data->sign_type_offset = G_STRUCT_OFFSET(
LassoSamlpRequestAbstract, sign_type);
nclass->node_data->sign_method_offset = G_STRUCT_OFFSET(
diff --git a/lasso/xml/samlp_response_abstract.c b/lasso/xml/samlp_response_abstract.c
index f2cc245e..c671b93e 100644
--- a/lasso/xml/samlp_response_abstract.c
+++ b/lasso/xml/samlp_response_abstract.c
@@ -82,34 +82,6 @@ static struct XmlSnippet schema_snippets[] = {
static LassoNodeClass *parent_class = NULL;
-static xmlNode*
-get_xmlNode(LassoNode *node, gboolean lasso_dump)
-{
- LassoSamlpResponseAbstract *response = LASSO_SAMLP_RESPONSE_ABSTRACT(node);
- xmlNode *xmlnode;
- int rc = -1;
-
- xmlnode = parent_class->get_xmlNode(node, lasso_dump);
-
- if (lasso_dump == FALSE && response->sign_type) {
- if (response->private_key_file == NULL) {
- message(G_LOG_LEVEL_WARNING,
- "No Private Key set for signing samlp:ResponseAbstract");
- } else {
- rc = lasso_sign_node(xmlnode, "ResponseID", response->ResponseID,
- response->private_key_file, response->certificate_file);
- if (rc != 0) {
- message(G_LOG_LEVEL_WARNING, "Signing of samlp:ResponseAbstract failed: %s", lasso_strerror(rc));
- }
- }
- if (rc != 0) {
- lasso_release_xml_node(xmlnode);
- }
- }
-
- return xmlnode;
-}
-
/*****************************************************************************/
/* instance and class init functions */
/*****************************************************************************/
@@ -126,11 +98,13 @@ class_init(LassoSamlpResponseAbstractClass *klass)
LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
parent_class = g_type_class_peek_parent(klass);
- nclass->get_xmlNode = get_xmlNode;
nclass->node_data = g_new0(LassoNodeClassData, 1);
lasso_node_class_set_nodename(nclass, "ResponseAbstract");
lasso_node_class_set_ns(nclass, LASSO_SAML_PROTOCOL_HREF, LASSO_SAML_PROTOCOL_PREFIX);
lasso_node_class_add_snippets(nclass, schema_snippets);
+ nclass->node_data->id_attribute_name = "ResponseID";
+ nclass->node_data->id_attribute_offset = G_STRUCT_OFFSET(LassoSamlpResponseAbstract,
+ ResponseID);
nclass->node_data->sign_type_offset = G_STRUCT_OFFSET(LassoSamlpResponseAbstract,
sign_type);
nclass->node_data->sign_method_offset = G_STRUCT_OFFSET(LassoSamlpResponseAbstract,
diff --git a/lasso/xml/tools.c b/lasso/xml/tools.c
index 96b4f139..3e3272ea 100644
--- a/lasso/xml/tools.c
+++ b/lasso/xml/tools.c
@@ -2221,3 +2221,32 @@ lasso_log_remove_handler(guint handler_id)
{
g_log_remove_handler("Lasso", handler_id);
}
+
+void
+lasso_apply_signature(LassoNode *node, gboolean lasso_dump,
+ xmlNode **xmlnode, char *id_attribute, char *id_value, LassoSignatureType sign_type, char *private_key_file, char *certificate_file)
+{
+ int rc = 0;
+
+ if (lasso_dump == FALSE && sign_type) {
+ char *node_name;
+ char *prefix;
+
+ node_name = LASSO_NODE_GET_CLASS(node)->node_data->node_name;
+ prefix = (char*)LASSO_NODE_GET_CLASS(node)->node_data->ns->prefix;
+
+ if (private_key_file == NULL) {
+ message(G_LOG_LEVEL_WARNING,
+ "No Private Key set for signing %s:%s", prefix, node_name);
+ } else {
+ rc = lasso_sign_node(*xmlnode, id_attribute, id_value, private_key_file,
+ certificate_file);
+ if (rc != 0) {
+ message(G_LOG_LEVEL_WARNING, "Signing of %s:%s: %s", prefix, node_name, lasso_strerror(rc));
+ }
+ }
+ if (rc != 0) {
+ lasso_release_xml_node(*xmlnode);
+ }
+ }
+}
diff --git a/lasso/xml/xml.c b/lasso/xml/xml.c
index 4350ff8d..489fc87f 100644
--- a/lasso/xml/xml.c
+++ b/lasso/xml/xml.c
@@ -688,9 +688,37 @@ xmlNode*
lasso_node_get_xmlNode(LassoNode *node, gboolean lasso_dump)
{
LassoNodeClass *class;
+ xmlNode *xmlnode;
+ LassoNodeClassData *node_data = NULL;
+
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
class = LASSO_NODE_GET_CLASS(node);
- return class->get_xmlNode(node, lasso_dump);
+ xmlnode = class->get_xmlNode(node, lasso_dump);
+
+ /* find a class defining a signature */
+ while (class && LASSO_IS_NODE_CLASS(class)) {
+ if (class->node_data && class->node_data->sign_type_offset) {
+ node_data = class->node_data;
+ break;
+ }
+ class = g_type_class_peek_parent(class);
+ }
+
+ /* add signature */
+ if (xmlnode && node_data && node_data->sign_type_offset) {
+ LassoSignatureType sign_type = G_STRUCT_MEMBER(LassoSignatureType, node,
+ node_data->sign_type_offset);
+ char *id_attribute = G_STRUCT_MEMBER(char*, node, node_data->id_attribute_offset);
+ char *private_key_file = G_STRUCT_MEMBER(char*, node,
+ node_data->private_key_file_offset);
+ char *certificate_file = G_STRUCT_MEMBER(char*, node,
+ node_data->certificate_file_offset);
+
+ lasso_apply_signature(node, lasso_dump, &xmlnode, node_data->id_attribute_name,
+ id_attribute, sign_type, private_key_file, certificate_file);
+ }
+
+ return xmlnode;
}
/**
@@ -2883,7 +2911,6 @@ xml_insure_namespace(xmlNode *xmlnode, xmlNs *ns, gboolean force, gchar *ns_href
xmlNode*
lasso_node_get_xmlnode_for_any_type(LassoNode *node, xmlNode *cur)
{
-
xmlNode *original_xmlnode;
original_xmlnode = lasso_node_get_original_xmlnode(node);