summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lasso/id-ff/defederation.c13
-rw-r--r--lasso/id-ff/federation.c1
-rw-r--r--lasso/id-ff/login.c24
-rw-r--r--lasso/id-ff/logout.c1
-rw-r--r--lasso/id-ff/name_registration.c1
-rw-r--r--lasso/id-ff/profile.c76
-rw-r--r--lasso/id-ff/profileprivate.h3
-rw-r--r--lasso/id-ff/provider.c3
-rw-r--r--lasso/id-ff/server.c14
-rw-r--r--lasso/xml/lib_assertion.c3
-rw-r--r--lasso/xml/lib_authentication_statement.c3
-rw-r--r--lasso/xml/lib_subject.c3
-rw-r--r--lasso/xml/misc_text_node.c28
-rw-r--r--lasso/xml/private.h33
-rw-r--r--lasso/xml/saml-2.0/saml2_key_info_confirmation_data_type.c102
-rw-r--r--lasso/xml/saml-2.0/saml2_key_info_confirmation_data_type.h14
-rw-r--r--lasso/xml/saml-2.0/samlp2_logout_request.c10
-rw-r--r--lasso/xml/soap-1.1/soap_body.c20
-rw-r--r--lasso/xml/tools.c59
-rw-r--r--lasso/xml/xml.c807
20 files changed, 661 insertions, 557 deletions
diff --git a/lasso/id-ff/defederation.c b/lasso/id-ff/defederation.c
index 062a5beb..4cf3aada 100644
--- a/lasso/id-ff/defederation.c
+++ b/lasso/id-ff/defederation.c
@@ -456,6 +456,15 @@ lasso_defederation_validate_notification(LassoDefederation *defederation)
/* instance and class init functions */
/*****************************************************************************/
+static void
+class_init(LassoDefederationClass *klass)
+{
+ LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
+
+ nclass->node_data = NULL;
+}
+
+
GType
lasso_defederation_get_type()
{
@@ -464,11 +473,11 @@ lasso_defederation_get_type()
if (!this_type) {
static const GTypeInfo this_info = {
sizeof (LassoDefederationClass),
- NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, (GClassInitFunc) class_init, NULL, NULL,
sizeof(LassoDefederation),
0,
NULL,
- NULL
+ NULL,
};
this_type = g_type_register_static(LASSO_TYPE_PROFILE,
diff --git a/lasso/id-ff/federation.c b/lasso/id-ff/federation.c
index 7c28e2be..4dbea978 100644
--- a/lasso/id-ff/federation.c
+++ b/lasso/id-ff/federation.c
@@ -167,6 +167,7 @@ static struct XmlSnippet schema_snippets[] = {
G_STRUCT_OFFSET(LassoFederation, remote_nameIdentifier), NULL, NULL, NULL},
{ "RemoteProviderID", SNIPPET_ATTRIBUTE,
G_STRUCT_OFFSET(LassoFederation, remote_providerID), NULL, NULL, NULL},
+ { "FederationDumpVersion", SNIPPET_ATTRIBUTE, 0, NULL, NULL, NULL },
{NULL, 0, 0, NULL, NULL, NULL}
};
diff --git a/lasso/id-ff/login.c b/lasso/id-ff/login.c
index 15e4735e..dd3cc5c7 100644
--- a/lasso/id-ff/login.c
+++ b/lasso/id-ff/login.c
@@ -274,6 +274,9 @@
#include "../id-wsf/id_ff_extensions_private.h"
#endif
+#define LASSO_LOGIN_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), LASSO_TYPE_LOGIN, LassoLoginPrivate))
+
static void lasso_login_build_assertion_artifact(LassoLogin *login);
@@ -2286,6 +2289,10 @@ static struct XmlSnippet schema_snippets[] = {
{ "AssertionArtifact", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoLogin, assertionArtifact), NULL, NULL, NULL},
{ "NameIDPolicy", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoLogin, nameIDPolicy), NULL, NULL, NULL},
{ "Assertion", SNIPPET_NODE_IN_CHILD, G_STRUCT_OFFSET(LassoLogin, assertion), NULL, NULL, NULL},
+ { "RequestID", SNIPPET_CONTENT | SNIPPET_PRIVATE,
+ G_STRUCT_OFFSET(LassoLoginPrivate, request_id), NULL, NULL, NULL},
+ { "LoginDumpVersion", SNIPPET_ATTRIBUTE, 0, NULL, NULL, NULL},
+ { "ProtocolProfile", SNIPPET_CONTENT, 0, NULL, NULL, NULL},
{NULL, 0, 0, NULL, NULL, NULL}
};
@@ -2299,7 +2306,6 @@ get_xmlNode(LassoNode *node, gboolean lasso_dump)
xmlnode = parent_class->get_xmlNode(node, lasso_dump);
xmlSetProp(xmlnode, (xmlChar*)"LoginDumpVersion", (xmlChar*)"2");
- xmlSetProp(xmlnode, (xmlChar*)"RequestID", (xmlChar*)LASSO_LOGIN(node)->private_data->request_id);
if (login->protocolProfile == LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART)
xmlNewTextChild(xmlnode, NULL, (xmlChar*)"ProtocolProfile", (xmlChar*)"Artifact");
@@ -2321,9 +2327,6 @@ init_from_xml(LassoNode *node, xmlNode *xmlnode)
rc = parent_class->init_from_xml(node, xmlnode);
if (rc) return rc;
- lasso_assign_new_string(LASSO_LOGIN(node)->private_data->request_id, (char*)xmlGetProp(xmlnode,
- (xmlChar*)"RequestID"));
-
t = xmlnode->children;
while (t) {
if (t->type != XML_ELEMENT_NODE) {
@@ -2367,14 +2370,6 @@ dispose(GObject *object)
G_OBJECT_CLASS(parent_class)->dispose(object);
}
-static void
-finalize(GObject *object)
-{
- LassoLogin *login = LASSO_LOGIN(object);
- lasso_release(login->private_data);
- G_OBJECT_CLASS(parent_class)->finalize(object);
-}
-
/*****************************************************************************/
/* instance and class init functions */
/*****************************************************************************/
@@ -2382,8 +2377,7 @@ finalize(GObject *object)
static void
instance_init(LassoLogin *login)
{
- login->private_data = g_new0(LassoLoginPrivate, 1);
-
+ login->private_data = LASSO_LOGIN_GET_PRIVATE(login);
login->protocolProfile = 0;
login->assertionArtifact = NULL;
login->nameIDPolicy = NULL;
@@ -2402,9 +2396,9 @@ class_init(LassoLoginClass *klass)
lasso_node_class_set_nodename(nclass, "Login");
lasso_node_class_set_ns(nclass, LASSO_LASSO_HREF, LASSO_LASSO_PREFIX);
lasso_node_class_add_snippets(nclass, schema_snippets);
+ g_type_class_add_private(klass, sizeof(LassoLoginPrivate));
G_OBJECT_CLASS(klass)->dispose = dispose;
- G_OBJECT_CLASS(klass)->finalize = finalize;
}
GType
diff --git a/lasso/id-ff/logout.c b/lasso/id-ff/logout.c
index e8886933..7567a47d 100644
--- a/lasso/id-ff/logout.c
+++ b/lasso/id-ff/logout.c
@@ -1162,6 +1162,7 @@ static struct XmlSnippet schema_snippets[] = {
G_STRUCT_OFFSET(LassoLogout, initial_remote_providerID), NULL, NULL, NULL},
{ "InitialHttpRequestMethod", SNIPPET_CONTENT | SNIPPET_INTEGER,
G_STRUCT_OFFSET(LassoLogout, initial_http_request_method), NULL, NULL, NULL},
+ { "LogoutDumpVersion", SNIPPET_ATTRIBUTE, 0, NULL, NULL, NULL },
/* "ProviderIdIndex" must not be dumped (since apps assume to get
* it back to 0 after a restore from dump) (maybe this behaviour should
* be fixed)
diff --git a/lasso/id-ff/name_registration.c b/lasso/id-ff/name_registration.c
index 0badf76d..7d554902 100644
--- a/lasso/id-ff/name_registration.c
+++ b/lasso/id-ff/name_registration.c
@@ -645,6 +645,7 @@ lasso_name_registration_validate_request(LassoNameRegistration *name_registratio
static struct XmlSnippet schema_snippets[] = {
{ "OldNameIdentifier", SNIPPET_NODE_IN_CHILD,
G_STRUCT_OFFSET(LassoNameRegistration, oldNameIdentifier), NULL, NULL, NULL},
+ { "NameRegistrationDumpVersion", SNIPPET_ATTRIBUTE, 0, NULL, NULL, NULL},
{NULL, 0, 0, NULL, NULL, NULL}
};
diff --git a/lasso/id-ff/profile.c b/lasso/id-ff/profile.c
index c1c86daa..749fb119 100644
--- a/lasso/id-ff/profile.c
+++ b/lasso/id-ff/profile.c
@@ -539,69 +539,15 @@ static struct XmlSnippet schema_snippets[] = {
NULL, NULL},
{ "HttpRequestMethod", SNIPPET_CONTENT | SNIPPET_INTEGER,
G_STRUCT_OFFSET(LassoProfile, http_request_method), NULL, NULL, NULL},
+ { "Artifact", SNIPPET_CONTENT | SNIPPET_PRIVATE, G_STRUCT_OFFSET(LassoProfilePrivate,
+ artifact), NULL, NULL, NULL },
+ { "ArtifactMessage", SNIPPET_CONTENT | SNIPPET_PRIVATE, G_STRUCT_OFFSET(LassoProfilePrivate,
+ artifact_message), NULL, NULL, NULL },
{NULL, 0, 0, NULL, NULL, NULL}
};
static LassoNodeClass *parent_class = NULL;
-static xmlNode*
-get_xmlNode(LassoNode *node, gboolean lasso_dump)
-{
- xmlNode *xmlnode;
- LassoProfile *profile = LASSO_PROFILE(node);
-
- xmlnode = parent_class->get_xmlNode(node, lasso_dump);
-
- if (profile->private_data->artifact) {
- xmlNewTextChild(xmlnode, NULL, (xmlChar*)"Artifact",
- (xmlChar*)profile->private_data->artifact);
- }
-
- if (profile->private_data->artifact_message) {
- xmlNewTextChild(xmlnode, NULL, (xmlChar*)"ArtifactMessage",
- (xmlChar*)profile->private_data->artifact_message);
- }
-
- return xmlnode;
-}
-
-
-static int
-init_from_xml(LassoNode *node, xmlNode *xmlnode)
-{
- LassoProfile *profile = LASSO_PROFILE(node);
- xmlNode *t;
-
- parent_class->init_from_xml(node, xmlnode);
-
- if (xmlnode == NULL)
- return LASSO_XML_ERROR_OBJECT_CONSTRUCTION_FAILED;
-
- t = xmlnode->children;
- while (t) {
- xmlChar *s;
-
- if (t->type != XML_ELEMENT_NODE) {
- t = t->next;
- continue;
- }
-
- if (strcmp((char*)t->name, "Artifact") == 0) {
- s = xmlNodeGetContent(t);
- lasso_assign_string(profile->private_data->artifact, (char*)s);
- xmlFree(s);
- } else if (strcmp((char*)t->name, "ArtifactMessage") == 0) {
- s = xmlNodeGetContent(t);
- lasso_assign_string(profile->private_data->artifact_message, (char*)s);
- xmlFree(s);
- }
-
- t = t->next;
- }
-
- return 0;
-}
-
/**
* lasso_profile_set_signature_hint:
* @profile: a #LassoProfile object
@@ -819,14 +765,6 @@ dispose(GObject *object)
G_OBJECT_CLASS(parent_class)->dispose(G_OBJECT(profile));
}
-static void
-finalize(GObject *object)
-{
- LassoProfile *profile = LASSO_PROFILE(object);
- lasso_release(profile->private_data);
- G_OBJECT_CLASS(parent_class)->finalize(object);
-}
-
/*****************************************************************************/
/* instance and class init functions */
/*****************************************************************************/
@@ -834,7 +772,7 @@ finalize(GObject *object)
static void
instance_init(LassoProfile *profile)
{
- profile->private_data = g_new0(LassoProfilePrivate, 1);
+ profile->private_data = LASSO_PROFILE_GET_PRIVATE(profile);
profile->private_data->dispose_has_run = FALSE;
profile->private_data->artifact = NULL;
profile->private_data->artifact_message = NULL;
@@ -864,11 +802,9 @@ class_init(LassoProfileClass *klass)
lasso_node_class_set_nodename(nclass, "Profile");
lasso_node_class_set_ns(nclass, LASSO_LASSO_HREF, LASSO_LASSO_PREFIX);
lasso_node_class_add_snippets(nclass, schema_snippets);
- nclass->get_xmlNode = get_xmlNode;
- nclass->init_from_xml = init_from_xml;
+ g_type_class_add_private(klass, sizeof(LassoProfilePrivate));
G_OBJECT_CLASS(klass)->dispose = dispose;
- G_OBJECT_CLASS(klass)->finalize = finalize;
}
GType
diff --git a/lasso/id-ff/profileprivate.h b/lasso/id-ff/profileprivate.h
index 3a9f563f..2aeefad0 100644
--- a/lasso/id-ff/profileprivate.h
+++ b/lasso/id-ff/profileprivate.h
@@ -44,6 +44,9 @@ struct _LassoProfilePrivate
void lasso_profile_set_response_status(LassoProfile *profile, const gchar *statusCodeValue);
void lasso_profile_clean_msg_info(LassoProfile *profile);
+#define LASSO_PROFILE_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), LASSO_TYPE_PROFILE, LassoProfilePrivate))
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/lasso/id-ff/provider.c b/lasso/id-ff/provider.c
index 494d1351..3f9e6173 100644
--- a/lasso/id-ff/provider.c
+++ b/lasso/id-ff/provider.c
@@ -516,6 +516,9 @@ static struct XmlSnippet schema_snippets[] = {
{ "CaCertChainFilePath", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoProvider, ca_cert_chain), NULL, NULL, NULL},
{ "MetadataFilePath", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoProvider, metadata_filename), NULL, NULL, NULL},
{ "ProviderID", SNIPPET_ATTRIBUTE, G_STRUCT_OFFSET(LassoProvider, ProviderID), NULL, NULL, NULL},
+ { "ProviderRole", SNIPPET_ATTRIBUTE, 0, NULL, NULL, NULL},
+ { "EncryptionMode", SNIPPET_ATTRIBUTE, 0, NULL, NULL, NULL},
+ { "ProviderDumpVersion", SNIPPET_ATTRIBUTE, 0, NULL, NULL, NULL},
{NULL, 0, 0, NULL, NULL, NULL}
};
diff --git a/lasso/id-ff/server.c b/lasso/id-ff/server.c
index c95e2713..390a55b7 100644
--- a/lasso/id-ff/server.c
+++ b/lasso/id-ff/server.c
@@ -254,10 +254,20 @@ cleanup:
/*****************************************************************************/
static struct XmlSnippet schema_snippets[] = {
- { "PrivateKeyFilePath", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoServer, private_key), NULL, NULL, NULL},
+ { "PrivateKeyFilePath", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoServer, private_key), NULL,
+ NULL, NULL},
{ "PrivateKeyPassword", SNIPPET_CONTENT,
G_STRUCT_OFFSET(LassoServer, private_key_password), NULL, NULL, NULL},
- { "CertificateFilePath", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoServer, certificate), NULL, NULL, NULL},
+ { "CertificateFilePath", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoServer, certificate), NULL,
+ NULL, NULL},
+ { "SignatureMethod", SNIPPET_ATTRIBUTE, 0, NULL, NULL, NULL },
+ { "Providers", SNIPPET_LIST_NODES, 0, NULL, NULL, NULL },
+ { "ServerDumpVersion", SNIPPET_ATTRIBUTE, 0, NULL, NULL, NULL },
+#ifdef LASSO_WSF_ENABLED
+ { "Services", SNIPPET_LIST_NODES, 0, NULL, NULL, NULL },
+ { "SvcMDs", SNIPPET_LIST_NODES, 0, NULL, NULL, NULL },
+#endif
+
{NULL, 0, 0, NULL, NULL, NULL}
};
diff --git a/lasso/xml/lib_assertion.c b/lasso/xml/lib_assertion.c
index b79b569e..17f71c14 100644
--- a/lasso/xml/lib_assertion.c
+++ b/lasso/xml/lib_assertion.c
@@ -79,7 +79,8 @@ class_init(LassoLibAssertionClass *klass)
LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
nclass->node_data = g_new0(LassoNodeClassData, 1);
- lasso_node_class_set_nodename(nclass, "Assertion");
+ nclass->node_data->xsi_sub_type = TRUE;
+ lasso_node_class_set_nodename(nclass, "AssertionType");
lasso_node_class_set_ns(nclass, LASSO_LIB_HREF, LASSO_LIB_PREFIX);
lasso_node_class_add_snippets(nclass, schema_snippets);
}
diff --git a/lasso/xml/lib_authentication_statement.c b/lasso/xml/lib_authentication_statement.c
index fb36d203..dff4be3a 100644
--- a/lasso/xml/lib_authentication_statement.c
+++ b/lasso/xml/lib_authentication_statement.c
@@ -74,7 +74,8 @@ class_init(LassoLibAuthenticationStatementClass *klass)
LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
nclass->node_data = g_new0(LassoNodeClassData, 1);
- lasso_node_class_set_nodename(nclass, "AuthenticationStatement");
+ nclass->node_data->xsi_sub_type = TRUE;
+ lasso_node_class_set_nodename(nclass, "AuthenticationStatementType");
lasso_node_class_set_ns(nclass, LASSO_LIB_HREF, LASSO_LIB_PREFIX);
lasso_node_class_add_snippets(nclass, schema_snippets);
}
diff --git a/lasso/xml/lib_subject.c b/lasso/xml/lib_subject.c
index 49335b4c..b44c9956 100644
--- a/lasso/xml/lib_subject.c
+++ b/lasso/xml/lib_subject.c
@@ -67,7 +67,8 @@ class_init(LassoLibSubjectClass *klass)
LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
nclass->node_data = g_new0(LassoNodeClassData, 1);
- lasso_node_class_set_nodename(nclass, "Subject");
+ nclass->node_data->xsi_sub_type = TRUE;
+ lasso_node_class_set_nodename(nclass, "SubjectType");
lasso_node_class_set_ns(nclass, LASSO_LIB_HREF, LASSO_LIB_PREFIX);
lasso_node_class_add_snippets(nclass, schema_snippets);
}
diff --git a/lasso/xml/misc_text_node.c b/lasso/xml/misc_text_node.c
index 1cbaa675..0d88ad5e 100644
--- a/lasso/xml/misc_text_node.c
+++ b/lasso/xml/misc_text_node.c
@@ -33,6 +33,7 @@
typedef struct {
xmlNode *xml_content;
+ GHashTable *any_attributes;
} LassoMiscTextNodePrivate;
#define LASSO_MISC_TEXT_NODE_GET_PRIVATE(o) \
@@ -41,30 +42,19 @@ typedef struct {
static struct XmlSnippet schema_snippets[] = {
{ "content", SNIPPET_TEXT_CHILD,
G_STRUCT_OFFSET(LassoMiscTextNode, content), NULL, NULL, NULL},
+ { "any_attributes", SNIPPET_ATTRIBUTE | SNIPPET_ANY | SNIPPET_PRIVATE,
+ G_STRUCT_OFFSET(LassoMiscTextNodePrivate, any_attributes), NULL, NULL, NULL},
{NULL, 0, 0, NULL, NULL, NULL}
};
static LassoNodeClass *parent_class = NULL;
-
-static void
-insure_namespace(xmlNode *xmlnode, xmlNs *ns)
-{
- xmlNode *t = xmlnode->children;
-
- xmlSetNs(xmlnode, ns);
- while (t) {
- if (t->type == XML_ELEMENT_NODE && t->ns == NULL)
- insure_namespace(t, ns);
- t = t->next;
- }
-}
-
static xmlNode*
get_xmlNode(LassoNode *node, gboolean lasso_dump)
{
xmlNode *xmlnode;
xmlNs *ns;
+ LassoMiscTextNode *mtnode = (LassoMiscTextNode*)node;
LassoMiscTextNodePrivate *private;
private = LASSO_MISC_TEXT_NODE_GET_PRIVATE(node);
@@ -77,10 +67,12 @@ get_xmlNode(LassoNode *node, gboolean lasso_dump)
}
xmlnode = parent_class->get_xmlNode(node, lasso_dump);
- xmlNodeSetName(xmlnode, (xmlChar*)LASSO_MISC_TEXT_NODE(node)->name);
- ns = xmlNewNs(xmlnode, (xmlChar*)LASSO_MISC_TEXT_NODE(node)->ns_href,
- (xmlChar*)LASSO_MISC_TEXT_NODE(node)->ns_prefix);
- insure_namespace(xmlnode, ns);
+ xmlNodeSetName(xmlnode, BAD_CAST mtnode->name);
+ if (! lasso_strisempty(mtnode->ns_href) && ! lasso_strisempty(mtnode->ns_href)) {
+ ns = xmlNewNs(xmlnode, BAD_CAST mtnode->ns_href,
+ BAD_CAST mtnode->ns_prefix);
+ xmlSetNs(xmlnode, ns);
+ }
return xmlnode;
}
diff --git a/lasso/xml/private.h b/lasso/xml/private.h
index 0a301112..009596d8 100644
--- a/lasso/xml/private.h
+++ b/lasso/xml/private.h
@@ -40,7 +40,7 @@ typedef enum {
SNIPPET_NODE,
SNIPPET_CONTENT,
SNIPPET_TEXT_CHILD,
- SNIPPET_NAME_IDENTIFIER,
+ SNIPPET_UNUSED1,
SNIPPET_ATTRIBUTE,
SNIPPET_NODE_IN_CHILD,
SNIPPET_LIST_NODES,
@@ -72,11 +72,15 @@ typedef enum {
} SignatureVerificationOption;
struct XmlSnippet {
- char *name;
- SnippetType type;
- guint offset;
- char *class_name;
- char *ns_name;
+ char *name; /* name of the node or attribute to match */
+ SnippetType type; /* type of node to deserialize */
+ guint offset; /* offset of the storage field relative to the public or private object (if
+ using SNIPPET_PRIVATE). If 0, means that no storage must be done, it will
+ be handled by the init_from_xml virtual method. */
+ char *class_name; /* Force a certain LassoNode class for deserializing a node, usually
+ useless. */
+ char *ns_name; /* if the namespace is different from the one of the parent node, specify it
+ there */
char *ns_uri;
};
@@ -156,6 +160,7 @@ struct _LassoNodeClassData
int private_key_file_offset;
int certificate_file_offset;
gboolean keep_xmlnode;
+ gboolean xsi_sub_type;
};
void lasso_node_class_set_nodename(LassoNodeClass *klass, char *name);
@@ -278,6 +283,22 @@ LassoSignatureContext lasso_make_signature_context_from_path_or_string(char *fil
const char *password, LassoSignatureMethod signature_method,
const char *certificate);
+xmlNs * get_or_define_ns(xmlNode *xmlnode, const xmlChar *ns_uri, const xmlChar
+ *advised_prefix);
+
+void set_qname_attribute(xmlNode *node,
+ const xmlChar *attribute_ns_prefix,
+ const xmlChar *attribute_ns_href,
+ const xmlChar *attribute_name,
+ const xmlChar *prefix,
+ const xmlChar *href,
+ const xmlChar *name);
+
+
+void set_xsi_type(xmlNode *node,
+ const xmlChar *type_ns_prefix,
+ const xmlChar *type_ns_href,
+ const xmlChar *type_name);
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/lasso/xml/saml-2.0/saml2_key_info_confirmation_data_type.c b/lasso/xml/saml-2.0/saml2_key_info_confirmation_data_type.c
index 50f3c46a..901b709b 100644
--- a/lasso/xml/saml-2.0/saml2_key_info_confirmation_data_type.c
+++ b/lasso/xml/saml-2.0/saml2_key_info_confirmation_data_type.c
@@ -58,68 +58,33 @@
/* private methods */
/*****************************************************************************/
+struct _LassoSaml2KeyInfoConfirmationDataTypePrivate {
+ GList *KeyInfo;
+};
static struct XmlSnippet schema_snippets[] = {
- { "KeyInfo", SNIPPET_LIST_NODES,
- G_STRUCT_OFFSET(LassoSaml2KeyInfoConfirmationDataType, KeyInfo), NULL, NULL, NULL},
+ { "KeyInfo", SNIPPET_LIST_NODES|SNIPPET_PRIVATE,
+ G_STRUCT_OFFSET(LassoSaml2KeyInfoConfirmationDataTypePrivate, KeyInfo), "LassoDsKeyInfo", NULL, NULL},
{NULL, 0, 0, NULL, NULL, NULL}
};
static LassoNodeClass *parent_class = NULL;
+#define LASSO_SAML2_KEY_INFO_CONFIRMATION_DATA_TYPE_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), LASSO_TYPE_SAML2_KEY_INFO_CONFIRMATION_DATA_TYPE, LassoSaml2KeyInfoConfirmationDataTypePrivate))
/*****************************************************************************/
/* instance and class init functions */
/*****************************************************************************/
-static xmlNs *
-ensure_namespace(xmlNode *node, const xmlChar *href, const xmlChar *prefix)
-{
- xmlNs *ns;
-
- ns = xmlSearchNsByHref(node->doc, node, href);
- if (! ns) {
- ns = xmlNewNs(node, href, prefix);
- xmlSetNs(node, ns);
- }
- return ns;
-}
-
static void
-set_qname_attribue(xmlNode *node, xmlChar *attribute_name, const xmlChar *name, const
- xmlChar *href, const xmlChar *prefix) {
- xmlNs *type_ns;
- xmlNs *xsi_ns;
- xmlChar *value;
-
- xsi_ns = ensure_namespace(node, BAD_CAST LASSO_XSI_HREF, BAD_CAST LASSO_XSI_PREFIX);
- type_ns = ensure_namespace(node, href, prefix);
- value = BAD_CAST g_strdup_printf("%s:%s", type_ns->prefix, name);
- xmlSetNsProp(node, xsi_ns, attribute_name, value);
- lasso_release_string(value);
-}
-
-static void
-set_xsi_type(xmlNode *node, const xmlChar *type, const xmlChar *href, const xmlChar *prefix) {
- set_qname_attribue(node, BAD_CAST "type", type, href, prefix);
-}
-
-static xmlNode*
-get_xmlNode(LassoNode *node, gboolean lasso_dump)
+instance_init(LassoSaml2KeyInfoConfirmationDataType *saml2_key_info_confirmation_data_type)
{
- xmlNode *xmlnode = NULL;
-
- /* add xsi:type="KeyInfoConfirmationDataType" */
- xmlnode = parent_class->get_xmlNode(node, lasso_dump);
- set_xsi_type(xmlnode,
- BAD_CAST "KeyInfoConfirmationDataType",
- BAD_CAST LASSO_SAML2_ASSERTION_HREF,
- BAD_CAST LASSO_SAML2_ASSERTION_PREFIX);
-
- return xmlnode;
+ saml2_key_info_confirmation_data_type->private_data =
+ LASSO_SAML2_KEY_INFO_CONFIRMATION_DATA_TYPE_GET_PRIVATE(
+ saml2_key_info_confirmation_data_type);
}
-
static void
class_init(LassoSaml2KeyInfoConfirmationDataTypeClass *klass)
{
@@ -127,8 +92,11 @@ class_init(LassoSaml2KeyInfoConfirmationDataTypeClass *klass)
parent_class = g_type_class_peek_parent(klass);
nclass->node_data = g_new0(LassoNodeClassData, 1);
- nclass->get_xmlNode = get_xmlNode;
+ nclass->node_data->xsi_sub_type = TRUE;
+ lasso_node_class_set_nodename(nclass, "KeyInfoConfirmationDataType");
+ lasso_node_class_set_ns(nclass, LASSO_SAML2_ASSERTION_HREF, LASSO_SAML2_ASSERTION_PREFIX);
lasso_node_class_add_snippets(nclass, schema_snippets);
+ g_type_class_add_private(klass, sizeof(LassoSaml2KeyInfoConfirmationDataTypePrivate));
}
GType
@@ -146,7 +114,7 @@ lasso_saml2_key_info_confirmation_data_type_get_type()
NULL,
sizeof(LassoSaml2KeyInfoConfirmationDataType),
0,
- NULL,
+ (GInstanceInitFunc)instance_init,
NULL
};
@@ -171,3 +139,41 @@ lasso_saml2_key_info_confirmation_data_type_new()
{
return g_object_new(LASSO_TYPE_SAML2_KEY_INFO_CONFIRMATION_DATA_TYPE, NULL);
}
+
+/**
+ * lasso_saml2_key_info_confirmation_data_type_get_key_info:
+ * @kicdt: a #LassoSaml2KeyInfoConfirmationDataType object.
+ *
+ * Return the list of KeyInfo node contained in the saml2:SubjectConfirmationData of type
+ * saml2:KeyInfoConfirmationDataType.
+ *
+ * Return value:(element-type LassoDsKeyInfo)(transfer none): a list of #LassoDsKeyInfo objects.
+ */
+GList*
+lasso_saml2_key_info_confirmation_data_type_get_key_info(
+ LassoSaml2KeyInfoConfirmationDataType *kicdt)
+{
+ lasso_return_val_if_fail(LASSO_IS_SAML2_KEY_INFO_CONFIRMATION_DATA_TYPE(kicdt), NULL);
+
+ return kicdt->private_data->KeyInfo;
+}
+
+/**
+ * lasso_saml2_key_info_confirmation_data_type_set_key_info:
+ * @kicdt: a #LassoSaml2KeyInfoConfirmationDataType object.
+ * @key_infos:(tranfer none)(element-type LassoDsKeyInfo): a list of #LassoDsKeyInfo object.
+ *
+ * Set the list of ds:KeyInfo nodes for the saml2:SubjectConfirmationData of type
+ * saml2:KeyInfoConfirmationDataType.
+ */
+void
+lasso_saml2_key_info_confirmation_data_type_set_key_info(
+ LassoSaml2KeyInfoConfirmationDataType *kicdt,
+ GList *key_infos)
+{
+ lasso_return_if_fail(LASSO_IS_SAML2_KEY_INFO_CONFIRMATION_DATA_TYPE(kicdt));
+
+ lasso_assign_list_of_gobjects(
+ kicdt->private_data->KeyInfo,
+ key_infos);
+}
diff --git a/lasso/xml/saml-2.0/saml2_key_info_confirmation_data_type.h b/lasso/xml/saml-2.0/saml2_key_info_confirmation_data_type.h
index 6ebd0f64..f66235ab 100644
--- a/lasso/xml/saml-2.0/saml2_key_info_confirmation_data_type.h
+++ b/lasso/xml/saml-2.0/saml2_key_info_confirmation_data_type.h
@@ -51,14 +51,13 @@ extern "C" {
typedef struct _LassoSaml2KeyInfoConfirmationDataType LassoSaml2KeyInfoConfirmationDataType;
typedef struct _LassoSaml2KeyInfoConfirmationDataTypeClass LassoSaml2KeyInfoConfirmationDataTypeClass;
-
+typedef struct _LassoSaml2KeyInfoConfirmationDataTypePrivate LassoSaml2KeyInfoConfirmationDataTypePrivate;
struct _LassoSaml2KeyInfoConfirmationDataType {
LassoSaml2SubjectConfirmationData parent;
- /*< public >*/
- /* attributes */
- GList *KeyInfo; /* of LassoDsKeyInfo */
+ /*< private >*/
+ LassoSaml2KeyInfoConfirmationDataTypePrivate *private_data;
};
@@ -68,8 +67,11 @@ struct _LassoSaml2KeyInfoConfirmationDataTypeClass {
LASSO_EXPORT GType lasso_saml2_key_info_confirmation_data_type_get_type(void);
LASSO_EXPORT LassoNode* lasso_saml2_key_info_confirmation_data_type_new(void);
-
-
+LASSO_EXPORT GList *lasso_saml2_key_info_confirmation_data_type_get_key_info(
+ LassoSaml2KeyInfoConfirmationDataType *kicdt);
+LASSO_EXPORT void lasso_saml2_key_info_confirmation_data_type_set_key_info(
+ LassoSaml2KeyInfoConfirmationDataType *kicdt,
+ GList *key_infos);
#ifdef __cplusplus
}
diff --git a/lasso/xml/saml-2.0/samlp2_logout_request.c b/lasso/xml/saml-2.0/samlp2_logout_request.c
index 0152a0d5..947e0cd6 100644
--- a/lasso/xml/saml-2.0/samlp2_logout_request.c
+++ b/lasso/xml/saml-2.0/samlp2_logout_request.c
@@ -142,7 +142,6 @@ init_from_xml(LassoNode *node, xmlNode *xmlnode)
rc = parent_class->init_from_xml(node, xmlnode);
if (rc == 0) {
- GList *last;
pv = GET_PRIVATE(node);
child = xmlSecFindChild(xmlnode, BAD_CAST SESSION_INDEX,
@@ -154,11 +153,10 @@ init_from_xml(LassoNode *node, xmlNode *xmlnode)
lasso_release_xml_string(content);
child = xmlSecGetNextElementNode(child->next);
}
- /* remove the last one, since it is also stored in node->SessionIndex */
- last = g_list_last(pv->SessionIndex);
- if (last) {
- lasso_release_string(last->data);
- pv->SessionIndex = g_list_delete_link(pv->SessionIndex, last);
+ /* remove the first one, since it is also stored in node->SessionIndex */
+ if (pv->SessionIndex) {
+ lasso_release_string(pv->SessionIndex->data);
+ pv->SessionIndex = g_list_delete_link(pv->SessionIndex, pv->SessionIndex);
}
}
diff --git a/lasso/xml/soap-1.1/soap_body.c b/lasso/xml/soap-1.1/soap_body.c
index d88b805f..4a1768d2 100644
--- a/lasso/xml/soap-1.1/soap_body.c
+++ b/lasso/xml/soap-1.1/soap_body.c
@@ -65,9 +65,6 @@ static struct XmlSnippet schema_snippets[] = {
/* instance and class init functions */
/*****************************************************************************/
-static xmlNode* get_xmlNode(LassoNode *node, gboolean lasso_dump);
-
-
static LassoNodeClass *parent_class = NULL;
static void
@@ -77,28 +74,11 @@ class_init(LassoSoapBodyClass *klass)
parent_class = g_type_class_peek_parent(nclass);
nclass->node_data = g_new0(LassoNodeClassData, 1);
- nclass->get_xmlNode = get_xmlNode;
lasso_node_class_set_nodename(nclass, "Body");
lasso_node_class_set_ns(nclass, LASSO_SOAP_ENV_HREF, LASSO_SOAP_ENV_PREFIX);
lasso_node_class_add_snippets(nclass, schema_snippets);
}
-static xmlNode*
-get_xmlNode(LassoNode *node, gboolean lasso_dump) {
- xmlNodePtr ret;
-
- /* Fix namespace of Id */
- ret = parent_class->get_xmlNode(node, lasso_dump);
-
- {
- xmlNsPtr ns;
- ns = xmlNewNs(ret, (xmlChar*)LASSO_WSUTIL1_HREF, (xmlChar*)LASSO_WSUTIL1_PREFIX);
- xmlNewNsProp(ret, ns, (xmlChar*)"Id", (xmlChar*)LASSO_SOAP_BODY(node)->Id);
- }
-
- return ret;
-}
-
GType
lasso_soap_body_get_type()
{
diff --git a/lasso/xml/tools.c b/lasso/xml/tools.c
index 429b4526..00425043 100644
--- a/lasso/xml/tools.c
+++ b/lasso/xml/tools.c
@@ -2405,3 +2405,62 @@ lasso_make_signature_context_from_path_or_string(char *filename_or_buffer, const
}
return context;
}
+
+xmlNs *
+get_or_define_ns(xmlNode *xmlnode, const xmlChar *ns_uri, const xmlChar *advised_prefix) {
+ xmlNs *ns;
+ char prefix[20];
+ int i = 1;
+
+ ns = xmlSearchNsByHref(NULL, xmlnode, ns_uri);
+ if (ns)
+ return ns;
+ /* Try with the advised prefix */
+ if (advised_prefix) {
+ ns = xmlSearchNs(NULL, xmlnode, BAD_CAST prefix);
+ if (! ns) { /* If not taken, use it */
+ return xmlNewNs(xmlnode, ns_uri, BAD_CAST advised_prefix);
+ }
+ }
+ /* Create a prefix from scratch */
+ do {
+ sprintf(prefix, "ns%u", i);
+ i++;
+ ns = xmlSearchNs(NULL, xmlnode, BAD_CAST prefix);
+ } while (ns);
+ return xmlNewNs(xmlnode, ns_uri, BAD_CAST prefix);
+}
+
+
+void
+set_qname_attribute(xmlNode *node,
+ const xmlChar *attribute_ns_prefix,
+ const xmlChar *attribute_ns_href,
+ const xmlChar *attribute_name,
+ const xmlChar *prefix,
+ const xmlChar *href,
+ const xmlChar *name) {
+ xmlNs *type_ns;
+ xmlNs *xsi_ns;
+ xmlChar *value;
+
+ xsi_ns = get_or_define_ns(node, attribute_ns_href, attribute_ns_prefix);
+ type_ns = get_or_define_ns(node, href, prefix);
+ value = BAD_CAST g_strdup_printf("%s:%s", type_ns->prefix, name);
+ xmlSetNsProp(node, xsi_ns, attribute_name, value);
+ lasso_release_string(value);
+}
+
+void
+set_xsi_type(xmlNode *node,
+ const xmlChar *type_ns_prefix,
+ const xmlChar *type_ns_href,
+ const xmlChar *type_name) {
+ set_qname_attribute(node,
+ BAD_CAST LASSO_XSI_PREFIX,
+ BAD_CAST LASSO_XSI_HREF,
+ BAD_CAST "type",
+ type_ns_prefix,
+ type_ns_href,
+ type_name);
+}
diff --git a/lasso/xml/xml.c b/lasso/xml/xml.c
index 265236a8..bc8111b9 100644
--- a/lasso/xml/xml.c
+++ b/lasso/xml/xml.c
@@ -52,6 +52,7 @@
#include "../debug.h"
#include "./soap-1.1/soap_envelope.h"
#include "./soap-1.1/soap_body.h"
+#include "./misc_text_node.h"
#include "../lasso_config.h"
#ifdef LASSO_WSF_ENABLED
#include "./idwsf_strings.h"
@@ -72,7 +73,6 @@ static void lasso_node_traversal(LassoNode *node, void (*do_to_node)(LassoNode *
static LassoNode* lasso_node_new_from_xmlNode_with_type(xmlNode *xmlnode, char *typename);
static void lasso_node_remove_original_xmlnode(LassoNode *node, SnippetType type);
-static xmlNs * get_or_define_ns(xmlNode *xmlnode, xmlChar *ns_uri);
GHashTable *dst_services_by_href = NULL; /* ID-WSF 1 extra DST services, indexed on href */
GHashTable *dst_services_by_prefix = NULL; /* ID-WSF 1 extra DST services, indexed on prefix */
@@ -1191,7 +1191,6 @@ lasso_node_traversal(LassoNode *node, void (*do_to_node)(LassoNode *node, Snippe
type = snippet->type & 0xff;
switch (type) {
case SNIPPET_NODE:
- case SNIPPET_NAME_IDENTIFIER:
case SNIPPET_NODE_IN_CHILD:
lasso_node_traversal(*value, do_to_node, snippet->type);
break;
@@ -1206,6 +1205,8 @@ lasso_node_traversal(LassoNode *node, void (*do_to_node)(LassoNode *node, Snippe
}
}
break;
+ case SNIPPET_UNUSED1:
+ g_assert_not_reached();
default:
break;
}
@@ -1273,6 +1274,105 @@ cleanup:
return rc;
}
+static inline gboolean
+lasso_equal_namespace(xmlNs *t1, xmlNs *t2) {
+ return t1 && t2 && (t1 == t2 ||
+ lasso_strisequal((char*)t1->href, (char*)t2->href));
+}
+
+static void
+snippet_set_value(LassoNode *node, LassoNodeClass *class, struct XmlSnippet *snippet, xmlChar *content) {
+ void *value;
+ GType g_type = G_TYPE_FROM_CLASS(class);
+
+ /* If not offset, it means it is handled by an adhoc init_from_xml */
+ if (! snippet->offset && ! (snippet->type & SNIPPET_PRIVATE)) {
+ return;
+ }
+ value = SNIPPET_STRUCT_MEMBER_P(node, g_type, snippet);
+ if (snippet->type & SNIPPET_INTEGER) {
+ int val = strtol((char*)content, NULL, 10);
+ if (((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE)
+ || errno == EINVAL || val < 0) {
+ if (snippet->type & SNIPPET_OPTIONAL_NEG) {
+ val = -1;
+ } else {
+ val = 0;
+ }
+ }
+ (*(int*)value) = val;
+ } else if (snippet->type & SNIPPET_BOOLEAN) {
+ int val = 0;
+ if (strcmp((char*)content, "true") == 0) {
+ val = 1;
+ } else if (strcmp((char*)content, "1") == 0) {
+ val = 1;
+ }
+ (*(int*)value) = val;
+ } else {
+ lasso_assign_string((*(char**)value), (char*)content);
+ if (lasso_flag_memory_debug == TRUE) {
+ fprintf(stderr, " setting prop %s/%s to value %p: %s\n",
+ G_OBJECT_TYPE_NAME(node), snippet->name, *(void**)value, (char*)content);
+ }
+ }
+}
+
+gboolean
+next_node_snippet(GSList **class_iter_p, struct XmlSnippet **snippet_p)
+{
+ while (*class_iter_p) {
+ if (*snippet_p) {
+ if ((*snippet_p)->name) {
+ SnippetType type = (*snippet_p)->type;
+ /* special case for ArtifactResponse */
+ if (type & SNIPPET_ANY && (type & 0xff) == SNIPPET_NODE)
+ return TRUE;
+ if (! (type & SNIPPET_ANY) && (*snippet_p)->name[0] != '\0') {
+ switch (type & 0xff) {
+ case SNIPPET_NODE:
+ case SNIPPET_NODE_IN_CHILD:
+ case SNIPPET_LIST_XMLNODES:
+ case SNIPPET_LIST_CONTENT:
+ case SNIPPET_LIST_NODES:
+ case SNIPPET_EXTENSION:
+ case SNIPPET_XMLNODE:
+ case SNIPPET_CONTENT:
+ case SNIPPET_SIGNATURE:
+ return TRUE;
+ default:
+ break;
+ }
+ }
+ ++*snippet_p;
+ } else {
+ *class_iter_p = g_slist_next(*class_iter_p);
+ *snippet_p = NULL;
+ }
+ } else {
+ *snippet_p = ((LassoNodeClass*)(*class_iter_p)->data)
+ ->node_data->snippets;
+ }
+ }
+ return FALSE;
+}
+
+static inline gboolean
+is_snippet_type(struct XmlSnippet *snippet, SnippetType simple_type) {
+ return (snippet->type & 0xff) == simple_type;
+}
+
+static inline gboolean
+node_match_snippet(xmlNode *parent, xmlNode *node, struct XmlSnippet *snippet)
+{
+ /* special case of ArtifactResponse */
+ if (snippet->type & SNIPPET_ANY)
+ return TRUE;
+ return (lasso_strisequal(snippet->name, (char*)node->name)
+ && ((!snippet->ns_uri && lasso_equal_namespace(parent->ns, node->ns)) ||
+ (node->ns && lasso_strisequal((char*)node->ns->href, snippet->ns_uri))));
+}
+
/** FIXME: return a real error code */
static int
lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
@@ -1287,269 +1387,301 @@ lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
GType g_type_collect_namespaces, g_type_any, g_type_any_attribute;
struct XmlSnippet *snippet_collect_namespaces = NULL;
struct XmlSnippet *snippet_signature = NULL;
- GSList *unknown_nodes = NULL;
- GSList *known_attributes = NULL;
gboolean keep_xmlnode = FALSE;
+ GSList *class_list = NULL;
+ GSList *class_iter = NULL;
+ xmlAttr *attr = NULL;
+ GType g_type = 0;
+ LassoNodeClass *node_class;
- class = LASSO_NODE_GET_CLASS(node);
-
- /* What do you want me to initialize ? */
if (! xmlnode)
return 1;
+ node_class = class = LASSO_NODE_GET_CLASS(node);
/* No node_data no initialization possible */
if (! class->node_data) {
- message(G_LOG_LEVEL_WARNING, "Class %s has no node_data so no initialization is possible", G_OBJECT_CLASS_NAME(class));
+ message(G_LOG_LEVEL_WARNING, "Class %s has no node_data so no initialization "
+ "is possible", G_OBJECT_CLASS_NAME(class));
return 0;
}
- if (lasso_flag_memory_debug == TRUE) {
- fprintf(stderr, "Initializing %s (at %p)\n", G_OBJECT_TYPE_NAME(node), node);
- }
-
- while (class && LASSO_IS_NODE_CLASS(class) && class->node_data) {
- GType g_type = G_TYPE_FROM_CLASS(class);
+ /* Collect special snippets like SNIPPET_COLLECT_NAMESPACES, SNIPPET_ANY, SNIPPET_ATTRIBUTE
+ * or SNIPPET_SIGNATURE, and initialize class_list in reverse. */
+ while (class && LASSO_IS_NODE_CLASS(class)) {
+ if (class->node_data) {
+ GType g_type = G_TYPE_FROM_CLASS(class);
+ keep_xmlnode |= class->node_data->keep_xmlnode;
+ if (class->node_data->snippets)
+ class_list = g_slist_prepend(class_list, class);
+ for (snippet = class->node_data->snippets; snippet && snippet->name; snippet++) {
+ type = snippet->type & 0xff;
- lasso_trace(" initializing %s\n", G_OBJECT_CLASS_NAME(class));
-
- /* reduce keep_xmlnode flags */
- keep_xmlnode |= class->node_data->keep_xmlnode;
-
- for (t = xmlnode->children; t; t = t->next) {
- if (t->type == XML_TEXT_NODE) {
- for (snippet = class->node_data->snippets;
- snippet && snippet->name; snippet++) {
- GList **location = NULL;
-
- type = snippet->type & 0xff;
- value = SNIPPET_STRUCT_MEMBER_P(node, g_type, snippet);
-
- if (type == SNIPPET_LIST_XMLNODES) {
- location = value;
- *location = g_list_append(
- *location, xmlCopyNode(t, 1));
- trace_snippet(" adding xmlNode %p", g_list_last(*location)->data);
- } else if (type == SNIPPET_LIST_NODES &&
- snippet->type & SNIPPET_ALLOW_TEXT) {
- LassoNode *text_node;
- text_node = lasso_node_new_from_xmlNode_with_type(t,
- "LassoMiscTextNode");
- location = value;
- *location = g_list_append(*location, text_node);
- trace_snippet(" adding LassoMiscTextNode %p", text_node);
+ if (snippet->name && snippet->name[0] == '\0' && type ==
+ SNIPPET_COLLECT_NAMESPACES) {
+ snippet_collect_namespaces = snippet;
+ g_type_collect_namespaces = g_type;
+ } else if (type == SNIPPET_SIGNATURE) {
+ snippet_signature = snippet;
+ } else if (type == SNIPPET_ATTRIBUTE && snippet->type & SNIPPET_ANY) {
+ g_type_any_attribute = g_type;
+ snippet_any_attribute = snippet;
+ } else if (type == SNIPPET_TEXT_CHILD) {
+ xmlChar *tmp = xmlNodeGetContent(xmlnode);
+ snippet_set_value(node, class, snippet, tmp);
+ lasso_release_xml_string(tmp);
+ } else if (type != SNIPPET_ATTRIBUTE && type != SNIPPET_NODE && snippet->type & SNIPPET_ANY) {
+ if (! snippet_any) {
+ g_type_any = g_type;
+ snippet_any = snippet;
+ } else {
+ critical("Two any node snippet for class %s",
+ g_type_name(G_TYPE_FROM_INSTANCE(node)));
}
- continue;
}
- continue;
}
+ }
+ class = g_type_class_peek_parent(class);
+ }
- if (t->type != XML_ELEMENT_NODE)
+ /* If any class asked for keeping the xmlNode, keep it around */
+ if (keep_xmlnode) {
+ lasso_node_set_original_xmlnode(node, xmlnode);
+ }
+
+ /** Collect attributes */
+ for (attr = xmlnode->properties; attr; attr = attr->next) {
+ xmlChar *content;
+ content = xmlNodeGetContent((xmlNode*)attr);
+ int ok = 0;
+
+ /* Skip xsi:type if it was used to find the node class */
+ if (attr->ns && lasso_strisequal((char*)attr->name, "type") &&
+ lasso_strisequal((char*)attr->ns->href, LASSO_XSI_HREF)) {
+ char *colon = strchr((char*)content, ':');
+ xmlNs *ns;
+ *colon = '\0';
+ ns = xmlSearchNs(NULL, xmlnode, content);
+ *colon = ':';
+ if (ns && lasso_strisequal((char*)ns->href, (char*)node_class->node_data->ns->href)
+ && lasso_strisequal(&colon[1], node_class->node_data->node_name)) {
+ lasso_release_xml_string(content);
continue;
+ }
+ }
+ for (class_iter = class_list; class_iter; class_iter = class_iter->next) {
+ class = class_iter->data;
for (snippet = class->node_data->snippets;
snippet && snippet->name; snippet++) {
- void *tmp = NULL;
type = snippet->type & 0xff;
- value = SNIPPET_STRUCT_MEMBER_P(node, g_type, snippet);
-
- if ((snippet->type & SNIPPET_ANY) && type != SNIPPET_ATTRIBUTE) {
- g_type_any = g_type;
- snippet_any = snippet;
- }
-
- if (strcmp((char*)t->name, snippet->name) != 0 && snippet->name[0])
+ /* assign attribute content if attribute has the same name as the
+ * snippet and:
+ * - the snippet and the attribute have no namespace
+ * - the snippet has no namespace but the attribute has the same
+ * namespace as the node
+ * - the snippet and the node have a namespace, which are equal.
+ */
+ if (type != SNIPPET_ATTRIBUTE)
continue;
-
- if (type == SNIPPET_NODE) {
- tmp = lasso_node_new_from_xmlNode_with_type(t,
- snippet->class_name);
- } else if (type == SNIPPET_NODE_IN_CHILD) {
- xmlNode *t2 = t->children;
- while (t2 && t2->type != XML_ELEMENT_NODE)
- t2 = t2->next;
- if (t2) {
- tmp = lasso_node_new_from_xmlNode_with_type(t2,
- snippet->class_name);
- }
- } else if (type == SNIPPET_CONTENT) {
- tmp = xmlNodeGetContent(t);
- } else if (type == SNIPPET_NAME_IDENTIFIER) {
- tmp = lasso_saml_name_identifier_new_from_xmlNode(t);
- } else if (type == SNIPPET_LIST_NODES) {
- GList **location = value;
- LassoNode *n;
- n = lasso_node_new_from_xmlNode_with_type(t,
- snippet->class_name);
- if (n == NULL && snippet_any == snippet) {
- /* unknown, can be text or node -> make a
- * LassoMiscTextNode */
- n = lasso_node_new_from_xmlNode_with_type(t,
- "LassoMiscTextNode");
- }
- if (n && snippet->type & SNIPPET_KEEP_XMLNODE &&
- ! LASSO_NODE_GET_CLASS(n)->node_data->keep_xmlnode) {
- lasso_node_set_original_xmlnode(n, t);
- }
-
- if (n) {
- *location = g_list_append(*location, n);
- trace_snippet(" adding %p of type %s(%s) to ",
- n, G_OBJECT_TYPE_NAME(n),
- snippet->class_name);
- } else {
- /* failed to do sth with */
- message(G_LOG_LEVEL_WARNING,
- "Failed to do sth with %s",
- t->name);
- }
- } else if (type == SNIPPET_LIST_CONTENT) {
- GList **location = value;
- xmlChar *s = xmlNodeGetContent(t);
- lasso_list_add_string(*location, (char*)s);
- trace_snippet(" adding text %s as content to ", s);
- lasso_release_xml_string(s);
- } else if (type == SNIPPET_EXTENSION ||
- type == SNIPPET_LIST_XMLNODES) {
- GList **location = value;
- *location = g_list_append(*location, xmlCopyNode(t, 1));
- trace_snippet(" adding xmlNode %p to ", g_list_last(*location)->data);
- } else if (type == SNIPPET_XMLNODE) {
- tmp = xmlCopyNode(t, 1);
- } else if (type == SNIPPET_COLLECT_NAMESPACES) {
- /* Collect namespaces on the children t */
- _lasso_node_collect_namespaces(value, t);
+ if (! lasso_strisequal((char*)attr->name, (char*)snippet->name))
+ continue;
+ if (attr->ns) {
+ gboolean same_namespace, given_namespace;
+
+ same_namespace = lasso_equal_namespace(attr->ns,
+ xmlnode->ns) && ! snippet->ns_uri;
+ given_namespace = snippet->ns_uri &&
+ lasso_strisequal((char*)attr->ns->href,
+ snippet->ns_uri);
+ if (! same_namespace && ! given_namespace)
+ break;
}
+ snippet_set_value(node, class, snippet, content);
+ ok = 1;
+ break;
+ }
+ }
+ if (! ok && attr->ns && snippet_any_attribute) {
+ GHashTable **any_attribute;
+ gchar *key;
- if (tmp == NULL)
- break;
+ any_attribute = SNIPPET_STRUCT_MEMBER_P(node, g_type_any_attribute,
+ snippet_any_attribute);
+ if (*any_attribute == NULL) {
+ *any_attribute = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, g_free);
+ }
+ if (lasso_equal_namespace(attr->ns, xmlnode->ns)) {
+ key = g_strdup((char*)attr->name);
+ } else {
+ key = g_strdup_printf("{%s}%s", attr->ns->href, attr->name);
+ }
+ g_hash_table_insert(*any_attribute, key, g_strdup((char*)content));
+ lasso_release_xml_string(content);
+ } else if (! ok) {
+ warning("lasso_node_impl_init_from_xml: Unexpected attribute: {%s}%s = %s",
+ attr->ns ? attr->ns->href : NULL, attr->name, content);
+ }
+ lasso_release_xml_string(content);
+ }
+
+ /* Collect children nodes in reverse order of class parents (older parent first), skip non
+ * node and ANY snippets) */
+ class_iter = class_list;
+ snippet = ((LassoNodeClass*)class_iter->data)->node_data->snippets;
+ next_node_snippet(&class_iter, &snippet);
+ for (t = xmlnode->children; t && class_iter && snippet; t = t->next) {
+ /* Only collect text node if:
+ * - there is a LIST_XMLNODES any snippet
+ * - there is a LIST_NODES any snippet with the ALLOW_TEXT modifier
+ */
+ if (t->type == XML_TEXT_NODE && snippet_any &&
+ (is_snippet_type(snippet_any, SNIPPET_LIST_XMLNODES)
+ || (is_snippet_type(snippet_any, SNIPPET_LIST_NODES) &&
+ (snippet_any->type & SNIPPET_ALLOW_TEXT)))) {
+ GList **location = SNIPPET_STRUCT_MEMBER_P(node, g_type_any, snippet_any);
+ if (is_snippet_type(snippet_any, SNIPPET_LIST_XMLNODES)) {
+ lasso_list_add_xml_node(*location, t);
+ } else {
+ lasso_list_add_new_gobject(*location,
+ lasso_node_new_from_xmlNode_with_type(t,
+ "LassoMiscTextNode"));
+ }
+ } else if (t->type == XML_COMMENT_NODE || t->type == XML_PI_NODE || t->type == XML_TEXT_NODE) {
+ /* ignore comments */
+ continue;
+ } else if (t->type == XML_ELEMENT_NODE) {
+ LassoNode *subnode = NULL;
+ xmlNode *first_child = NULL;
+ GList **list = NULL;
+ xmlChar *content = NULL;
+
+ /* Find a matching snippet */
+ while (class_iter && ! node_match_snippet(xmlnode, t, snippet)) {
+ snippet++;
+ next_node_snippet(&class_iter, &snippet);
+ }
+ if (! class_iter) {
+ /* If we cannot find one, terminate here. */
+ break;
+ }
+ class = class_iter->data;
+ g_type = G_TYPE_FROM_CLASS(class);
+ value = SNIPPET_STRUCT_MEMBER_P(node, g_type, snippet);
+ list = value;
- if (type == SNIPPET_XMLNODE || type == SNIPPET_NODE || type == SNIPPET_NODE_IN_CHILD || type ==
- SNIPPET_NAME_IDENTIFIER) {
- if (snippet->type & SNIPPET_KEEP_XMLNODE && !
- LASSO_NODE_GET_CLASS(tmp)->node_data->keep_xmlnode)
- {
- lasso_trace(" setting original xmlNode of %p (%s) to %p", tmp, G_OBJECT_TYPE_NAME(tmp), t)
- lasso_node_set_original_xmlnode(tmp, t);
- }
- if (type == SNIPPET_XMLNODE) {
- trace_snippet(" setting xmlNode %p as ", tmp);
- } else {
- trace_snippet(" setting %p of type %s (wanted %s) as ", tmp,
- G_OBJECT_TYPE_NAME(tmp),
+ if (snippet->offset || (snippet->type & SNIPPET_PRIVATE)) {
+ switch (snippet->type & 0xff) {
+ case SNIPPET_LIST_NODES:
+ case SNIPPET_NODE:
+ subnode = lasso_node_new_from_xmlNode_with_type(t,
snippet->class_name);
- }
- *(void**)value = tmp;
- tmp = NULL;
- } else if (snippet->type & SNIPPET_INTEGER) {
- int val = strtol(tmp, NULL, 10);
- if (((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE)
- || errno == EINVAL || val < 0) {
- if (snippet->type & SNIPPET_OPTIONAL_NEG) {
- val = -1;
+ if (is_snippet_type(snippet, SNIPPET_NODE)) {
+ lasso_assign_new_gobject(*(LassoNode**)value, subnode);
} else {
- val = 0;
+ lasso_list_add_new_gobject(*list, subnode);
}
- }
- (*(int*)value) = val;
- trace_snippet(" setting integer %i for ", val);
- xmlFree(tmp);
- tmp = NULL;
- } else if (snippet->type & SNIPPET_BOOLEAN) {
- int val = 0;
- if (strcmp((char*)tmp, "true") == 0) {
- val = 1;
- } else if (strcmp((char*)tmp, "1") == 0) {
- val = 1;
- }
- trace_snippet(" setting bool %s for ", val ? "TRUE" : "FALSE");
- (*(int*)value) = val;
- xmlFree(tmp);
- tmp = NULL;
- } else {
- lasso_release_string(*(char**)value);
- *(char**)value = g_strdup(tmp);
- trace_snippet(" setting text %s as value for ", (char*)tmp);
- if (lasso_flag_memory_debug == TRUE) {
- fprintf(stderr, " setting field %s/%s to value %p: %s\n", G_OBJECT_TYPE_NAME(node), snippet->name, *(void**)value, (char*)tmp);
- }
- lasso_release_xml_string((*(xmlChar**)&tmp));
- tmp = NULL;
- }
+ break;
+ case SNIPPET_NODE_IN_CHILD:
+ first_child = xmlSecGetNextElementNode(t->children);
+ if (first_child) {
+ subnode = lasso_node_new_from_xmlNode_with_type(first_child,
+ snippet->class_name);
+ lasso_assign_new_gobject(*(LassoNode**)value, subnode);
+ }
+ break;
+ case SNIPPET_XMLNODE:
+ lasso_assign_xml_node(*(xmlNode**)value, t);
+ break;
+ case SNIPPET_LIST_XMLNODES:
+ case SNIPPET_EXTENSION:
+ lasso_list_add_xml_node(*list, t);
+ break;
+ case SNIPPET_CONTENT:
+ case SNIPPET_LIST_CONTENT:
+ content = xmlNodeGetContent(t);
+ if (is_snippet_type(snippet, SNIPPET_CONTENT)) {
+ snippet_set_value(node, class, snippet, content);
+ } else { /* only list of string-like xsd:type supported */
+ lasso_list_add_string(*list, (char*)content);
+ }
+ lasso_release_xml_string(content);
+ break;
+ case SNIPPET_SIGNATURE:
+ /* We ignore it */
+ break;
+ default:
+ g_assert_not_reached();
- break;
+ }
}
- if ((snippet == NULL || snippet->name == NULL) && snippet_any) {
- if (g_slist_find(unknown_nodes, t) == NULL)
- unknown_nodes = g_slist_append(unknown_nodes, t);
- } else {
- unknown_nodes = g_slist_remove(unknown_nodes, t);
+ /* When creating a new LassoNode and option KEEP_XMLNODE is present,
+ * we attached the xmlNode to the LassoNode */
+ if (subnode && (snippet->type & SNIPPET_KEEP_XMLNODE)) {
+ lasso_node_set_original_xmlnode(subnode, t);
}
- }
-
- for (snippet = class->node_data->snippets; snippet && snippet->name; snippet++) {
- void *tmp = NULL;
- type = snippet->type & 0xff;
-
- value = SNIPPET_STRUCT_MEMBER_P(node, g_type, snippet);
- if (snippet->name && snippet->name[0] == '\0' && type ==
- SNIPPET_COLLECT_NAMESPACES) {
- snippet_collect_namespaces = snippet;
- g_type_collect_namespaces = g_type;
- }
-
- if (type == SNIPPET_SIGNATURE) {
- snippet_signature = snippet;
+ switch (snippet->type & 0xff) {
+ case SNIPPET_NODE:
+ case SNIPPET_NODE_IN_CHILD:
+ case SNIPPET_XMLNODE:
+ case SNIPPET_CONTENT:
+ case SNIPPET_SIGNATURE:
+ /* Only one node to read, advance ! */
+ ++snippet;
+ next_node_snippet(&class_iter, &snippet);
+ break;
+ default:
+ break;
}
-
- if (type == SNIPPET_ATTRIBUTE) {
- if (snippet->type & SNIPPET_ANY) {
- g_type_any_attribute = g_type;
- snippet_any_attribute = snippet;
- continue;
- }
- tmp = xmlGetProp(xmlnode, (xmlChar*)snippet->name);
- known_attributes = g_slist_append(known_attributes, snippet->name);
+ } else {
+ g_assert_not_reached();
+ }
+ }
+ if (t) { /* t is an ELEMENT that dont match any snippet, when taken in order */
+ if (snippet_any && is_snippet_type(snippet_any, SNIPPET_LIST_XMLNODES)) {
+ value = SNIPPET_STRUCT_MEMBER_P(node, g_type_any, snippet_any);
+ GList **list = value;
+ for (; t; t = t->next) {
+ lasso_list_add_xml_node(*list, t);
}
- if (type == SNIPPET_TEXT_CHILD)
- tmp = xmlNodeGetContent(xmlnode);
- if (tmp == NULL)
- continue;
-
- if (snippet->type & SNIPPET_INTEGER) {
- int val = strtol(tmp, NULL, 10);
- if (((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE)
- || errno == EINVAL || val < 0) {
- if (snippet->type & SNIPPET_OPTIONAL_NEG) {
- val = -1;
- } else {
- val = 0;
+ } else if (snippet_any && is_snippet_type(snippet_any, SNIPPET_LIST_NODES)) {
+ value = SNIPPET_STRUCT_MEMBER_P(node, g_type_any, snippet_any);
+ GList **list = value;
+ for (; t; t = t->next) {
+ LassoNode *subnode = NULL;
+
+ if (t->type == XML_TEXT_NODE && (snippet_any->type &
+ SNIPPET_ALLOW_TEXT)) {
+ lasso_list_add_new_gobject(*list,
+ lasso_node_new_from_xmlNode_with_type(t,
+ "LassoMiscTextNode"));
+ } else if (t->type == XML_ELEMENT_NODE) {
+ subnode = lasso_node_new_from_xmlNode_with_type(t,
+ snippet_any->class_name);
+ if (subnode && (snippet_any->type & SNIPPET_KEEP_XMLNODE)) {
+ lasso_node_set_original_xmlnode(subnode, t);
}
+ if (! subnode) {
+ subnode = (LassoNode*)
+ lasso_misc_text_node_new_with_xml_node(t);
+ }
+ lasso_list_add_new_gobject(*list, subnode);
}
- (*(int*)value) = val;
- } else if (snippet->type & SNIPPET_BOOLEAN) {
- int val = 0;
- if (strcmp((char*)tmp, "true") == 0) {
- val = 1;
- } else if (strcmp((char*)tmp, "1") == 0) {
- val = 1;
- }
- (*(int*)value) = val;
- } else {
- lasso_assign_string((*(char**)value), tmp);
- if (lasso_flag_memory_debug == TRUE) {
- fprintf(stderr, " setting prop %s/%s to value %p: %s\n",
- G_OBJECT_TYPE_NAME(node), snippet->name, *(void**)value, (char*)tmp);
+ }
+ } else if (snippet_any) {
+ g_assert_not_reached();
+ } else {
+ for (; t; t = t->next) {
+ if (t->type == XML_ELEMENT_NODE) {
+ critical("lasso_node_impl_init_from_xml: Cannot match "
+ "element {%s}%s with a snippet of "
+ "class %s",
+ t->ns ? t->ns->href : NULL, t->name,
+ g_type_name(G_TYPE_FROM_INSTANCE(node)));
+ return 1;
}
}
- xmlFree(tmp);
}
-
- class = g_type_class_peek_parent(class);
- }
-
- /* If any parent asked for keeping the current xmlnode, keep it around */
- if (keep_xmlnode) {
- lasso_node_set_original_xmlnode(node, xmlnode);
}
/* Collect namespaces on the current node */
@@ -1594,62 +1726,13 @@ lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
signature_context.signature_key = lasso_xmlsec_load_private_key((char*) private_key,
(char*) private_key_password, method, (char*) certificate);
lasso_node_set_signature(node, signature_context);
+ break;
}
lasso_release_xml_string(private_key);
lasso_release_xml_string(private_key_password);
lasso_release_xml_string(certificate);
}
- /* Collect other children */
- if (unknown_nodes && snippet_any) {
- xmlNode *t = unknown_nodes->data;
- void *tmp;
- value = SNIPPET_STRUCT_MEMBER_P(node, g_type_any, snippet_any);
- tmp = lasso_node_new_from_xmlNode_with_type(t, snippet_any->class_name);
- (*(char**)value) = tmp;
- }
-
- /* Collect other attributes */
- if (snippet_any_attribute) {
- GHashTable **any_attribute;
- GSList *tmp_attr;
- xmlAttr *node_attr;
-
-
- any_attribute = SNIPPET_STRUCT_MEMBER_P(node, g_type_any_attribute, snippet_any_attribute);
- if (*any_attribute == NULL) {
- *any_attribute = g_hash_table_new_full(
- g_str_hash, g_str_equal, g_free, g_free);
- }
-
- for (node_attr = xmlnode->properties; node_attr; node_attr = node_attr->next) {
- xmlChar *attr_name = (xmlChar*)node_attr->name;
- gboolean known_attr = FALSE;
- for (tmp_attr = known_attributes; tmp_attr;
- tmp_attr = g_slist_next(tmp_attr)) {
- if (strcmp(tmp_attr->data, (char*)attr_name) == 0) {
- known_attr = TRUE;
- break;
- }
- }
- if (known_attr == FALSE) {
- xmlChar *tmp = xmlGetProp(xmlnode, attr_name);
- g_hash_table_insert(*any_attribute,
- g_strdup((char*)attr_name), g_strdup((char*)tmp));
- xmlFree(tmp);
- }
- }
-
- }
-
- if (unknown_nodes) {
- g_slist_free(unknown_nodes);
- }
-
- if (known_attributes) {
- g_slist_free(known_attributes);
- }
-
return 0;
}
#undef trace_snippet
@@ -1711,40 +1794,45 @@ lasso_node_impl_get_xmlNode(LassoNode *node, gboolean lasso_dump)
LassoNodeClass *class = LASSO_NODE_GET_CLASS(node);
LassoNodeClass *version_class = NULL;
xmlNode *xmlnode;
- xmlNs *ns;
- GList *list_ns = NULL, *list_classes = NULL, *t;
+ xmlNs *ns = NULL;
+ GSList *list_classes = NULL, *iter_classes = NULL;
LassoNode *value_node;
struct XmlSnippet *version_snippet;
struct _CustomElement *custom_element;
- LassoNodeClass *node_data_class = class;
+ LassoNodeClass *xsi_sub_type_data_class = NULL;
+ LassoNodeClass *node_name_class = class;
- while (node_data_class && node_data_class->node_data != NULL && node_data_class->node_data->node_name == NULL) {
- node_data_class = g_type_class_peek_parent(node_data_class);
+ while (node_name_class->node_data->xsi_sub_type) {
+ node_name_class= g_type_class_peek_parent(node_name_class);
}
- if (! node_data_class || node_data_class->node_data == NULL ||
- node_data_class->node_data->node_name == NULL)
- return NULL;
+ if (node_name_class != class) {
+ xsi_sub_type_data_class = class;
+ }
+ g_assert(node_name_class && node_name_class->node_data &&
+ node_name_class->node_data->node_name);
- xmlnode = xmlNewNode(NULL, (xmlChar*)node_data_class->node_data->node_name);
- custom_element = _lasso_node_get_custom_element(node);
- /* collect namespaces in the order of ancestor classes, nearer first */
- while (class && LASSO_IS_NODE_CLASS(class) && class->node_data) {
- if (class->node_data->ns && (! custom_element || ! custom_element->href || class != LASSO_NODE_GET_CLASS(node)))
- list_ns = g_list_append(list_ns, class->node_data->ns);
- list_classes = g_list_append(list_classes, class);
- class = g_type_class_peek_parent(class);
+ /* Create node in its namespace */
+ xmlnode = xmlNewNode(NULL, (xmlChar*)node_name_class->node_data->node_name);
+ if (node_name_class->node_data->ns) {
+ ns = get_or_define_ns(xmlnode, node_name_class->node_data->ns->href,
+ node_name_class->node_data->ns->prefix);
+ xmlSetNs(xmlnode, ns);
+ }
+ /* If subtype, set an xsi:type attribute */
+ if (xsi_sub_type_data_class) {
+ set_xsi_type(xmlnode,
+ xsi_sub_type_data_class->node_data->ns->prefix,
+ xsi_sub_type_data_class->node_data->ns->href,
+ BAD_CAST xsi_sub_type_data_class->node_data->node_name);
}
+ custom_element = _lasso_node_get_custom_element(node);
- /* create the namespaces */
- t = g_list_first(list_ns);
- while (t) {
- ns = t->data;
- xmlNewNs(xmlnode, ns->href, ns->prefix);
- t = g_list_next(t);
+ /* collect all classes in reverse order */
+ while (class && LASSO_IS_NODE_CLASS(class)) {
+ if (class->node_data && class->node_data->snippets)
+ list_classes = g_slist_prepend(list_classes, class);
+ class = g_type_class_peek_parent(class);
}
- lasso_release_list(list_ns);
- /* first NS defined is the namespace of the element */
- xmlSetNs(xmlnode, xmlnode->nsDef);
/* set a custom namespace if one is found */
if (custom_element != NULL) {
@@ -1785,14 +1873,13 @@ lasso_node_impl_get_xmlNode(LassoNode *node, gboolean lasso_dump)
}
- t = g_list_last(list_classes);
- while (t) {
- class = t->data;
- lasso_node_build_xmlNode_from_snippets(node, (LassoNodeClass*)class, xmlnode,
- class->node_data->snippets, lasso_dump);
- t = g_list_previous(t);
+ for (iter_classes = list_classes; iter_classes; iter_classes = g_slist_next(iter_classes)) {
+ class = iter_classes->data;
+ lasso_node_build_xmlNode_from_snippets(node,
+ (LassoNodeClass*)class, xmlnode,
+ class->node_data->snippets,
+ lasso_dump);
}
- lasso_release_list(list_classes);
xmlCleanNs(xmlnode);
@@ -1819,6 +1906,7 @@ lasso_node_impl_get_xmlNode(LassoNode *node, gboolean lasso_dump)
}
}
+ g_slist_free(list_classes);
return xmlnode;
}
@@ -1846,6 +1934,8 @@ lasso_node_dispose(GObject *object)
void **value = SNIPPET_STRUCT_MEMBER_P(object, G_TYPE_FROM_CLASS(class), snippet);
type = snippet->type & 0xff;
+ if (! snippet->offset && ! (snippet->type & SNIPPET_PRIVATE))
+ continue;
if (snippet->type & SNIPPET_BOOLEAN)
continue;
if (snippet->type & SNIPPET_INTEGER)
@@ -1860,7 +1950,6 @@ lasso_node_dispose(GObject *object)
}
switch (type) {
case SNIPPET_NODE:
- case SNIPPET_NAME_IDENTIFIER:
case SNIPPET_NODE_IN_CHILD:
lasso_release_gobject(*value);
break;
@@ -2530,23 +2619,6 @@ lasso_node_class_set_ns(LassoNodeClass *klass, char *href, char *prefix)
klass->node_data->ns = xmlNewNs(NULL, (xmlChar*)href, (xmlChar*)prefix);
}
-static xmlNs *
-get_or_define_ns(xmlNode *xmlnode, xmlChar *ns_uri) {
- xmlNs *ns;
- char prefix[10];
- int i = 1;
-
- ns = xmlSearchNsByHref(NULL, xmlnode, ns_uri);
- if (ns)
- return ns;
- do {
- sprintf(prefix, "ns%u", i);
- i++;
- ns = xmlSearchNs(NULL, xmlnode, BAD_CAST prefix);
- } while (ns);
- return xmlNewNs(xmlnode, ns_uri, BAD_CAST prefix);
-}
-
static void
snippet_dump_any(gchar *key, gchar *value, xmlNode *xmlnode)
{
@@ -2564,14 +2636,33 @@ snippet_dump_any(gchar *key, gchar *value, xmlNode *xmlnode)
return;
}
ns_uri = g_strndup(key+1, end-(key+1));
- ns = get_or_define_ns(xmlnode, BAD_CAST ns_uri);
- xmlSetNsProp(xmlnode, ns, BAD_CAST key, BAD_CAST value);
+ ns = get_or_define_ns(xmlnode, BAD_CAST ns_uri, NULL);
+ xmlSetNsProp(xmlnode, ns, BAD_CAST &end[1], BAD_CAST value);
} else {
xmlSetProp(xmlnode, BAD_CAST key, BAD_CAST value);
}
}
static void
+apply_snippet_ns(struct XmlSnippet *snippet, xmlNode *xmlnode)
+{
+ xmlNs *ns;
+
+ if (! xmlnode)
+ return;
+ if (snippet->ns_uri) {
+ if (! xmlnode->ns || !lasso_strisequal((char*)xmlnode->ns->href, (char*)snippet->ns_uri)) {
+ ns = get_or_define_ns(xmlnode, BAD_CAST snippet->ns_uri, BAD_CAST snippet->ns_name);
+ xmlSetNs(xmlnode, ns);
+ }
+ /* If not a any snippet, apply given Name, what about xsi:type ? */
+ }
+ if (! (snippet->type & SNIPPET_ANY) && ! lasso_strisempty(snippet->name) &&
+ lasso_strisnotequal((char*)xmlnode->name, (char*)snippet->name))
+ xmlNodeSetName(xmlnode, BAD_CAST snippet->name);
+}
+
+static void
lasso_node_build_xmlNode_from_snippets(LassoNode *node, LassoNodeClass *class, xmlNode *xmlnode,
struct XmlSnippet *snippets, gboolean lasso_dump)
{
@@ -2579,17 +2670,21 @@ lasso_node_build_xmlNode_from_snippets(LassoNode *node, LassoNodeClass *class, x
SnippetType type;
GType g_type;
xmlNode *t;
- xmlNs *xmlns;
GList *elem;
struct XmlSnippet *snippet_any_attribute = NULL;
g_type = G_TYPE_FROM_CLASS(class);
for (snippet = snippets; snippet && snippet->name; snippet++) {
- void *value = SNIPPET_STRUCT_MEMBER(void *, node, g_type, snippet);
- char *str = value;
- type = snippet->type & 0xff;
+ void *value;
+ char *str;
+ if (! snippet->offset && ! (snippet->type & SNIPPET_PRIVATE)) {
+ continue;
+ }
+ type = snippet->type & 0xff;
+ value = SNIPPET_STRUCT_MEMBER(void *, node, g_type, snippet);
+ str = value;
if (lasso_dump == FALSE && snippet->type & SNIPPET_LASSO_DUMP)
continue;
@@ -2629,23 +2724,13 @@ lasso_node_build_xmlNode_from_snippets(LassoNode *node, LassoNodeClass *class, x
{
xmlNode *t2;
t2 = lasso_node_get_xmlNode(LASSO_NODE(value), lasso_dump);
- if (snippet->name && ! (snippet->type & SNIPPET_ANY)) {
- xmlNodeSetName(t2, (xmlChar*)snippet->name);
- }
+ apply_snippet_ns(snippet, t2);
xmlAddChild(xmlnode, t2);
} break;
case SNIPPET_CONTENT:
xmlNewTextChild(xmlnode, NULL,
(xmlChar*)snippet->name, (xmlChar*)str);
break;
- case SNIPPET_NAME_IDENTIFIER:
- xmlns = xmlNewNs(NULL, (xmlChar*)LASSO_LIB_HREF,
- (xmlChar*)LASSO_LIB_PREFIX);
- t = xmlAddChild(xmlnode, lasso_node_get_xmlNode(
- LASSO_NODE(value), lasso_dump));
- xmlNodeSetName(t, (xmlChar*)snippet->name);
- xmlSetNs(t, xmlns);
- break;
case SNIPPET_NODE_IN_CHILD:
t = xmlNewTextChild(xmlnode, NULL, (xmlChar*)snippet->name, NULL);
xmlAddChild(t, lasso_node_get_xmlNode(
@@ -2657,10 +2742,7 @@ lasso_node_build_xmlNode_from_snippets(LassoNode *node, LassoNodeClass *class, x
xmlNode *subnode = lasso_node_get_xmlNode(
LASSO_NODE(elem->data), lasso_dump);
if (subnode) {
- if (snippet->name && snippet->name[0]) {
- xmlNodeSetName(subnode,
- (xmlChar*)snippet->name);
- }
+ apply_snippet_ns(snippet, subnode);
xmlAddChild(xmlnode, subnode);
}
elem = g_list_next(elem);
@@ -2671,15 +2753,11 @@ lasso_node_build_xmlNode_from_snippets(LassoNode *node, LassoNodeClass *class, x
* no attrs, just content) */
elem = (GList *)value;
while (elem) {
- xmlNs *content_ns = NULL;
- if (snippet->ns_name) {
- content_ns = xmlNewNs(xmlnode,
- (const xmlChar*)snippet->ns_uri,
- (const xmlChar*)snippet->ns_name);
- }
- xmlNewTextChild(xmlnode, content_ns,
+ xmlNode *subnode;
+ subnode = xmlNewTextChild(xmlnode, NULL,
(xmlChar*)snippet->name,
(xmlChar*)(elem->data));
+ apply_snippet_ns(snippet, subnode);
elem = g_list_next(elem);
}
break;
@@ -2708,6 +2786,7 @@ lasso_node_build_xmlNode_from_snippets(LassoNode *node, LassoNodeClass *class, x
case SNIPPET_ANY:
case SNIPPET_KEEP_XMLNODE:
case SNIPPET_PRIVATE:
+ case SNIPPET_UNUSED1:
g_assert_not_reached();
}
if (snippet->type & SNIPPET_INTEGER)
@@ -2769,11 +2848,17 @@ lasso_node_add_signature_template(LassoNode *node, xmlNode *xmlnode,
transform_id, NULL);
xmlAddChild(xmlnode, signature);
- id = SNIPPET_STRUCT_MEMBER(char *, node, G_TYPE_FROM_CLASS(klass), snippet_signature);
- uri = g_strdup_printf("#%s", id);
- reference = xmlSecTmplSignatureAddReference(signature,
- xmlSecTransformSha1Id, NULL, (xmlChar*)uri, NULL);
- lasso_release(uri);
+ /* Normally the signature is son of the signed node, which holds an Id attribute, but in
+ * other cases, set snippet->offset to 0 and use xmlSecTmpSignatureAddReference from another
+ * node get_xmlNode virtual method to add the needed reference.
+ */
+ if (snippet_signature->offset) {
+ id = SNIPPET_STRUCT_MEMBER(char *, node, G_TYPE_FROM_CLASS(klass), snippet_signature);
+ uri = g_strdup_printf("#%s", id);
+ reference = xmlSecTmplSignatureAddReference(signature,
+ xmlSecTransformSha1Id, NULL, (xmlChar*)uri, NULL);
+ lasso_release(uri);
+ }
/* add enveloped transform */
xmlSecTmplReferenceAddTransform(reference, xmlSecTransformEnvelopedId);