1
/* $Id: xml.c,v 1.83 2004/09/06 17:49:19 fpeters Exp $
3
* Lasso - A free implementation of the Liberty Alliance specifications.
5
* Copyright (C) 2004 Entr'ouvert
6
* http://lasso.entrouvert.org
8
* Authors: Nicolas Clapies <nclapies@entrouvert.com>
9
* Valery Febvre <vfebvre@easter-eggs.com>
11
* This program is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; either version 2 of the License, or
14
* (at your option) any later version.
16
* This program is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU General Public License for more details.
21
* You should have received a copy of the GNU General Public License
22
* along with this program; if not, write to the Free Software
23
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
#include <glib/gprintf.h>
30
#include <xmlsec/base64.h>
31
#include <xmlsec/xmltree.h>
32
#include <xmlsec/xmldsig.h>
33
#include <xmlsec/templates.h>
34
#include <xmlsec/crypto.h>
36
#include <lasso/xml/errors.h>
37
#include <lasso/xml/xml.h>
39
struct _LassoNodePrivate
41
gboolean dispose_has_run;
42
gboolean node_is_weak_ref;
46
static GObjectClass *parent_class = NULL;
48
/*****************************************************************************/
49
/* virtual public methods */
50
/*****************************************************************************/
52
static void lasso_node_impl_set_xmlNode(LassoNode *node, xmlNodePtr libxml_node);
58
* Build a copy of the node.
60
* Return value: a copy of the node
63
lasso_node_copy(LassoNode *node)
65
LassoNodeClass *class;
67
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
69
class = LASSO_NODE_GET_CLASS(node);
70
return class->copy(node);
76
* @encoding: the name of the encoding to use or NULL.
77
* @format: is formatting allowed
79
* Dumps @node. All datas in object are dumped in an XML format.
81
* Return value: a full XML dump of @node
84
lasso_node_dump(LassoNode *node,
85
const xmlChar *encoding,
88
LassoNodeClass *class;
89
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
91
class = LASSO_NODE_GET_CLASS(node);
92
return class->dump(node, encoding, format);
99
* Destroys the LassoNode.
102
lasso_node_destroy(LassoNode *node)
104
if (LASSO_IS_NODE(node)) {
105
LassoNodeClass *class = LASSO_NODE_GET_CLASS(node);
106
class->destroy(node);
114
* Exports the LassoNode.
116
* Return value: an XML dump of the LassoNode (UTF-8 encoding)
119
lasso_node_export(LassoNode *node)
121
LassoNodeClass *class;
122
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
124
class = LASSO_NODE_GET_CLASS(node);
125
return class->export(node);
129
* lasso_node_export_to_base64:
132
* Like lasso_node_export() method except that result is Base64 encoded.
134
* Return value: a Base64 encoded export of the LassoNode
137
lasso_node_export_to_base64(LassoNode *node)
139
LassoNodeClass *class;
140
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
142
class = LASSO_NODE_GET_CLASS(node);
143
return class->export_to_base64(node);
147
* lasso_node_export_to_query:
149
* @sign_method: the Signature transform method
150
* @private_key_file: a private key (may be NULL)
152
* URL-encodes and signes the LassoNode.
153
* If private_key_file is NULL, query won't be signed.
155
* Return value: URL-encoded and signed LassoNode
158
lasso_node_export_to_query(LassoNode *node,
159
lassoSignatureMethod sign_method,
160
const gchar *private_key_file)
162
LassoNodeClass *class;
163
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
165
class = LASSO_NODE_GET_CLASS(node);
166
return class->export_to_query(node, sign_method, private_key_file);
170
* lasso_node_export_to_soap:
173
* Like lasso_node_export() method except that result is SOAP enveloped.
175
* Return value: a SOAP enveloped export of the LassoNode
178
lasso_node_export_to_soap(LassoNode *node)
180
LassoNodeClass *class;
181
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
183
class = LASSO_NODE_GET_CLASS(node);
184
return class->export_to_soap(node);
188
* lasso_node_get_attr:
190
* @name: the attribute name
191
* @err: return location for an allocated GError, or NULL to ignore errors
193
* Gets an attribute associated with the node.
195
* Return value: the attribute or NULL if not found.
198
lasso_node_get_attr(LassoNode *node,
202
LassoNodeClass *class;
203
if (err != NULL && *err != NULL) {
204
g_set_error(err, g_quark_from_string("Lasso"),
205
LASSO_PARAM_ERROR_CHECK_FAILED,
206
lasso_strerror(LASSO_PARAM_ERROR_CHECK_FAILED));
207
g_return_val_if_fail (err == NULL || *err == NULL, NULL);
209
if (LASSO_IS_NODE(node) == FALSE) {
210
g_set_error(err, g_quark_from_string("Lasso"),
211
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ,
212
lasso_strerror(LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ));
213
g_return_val_if_fail(LASSO_IS_NODE(node), NULL);
215
/* don't check @name here, it's checked in impl method */
217
class = LASSO_NODE_GET_CLASS(node);
218
return class->get_attr(node, name, err);
222
* lasso_node_get_attr_value:
224
* @name: the attribute name
225
* @err: return location for an allocated GError, or NULL to ignore errors
227
* Gets the value of an attribute associated to a node.
229
* Return value: the attribute value or NULL if not found. It's up to the caller
230
* to free the memory with xmlFree().
233
lasso_node_get_attr_value(LassoNode *node,
237
LassoNodeClass *class;
238
if (err != NULL && *err != NULL) {
239
g_set_error(err, g_quark_from_string("Lasso"),
240
LASSO_PARAM_ERROR_CHECK_FAILED,
241
lasso_strerror(LASSO_PARAM_ERROR_CHECK_FAILED));
242
g_return_val_if_fail (err == NULL || *err == NULL, NULL);
244
if (LASSO_IS_NODE(node) == FALSE) {
245
g_set_error(err, g_quark_from_string("Lasso"),
246
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ,
247
lasso_strerror(LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ));
248
g_return_val_if_fail(LASSO_IS_NODE(node), NULL);
250
/* don't check @name here, it's checked in impl method */
252
class = LASSO_NODE_GET_CLASS(node);
253
return class->get_attr_value(node, name, err);
257
* lasso_node_get_attrs:
260
* Gets attributes associated with the node.
262
* Return value: an array of attributes or NULL if no attribute found.
265
lasso_node_get_attrs(LassoNode *node)
267
LassoNodeClass *class;
268
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
270
class = LASSO_NODE_GET_CLASS(node);
271
return class->get_attrs(node);
275
* lasso_node_get_child:
277
* @name: the child name
278
* @href: the namespace (may be NULL)
279
* @err: return location for an allocated GError, or NULL to ignore errors
281
* Gets child of node having given @name and namespace @href.
283
* Return value: a child node
286
lasso_node_get_child(LassoNode *node,
291
LassoNodeClass *class;
292
if (err != NULL && *err != NULL) {
293
g_set_error(err, g_quark_from_string("Lasso"),
294
LASSO_PARAM_ERROR_CHECK_FAILED,
295
lasso_strerror(LASSO_PARAM_ERROR_CHECK_FAILED));
296
g_return_val_if_fail (err == NULL || *err == NULL, NULL);
298
if (LASSO_IS_NODE(node) == FALSE) {
299
g_set_error(err, g_quark_from_string("Lasso"),
300
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ,
301
lasso_strerror(LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ));
302
g_return_val_if_fail(LASSO_IS_NODE(node), NULL);
304
/* don't check @name here, it's checked in impl method */
306
class = LASSO_NODE_GET_CLASS(node);
307
return class->get_child(node, name, href, err);
311
* lasso_node_get_child_content:
313
* @name: the child name
314
* @href: the namespace (may be NULL)
315
* @err: return location for an allocated GError, or NULL to ignore errors
317
* Gets child content of node having given @name and namespace @href.
319
* Return value: a new xmlChar * or NULL if no child found or no content is
320
* available. It's up to the caller to free the memory with xmlFree().
323
lasso_node_get_child_content(LassoNode *node,
328
LassoNodeClass *class;
329
if (err != NULL && *err != NULL) {
330
g_set_error(err, g_quark_from_string("Lasso"),
331
LASSO_PARAM_ERROR_CHECK_FAILED,
332
lasso_strerror(LASSO_PARAM_ERROR_CHECK_FAILED));
333
g_return_val_if_fail (err == NULL || *err == NULL, NULL);
335
if (LASSO_IS_NODE(node) == FALSE) {
336
g_set_error(err, g_quark_from_string("Lasso"),
337
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ,
338
lasso_strerror(LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ));
339
g_return_val_if_fail(LASSO_IS_NODE(node), NULL);
341
/* don't check @name here, it's checked in impl method */
343
class = LASSO_NODE_GET_CLASS(node);
344
return class->get_child_content(node, name, href, err);
348
* lasso_node_get_children:
351
* Gets direct children of node.
353
* Return value: an array of node or NULL if no children found.
356
lasso_node_get_children(LassoNode *node)
358
LassoNodeClass *class;
359
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
361
class = LASSO_NODE_GET_CLASS(node);
362
return class->get_children(node);
366
* lasso_node_get_content:
368
* @err: return location for an allocated GError, or NULL to ignore errors
370
* Read the value of a node, this can be either the text carried directly by
371
* this node if it's a TEXT node or the aggregate string of the values carried
372
* by this node child's (TEXT and ENTITY_REF). Entity references are
375
* Return value: a new xmlChar * or NULL if no content is available.
376
* It's up to the caller to free the memory with xmlFree().
379
lasso_node_get_content(LassoNode *node,
382
LassoNodeClass *class;
383
if (err != NULL && *err != NULL) {
384
g_set_error(err, g_quark_from_string("Lasso"),
385
LASSO_PARAM_ERROR_CHECK_FAILED,
386
lasso_strerror(LASSO_PARAM_ERROR_CHECK_FAILED));
387
g_return_val_if_fail (err == NULL || *err == NULL,NULL);
389
if (LASSO_IS_NODE(node) == FALSE) {
390
g_set_error(err, g_quark_from_string("Lasso"),
391
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ,
392
lasso_strerror(LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ));
393
g_return_val_if_fail(LASSO_IS_NODE(node), NULL);
396
class = LASSO_NODE_GET_CLASS(node);
397
return class->get_content(node, err);
401
* lasso_node_get_name:
404
* Gets the name of the node.
406
* Return value: the name of the node
409
lasso_node_get_name(LassoNode *node)
411
LassoNodeClass *class;
412
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
414
class = LASSO_NODE_GET_CLASS(node);
415
return class->get_name(node);
421
* @buffer: an XML buffer
423
* Parses the XML buffer and loads it into the node.
426
lasso_node_import(LassoNode *node,
429
LassoNodeClass *class;
430
g_return_if_fail(LASSO_IS_NODE(node));
432
class = LASSO_NODE_GET_CLASS(node);
433
class->import(node, buffer);
437
* lasso_node_import_from_node:
439
* @imported_node: a LassoNode
441
* Put a copy of node->private->node into imported_node->private->node
444
lasso_node_import_from_node(LassoNode *node,
445
LassoNode *imported_node)
447
LassoNodeClass *class;
448
g_return_if_fail(LASSO_IS_NODE(node));
450
class = LASSO_NODE_GET_CLASS(node);
451
class->import_from_node(node, imported_node);
455
* lasso_node_rename_prop:
457
* @old_name: the attribute name
458
* @new_name: the new attribute name
460
* Renames an attribute of the node.
463
lasso_node_rename_prop(LassoNode *node,
464
const xmlChar *old_name,
465
const xmlChar *new_name)
467
LassoNodeClass *class;
468
g_return_if_fail(LASSO_IS_NODE(node));
470
class = LASSO_NODE_GET_CLASS(node);
471
class->rename_prop(node, old_name, new_name);
475
* lasso_node_verify_signature:
477
* @public_key_file: the public key
479
* Verifys the node signature.
481
* Return value: 1 if signature is valid, 0 if invalid or a negative value
482
* if an error occurs.
485
lasso_node_verify_signature(LassoNode *node,
486
const gchar *public_key_file)
488
LassoNodeClass *class;
490
g_return_val_if_fail(LASSO_IS_NODE(node),
491
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
492
/* don't check @public_key_file here, it's checked in impl method */
494
class = LASSO_NODE_GET_CLASS(node);
495
return class->verify_signature(node, public_key_file);
499
* lasso_node_verify_x509_signature:
501
* @ca_certificate_file: the trusted certificate
503
* Verifys the node signature with X509 certificate.
505
* Return value: 1 if signature is valid, 0 if invalid or a negative value
506
* if an error occurs.
509
lasso_node_verify_x509_signature(LassoNode *node,
510
const gchar *ca_certificate_file)
512
LassoNodeClass *class;
514
g_return_val_if_fail(LASSO_IS_NODE(node),
515
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
516
/* don't check @certificate_file here, it's checked in impl method */
518
class = LASSO_NODE_GET_CLASS(node);
519
return class->verify_x509_signature(node, ca_certificate_file);
522
/*****************************************************************************/
523
/* virtual private methods */
524
/*****************************************************************************/
527
lasso_node_add_child(LassoNode *node,
531
LassoNodeClass *class;
532
g_return_if_fail(LASSO_IS_NODE(node));
534
class = LASSO_NODE_GET_CLASS(node);
535
class->add_child(node, child, unbounded);
539
lasso_node_add_signature(LassoNode *node,
541
const xmlChar *private_key_file,
542
const xmlChar *certificate_file)
544
LassoNodeClass *class;
546
g_return_val_if_fail(LASSO_IS_NODE(node),
547
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
548
/* don't check @private_key_file and @certificate_file here,
549
it's checked in impl method */
551
class = LASSO_NODE_GET_CLASS(node);
552
return (class->add_signature(node, sign_method, private_key_file,
557
lasso_node_add_signature_tmpl(LassoNode *node,
558
lassoSignatureType sign_type,
559
lassoSignatureMethod sign_method,
560
xmlChar *reference_id)
562
LassoNodeClass *class;
564
g_return_val_if_fail(LASSO_IS_NODE(node),
565
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
567
class = LASSO_NODE_GET_CLASS(node);
568
return class->add_signature_tmpl(node, sign_type, sign_method, reference_id);
572
lasso_node_build_query(LassoNode *node)
574
LassoNodeClass *class;
575
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
577
class = LASSO_NODE_GET_CLASS(node);
578
return class->build_query(node);
582
lasso_node_get_xmlNode(LassoNode *node)
584
LassoNodeClass *class;
585
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
587
class = LASSO_NODE_GET_CLASS(node);
588
return class->get_xmlNode(node);
592
* lasso_node_new_child:
594
* @name: the name of the child
595
* @content: the content of the child
596
* @unbounded: if TRUE, several children with the same name can be added else
597
* the child must be unique.
599
* Add a new child in node.
600
* This is an internal function and should not be called by application
604
lasso_node_new_child(LassoNode *node,
606
const xmlChar *content,
609
LassoNodeClass *class;
610
g_return_if_fail(LASSO_IS_NODE(node));
612
class = LASSO_NODE_GET_CLASS(node);
613
class->new_child(node, name, content, unbounded);
617
lasso_node_new_ns_prop(LassoNode *node,
619
const xmlChar *value,
621
const xmlChar *prefix)
623
LassoNodeClass *class;
624
g_return_if_fail(LASSO_IS_NODE(node));
626
class = LASSO_NODE_GET_CLASS(node);
627
class->new_ns_prop(node, name, value, href, prefix);
631
lasso_node_serialize(LassoNode *node,
634
LassoNodeClass *class;
635
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
637
class = LASSO_NODE_GET_CLASS(node);
638
return class->serialize(node, gd);
642
lasso_node_set_name(LassoNode *node,
645
LassoNodeClass *class;
646
g_return_if_fail(LASSO_IS_NODE(node));
648
class = LASSO_NODE_GET_CLASS(node);
649
class->set_name(node, name);
653
lasso_node_set_ns(LassoNode *node,
655
const xmlChar *prefix)
657
LassoNodeClass *class;
658
g_return_if_fail(LASSO_IS_NODE(node));
660
class = LASSO_NODE_GET_CLASS(node);
661
class->set_ns(node, href, prefix);
665
lasso_node_set_prop(LassoNode *node,
667
const xmlChar *value)
669
LassoNodeClass *class;
670
g_return_if_fail(LASSO_IS_NODE(node));
672
class = LASSO_NODE_GET_CLASS(node);
673
class->set_prop(node, name, value);
677
lasso_node_set_xmlNode(LassoNode *node,
678
xmlNodePtr libxml_node)
680
LassoNodeClass *class;
681
g_return_if_fail(LASSO_IS_NODE(node));
683
class = LASSO_NODE_GET_CLASS(node);
684
class->set_xmlNode(node, libxml_node);
688
lasso_node_sign_signature_tmpl(LassoNode *node,
689
const xmlChar *private_key_file,
690
const xmlChar *certificate_file)
692
LassoNodeClass *class;
694
g_return_val_if_fail(LASSO_IS_NODE(node),
695
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
696
/* don't check @private_key_file and @certificate_file here,
697
it's checked in impl method */
699
class = LASSO_NODE_GET_CLASS(node);
700
class->sign_signature_tmpl(node, private_key_file, certificate_file);
705
/*****************************************************************************/
706
/* implementation methods */
707
/*****************************************************************************/
710
lasso_node_impl_copy(LassoNode *node)
714
copy = LASSO_NODE(g_object_new(G_OBJECT_TYPE(node), NULL));
715
lasso_node_set_xmlNode(copy, xmlCopyNode(node->private->node, 1));
721
lasso_node_impl_destroy(LassoNode *node)
723
g_object_unref(G_OBJECT(node));
727
lasso_node_impl_dump(LassoNode *node,
728
const xmlChar *encoding,
732
xmlOutputBufferPtr buf;
733
xmlCharEncodingHandlerPtr handler = NULL;
735
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
736
/* encoding is optional */
737
g_return_val_if_fail (format == 0 || format == 1, NULL);
739
if (encoding != NULL) {
740
handler = xmlFindCharEncodingHandler(encoding);
741
if (handler == NULL) {
745
buf = xmlAllocOutputBuffer(handler);
749
xmlNodeDumpOutput(buf, NULL, node->private->node,
750
0, format, encoding);
751
xmlOutputBufferFlush(buf);
752
if (buf->conv != NULL) {
753
ret = g_strdup(buf->conv->content);
756
ret = g_strdup(buf->buffer->content);
758
xmlOutputBufferClose(buf);
764
lasso_node_impl_export(LassoNode *node)
766
/* using lasso_node_impl_dump because dump method can be overrided */
767
return lasso_node_impl_dump(node, "utf-8", 0);
771
lasso_node_impl_export_to_base64(LassoNode *node)
775
buffer = lasso_node_impl_dump(node, "utf-8", 0);
776
ret = xmlSecBase64Encode((const xmlSecByte *) buffer,
777
(xmlSecSize)strlen((const char *)buffer), 0);
785
lasso_node_impl_export_to_query(LassoNode *node,
786
lassoSignatureMethod sign_method,
787
const gchar *private_key_file)
791
xmlChar *str1, *str2, *str_escaped = NULL;
792
gchar *unsigned_query, *ret;
794
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
795
g_return_val_if_fail (private_key_file != NULL, NULL);
797
unsigned_query = lasso_node_build_query(node);
798
query = g_string_new(unsigned_query);
799
g_free(unsigned_query);
800
unsigned_query = NULL;
802
if (sign_method > 0 && private_key_file != NULL) {
803
/* add SigAlg in query */
804
query = g_string_append(query, "&SigAlg=");
805
switch (sign_method) {
806
case lassoSignatureMethodRsaSha1:
807
str_escaped = lasso_str_escape((xmlChar *)xmlSecHrefRsaSha1);
809
case lassoSignatureMethodDsaSha1:
810
str_escaped = lasso_str_escape((xmlChar *)xmlSecHrefDsaSha1);
813
query = g_string_append(query, str_escaped);
814
xmlFree(str_escaped);
817
/* try to sign query */
818
doc = lasso_str_sign(query->str, sign_method, private_key_file);
820
/* get signature (base64 encoded) */
821
str1 = lasso_doc_get_node_content(doc, xmlSecNodeSignatureValue);
822
str2 = lasso_str_escape(str1);
828
g_string_free(query, TRUE);
832
/* add signature in query */
833
query = g_string_append(query, "&Signature=");
834
query = g_string_append(query, str2);
839
ret = g_strdup(query->str);
840
g_string_free(query, TRUE);
845
lasso_node_impl_export_to_soap(LassoNode *node)
847
LassoNode *envelope, *body, *copy_node;
850
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
852
envelope = lasso_node_new();
853
lasso_node_set_name(envelope, "Envelope");
854
lasso_node_set_ns(envelope, lassoSoapEnvHRef, lassoSoapEnvPrefix);
856
copy_node = lasso_node_copy(node);
858
body = lasso_node_new();
859
lasso_node_set_name(body, "Body");
860
lasso_node_set_ns(body, lassoSoapEnvHRef, lassoSoapEnvPrefix);
862
lasso_node_add_child(body, copy_node, FALSE);
863
lasso_node_add_child(envelope, body, FALSE);
865
buffer = lasso_node_export(envelope);
867
lasso_node_destroy(copy_node);
868
lasso_node_destroy(body);
869
lasso_node_destroy(envelope);
875
lasso_node_impl_get_attr(LassoNode *node,
882
g_set_error(err, g_quark_from_string("Lasso"),
883
LASSO_PARAM_ERROR_INVALID_VALUE,
884
lasso_strerror(LASSO_PARAM_ERROR_INVALID_VALUE));
885
g_return_val_if_fail(name != NULL, NULL);
888
prop = node->private->node->properties;
889
while (prop != NULL) {
890
if (xmlStrEqual(prop->name, name)) {
897
g_set_error(err, g_quark_from_string("Lasso"),
898
LASSO_XML_ERROR_ATTR_NOT_FOUND,
899
lasso_strerror(LASSO_XML_ERROR_ATTR_NOT_FOUND),
900
name, node->private->node->name);
905
lasso_node_impl_get_attr_value(LassoNode *node,
911
g_set_error(err, g_quark_from_string("Lasso"),
912
LASSO_PARAM_ERROR_INVALID_VALUE,
913
lasso_strerror(LASSO_PARAM_ERROR_INVALID_VALUE));
914
g_return_val_if_fail(name != NULL, NULL);
917
value = xmlGetProp(node->private->node, name);
920
g_set_error(err, g_quark_from_string("Lasso"),
921
LASSO_XML_ERROR_ATTR_VALUE_NOT_FOUND,
922
lasso_strerror(LASSO_XML_ERROR_ATTR_VALUE_NOT_FOUND),
923
name, node->private->node->name);
930
lasso_node_impl_get_attrs(LassoNode *node)
932
GPtrArray *attributes = NULL;
935
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
937
prop = node->private->node->properties;
939
attributes = g_ptr_array_new();
941
while (prop != NULL) {
942
g_ptr_array_add(attributes, prop);
950
lasso_node_impl_get_child(LassoNode *node,
958
g_set_error(err, g_quark_from_string("Lasso"),
959
LASSO_PARAM_ERROR_INVALID_VALUE,
960
lasso_strerror(LASSO_PARAM_ERROR_INVALID_VALUE));
961
g_return_val_if_fail(name != NULL, NULL);
964
/* /\* No recurssive version *\/ */
965
/* xmlNodePtr cur; */
967
/* cur = node->private->node->children; */
968
/* while (cur != NULL) { */
969
/* if(cur->type == XML_ELEMENT_NODE) { */
970
/* if (xmlStrEqual(cur->name, name)) { */
971
/* return (lasso_node_new_from_xmlNode(cur)); */
974
/* cur = cur->next; */
978
/* /\* Recurssive version *\/ */
979
/* xmlNodePtr cur; */
980
/* LassoNode *ret, *child; */
982
/* cur = node->private->node; */
983
/* while (cur != NULL) { */
984
/* if ((cur->type == XML_ELEMENT_NODE) && xmlStrEqual(cur->name, name)) { */
985
/* return (lasso_node_new_from_xmlNode(cur)); */
987
/* if (cur->children != NULL) { */
988
/* child = lasso_node_new_from_xmlNode(cur->children); */
989
/* ret = lasso_node_get_child(child, name); */
990
/* if (ret != NULL) { */
994
/* cur = cur->next; */
999
child = xmlSecFindNode(node->private->node, name, href);
1002
child = xmlSecFindNode(node->private->node, name, href);
1004
child = xmlSecFindNode(node->private->node, name, lassoLibHRef);
1006
child = xmlSecFindNode(node->private->node, name, lassoSamlAssertionHRef);
1008
child = xmlSecFindNode(node->private->node, name, lassoSamlProtocolHRef);
1010
child = xmlSecFindNode(node->private->node, name, lassoSoapEnvHRef);
1012
child = xmlSecFindNode(node->private->node, name, lassoMetadataHRef);
1014
child = xmlSecFindNode(node->private->node, name, lassoLassoHRef);
1016
if (child != NULL) {
1017
return lasso_node_new_from_xmlNode(child);
1020
g_set_error(err, g_quark_from_string("Lasso"),
1021
LASSO_XML_ERROR_NODE_NOT_FOUND,
1022
lasso_strerror(LASSO_XML_ERROR_NODE_NOT_FOUND),
1023
name, node->private->node->name);
1029
lasso_node_impl_get_child_content(LassoNode *node,
1030
const xmlChar *name,
1031
const xmlChar *href,
1034
GError *tmp_err = NULL;
1036
xmlChar *content = NULL;
1039
g_set_error(err, g_quark_from_string("Lasso"),
1040
LASSO_PARAM_ERROR_INVALID_VALUE,
1041
lasso_strerror(LASSO_PARAM_ERROR_INVALID_VALUE));
1042
g_return_val_if_fail(name != NULL, NULL);
1045
child = lasso_node_get_child(node, name, href, &tmp_err);
1047
if (child != NULL) {
1048
content = lasso_node_get_content(child, &tmp_err);
1049
lasso_node_destroy(child);
1050
if (content == NULL) {
1051
g_propagate_error (err, tmp_err);
1055
g_propagate_error (err, tmp_err);
1062
lasso_node_impl_get_children(LassoNode *node)
1064
GPtrArray *children = NULL;
1067
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
1069
cur = node->private->node->children;
1071
children = g_ptr_array_new();
1073
while (cur != NULL) {
1074
g_ptr_array_add(children, lasso_node_new_from_xmlNode(cur));
1082
lasso_node_impl_get_content(LassoNode *node,
1087
content = xmlNodeGetContent(node->private->node);
1088
if (content == NULL) {
1089
g_set_error(err, g_quark_from_string("Lasso"),
1090
LASSO_XML_ERROR_NODE_CONTENT_NOT_FOUND,
1091
lasso_strerror(LASSO_XML_ERROR_NODE_CONTENT_NOT_FOUND),
1092
node->private->node->name);
1099
lasso_node_impl_get_name(LassoNode *node)
1101
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
1103
return xmlStrdup(node->private->node->name);
1107
lasso_node_impl_import(LassoNode *node,
1108
const gchar *buffer)
1113
g_return_if_fail (LASSO_IS_NODE(node));
1114
g_return_if_fail (buffer != NULL);
1116
doc = xmlParseMemory(buffer, strlen(buffer));
1117
/* get root element of doc and duplicate it */
1118
root = xmlCopyNode(xmlDocGetRootElement(doc), 1);
1119
lasso_node_set_xmlNode(node, root);
1125
lasso_node_impl_import_from_node(LassoNode *node,
1126
LassoNode *imported_node)
1128
g_return_if_fail (LASSO_IS_NODE(node));
1129
g_return_if_fail (LASSO_IS_NODE(imported_node));
1131
lasso_node_set_xmlNode(node, xmlCopyNode(imported_node->private->node, 1));
1135
lasso_node_impl_rename_prop(LassoNode *node,
1136
const xmlChar *old_name,
1137
const xmlChar *new_name)
1141
g_return_if_fail (LASSO_IS_NODE(node));
1142
g_return_if_fail (old_name != NULL);
1143
g_return_if_fail (new_name != NULL);
1145
value = xmlGetProp(node->private->node, old_name);
1146
if (value != NULL) {
1147
xmlRemoveProp(lasso_node_get_attr(node, old_name, NULL));
1148
lasso_node_set_prop(node, new_name, value);
1153
lasso_node_impl_verify_signature(LassoNode *node,
1154
const gchar *public_key_file)
1156
xmlDocPtr doc = NULL;
1157
xmlNodePtr xmlNode = NULL;
1158
xmlNodePtr signature = NULL;
1159
xmlSecDSigCtxPtr dsigCtx = NULL;
1165
g_return_val_if_fail(public_key_file != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
1167
doc = xmlNewDoc("1.0");
1168
/* Don't use xmlCopyNode here because it changed the attrs and ns order :-( */
1169
xmlNode = lasso_node_get_xmlNode(node);
1170
xmlAddChild((xmlNodePtr)doc, xmlNode);
1172
/* FIXME : register 'AssertionID' ID attribute manually */
1173
id_attr = lasso_node_get_attr(node, "AssertionID", NULL);
1174
if (id_attr != NULL) {
1175
id_value = xmlNodeListGetString(doc, id_attr->children, 1);
1176
id = xmlAddID(NULL, doc, id_value, id_attr);
1180
/* find start node */
1181
signature = xmlSecFindNode(xmlNode, xmlSecNodeSignature,
1183
if (signature == NULL) {
1184
message(G_LOG_LEVEL_CRITICAL,
1185
lasso_strerror(LASSO_DS_ERROR_SIGNATURE_NOT_FOUND),
1186
node->private->node->name);
1187
ret = LASSO_DS_ERROR_SIGNATURE_NOT_FOUND;
1191
/* create signature context */
1192
dsigCtx = xmlSecDSigCtxCreate(NULL);
1193
if (dsigCtx == NULL) {
1194
message(G_LOG_LEVEL_CRITICAL,
1195
lasso_strerror(LASSO_DS_ERROR_CONTEXT_CREATION_FAILED));
1196
ret = LASSO_DS_ERROR_CONTEXT_CREATION_FAILED;
1200
/* load public key */
1201
dsigCtx->signKey = xmlSecCryptoAppKeyLoad(public_key_file,
1202
xmlSecKeyDataFormatPem,
1204
if(dsigCtx->signKey == NULL) {
1205
message(G_LOG_LEVEL_CRITICAL,
1206
lasso_strerror(LASSO_DS_ERROR_PUBLIC_KEY_LOAD_FAILED),
1208
ret = LASSO_DS_ERROR_PUBLIC_KEY_LOAD_FAILED;
1212
/* verify signature */
1213
if (xmlSecDSigCtxVerify(dsigCtx, signature) < 0) {
1214
message(G_LOG_LEVEL_CRITICAL,
1215
lasso_strerror(LASSO_DS_ERROR_SIGNATURE_VERIFICATION_FAILED),
1216
node->private->node->name);
1217
ret = LASSO_DS_ERROR_SIGNATURE_VERIFICATION_FAILED;
1221
if (dsigCtx->status == xmlSecDSigStatusSucceeded) {
1225
message(G_LOG_LEVEL_CRITICAL,
1226
lasso_strerror(LASSO_DS_ERROR_INVALID_SIGNATURE),
1227
node->private->node->name);
1228
ret = LASSO_DS_ERROR_INVALID_SIGNATURE;
1233
if(dsigCtx != NULL) {
1234
xmlSecDSigCtxDestroy(dsigCtx);
1236
/* FIXME xmlFreeDoc(doc); */
1241
lasso_node_impl_verify_x509_signature(LassoNode *node,
1242
const gchar *ca_certificate_file)
1244
xmlDocPtr doc = NULL;
1245
xmlNodePtr xmlNode = NULL;
1246
xmlNodePtr signature = NULL;
1247
xmlSecKeysMngrPtr mngr = NULL;
1248
xmlSecDSigCtxPtr dsigCtx = NULL;
1254
g_return_val_if_fail(ca_certificate_file != NULL,
1255
LASSO_PARAM_ERROR_INVALID_VALUE);
1257
doc = xmlNewDoc("1.0");
1258
/* Don't use xmlCopyNode here because it changed the attrs and ns order :-( */
1259
xmlNode = lasso_node_get_xmlNode(node);
1260
xmlAddChild((xmlNodePtr)doc, xmlNode);
1262
/* FIXME: register 'AssertionID' ID attribute manually */
1263
id_attr = lasso_node_get_attr(node, "AssertionID", NULL);
1264
if (id_attr != NULL) {
1265
id_value = xmlNodeListGetString(doc, id_attr->children, 1);
1266
id = xmlAddID(NULL, doc, id_value, id_attr);
1270
/* find start node */
1271
signature = xmlSecFindNode(xmlNode, xmlSecNodeSignature,
1273
if (signature == NULL) {
1274
message(G_LOG_LEVEL_CRITICAL,
1275
lasso_strerror(LASSO_DS_ERROR_SIGNATURE_NOT_FOUND),
1276
node->private->node->name);
1277
ret = LASSO_DS_ERROR_SIGNATURE_NOT_FOUND;
1281
/* create simple keys mngr */
1282
mngr = xmlSecKeysMngrCreate();
1284
message(G_LOG_LEVEL_CRITICAL,
1285
lasso_strerror(LASSO_DS_ERROR_KEYS_MNGR_CREATION_FAILED));
1286
ret = LASSO_DS_ERROR_KEYS_MNGR_CREATION_FAILED;
1290
if (xmlSecCryptoAppDefaultKeysMngrInit(mngr) < 0) {
1291
message(G_LOG_LEVEL_CRITICAL,
1292
lasso_strerror(LASSO_DS_ERROR_KEYS_MNGR_INIT_FAILED));
1293
ret = LASSO_DS_ERROR_KEYS_MNGR_INIT_FAILED;
1297
/* load trusted cert */
1298
if (xmlSecCryptoAppKeysMngrCertLoad(mngr, ca_certificate_file,
1299
xmlSecKeyDataFormatPem,
1300
xmlSecKeyDataTypeTrusted) < 0) {
1301
message(G_LOG_LEVEL_CRITICAL,
1302
lasso_strerror(LASSO_DS_ERROR_CERTIFICATE_LOAD_FAILED),
1303
ca_certificate_file);
1304
ret = LASSO_DS_ERROR_CERTIFICATE_LOAD_FAILED;
1308
/* create signature context */
1309
dsigCtx = xmlSecDSigCtxCreate(mngr);
1310
if (dsigCtx == NULL) {
1311
message(G_LOG_LEVEL_CRITICAL,
1312
lasso_strerror(LASSO_DS_ERROR_CONTEXT_CREATION_FAILED));
1313
ret = LASSO_DS_ERROR_CONTEXT_CREATION_FAILED;
1317
/* verify signature */
1318
if (xmlSecDSigCtxVerify(dsigCtx, signature) < 0) {
1319
message(G_LOG_LEVEL_CRITICAL,
1320
lasso_strerror(LASSO_DS_ERROR_SIGNATURE_VERIFICATION_FAILED),
1321
node->private->node->name);
1322
ret = LASSO_DS_ERROR_SIGNATURE_VERIFICATION_FAILED;
1326
if (dsigCtx->status == xmlSecDSigStatusSucceeded) {
1330
message(G_LOG_LEVEL_CRITICAL,
1331
lasso_strerror(LASSO_DS_ERROR_INVALID_SIGNATURE),
1332
node->private->node->name);
1333
ret = LASSO_DS_ERROR_INVALID_SIGNATURE;
1338
if(dsigCtx != NULL) {
1339
xmlSecDSigCtxDestroy(dsigCtx);
1342
xmlSecKeysMngrDestroy(mngr);
1344
/* FIXME xmlFreeDoc(doc); */
1348
/*** private methods **********************************************************/
1351
lasso_node_impl_add_child(LassoNode *node,
1355
xmlNodePtr old_child = NULL;
1356
const xmlChar *href = NULL;
1358
g_return_if_fail (LASSO_IS_NODE(node));
1359
g_return_if_fail (LASSO_IS_NODE(child));
1361
/* if child is not unbounded, we search it */
1362
if (unbounded == FALSE) {
1363
if (child->private->node->ns != NULL) {
1364
href = child->private->node->ns->href;
1366
old_child = xmlSecFindNode(node->private->node,
1367
child->private->node->name,
1371
if (unbounded == FALSE && old_child != NULL) {
1372
/* child replace old child */
1373
xmlReplaceNode(old_child, child->private->node);
1376
/* else child is added */
1377
xmlAddChild(node->private->node, child->private->node);
1379
child->private->node_is_weak_ref = TRUE;
1383
lasso_node_impl_add_signature(LassoNode *node,
1385
const xmlChar *private_key_file,
1386
const xmlChar *certificate_file)
1390
g_return_val_if_fail (private_key_file != NULL,
1391
LASSO_PARAM_ERROR_INVALID_VALUE);
1393
if (certificate_file != NULL) {
1394
ret = lasso_node_add_signature_tmpl(node, lassoSignatureTypeWithX509, sign_method, 0);
1397
ret = lasso_node_add_signature_tmpl(node, lassoSignatureTypeSimple, sign_method, 0);
1400
ret = lasso_node_sign_signature_tmpl(node, private_key_file, certificate_file);
1407
lasso_node_impl_add_signature_tmpl(LassoNode *node,
1408
lassoSignatureType sign_type,
1409
lassoSignatureMethod sign_method,
1410
xmlChar *reference_uri)
1412
LassoNode *sign_node;
1414
xmlNodePtr signature, reference, key_info;
1417
g_return_val_if_fail(sign_method == lassoSignatureMethodRsaSha1 || \
1418
sign_method == lassoSignatureMethodDsaSha1,
1419
LASSO_PARAM_ERROR_INVALID_VALUE);
1421
doc = xmlNewDoc("1.0");
1422
xmlAddChild((xmlNodePtr)doc, lasso_node_get_xmlNode(node));
1424
switch (sign_method) {
1425
case lassoSignatureMethodRsaSha1:
1426
signature = xmlSecTmplSignatureCreate(doc, xmlSecTransformExclC14NId,
1427
xmlSecTransformRsaSha1Id, NULL);
1429
case lassoSignatureMethodDsaSha1:
1430
signature = xmlSecTmplSignatureCreate(doc, xmlSecTransformExclC14NId,
1431
xmlSecTransformDsaSha1Id, NULL);
1437
if (signature == NULL) {
1438
message(G_LOG_LEVEL_CRITICAL, "Failed to create signature template\n");
1439
return LASSO_DS_ERROR_SIGNATURE_TMPL_CREATION_FAILED;
1442
/* uri = xmlMalloc(strlen(reference_uri)+1+1); */
1443
/* g_sprintf(uri, "#%s", reference_uri); */
1445
if (reference_uri != NULL) {
1446
uri = xmlMalloc(strlen(reference_uri)+1+1);
1447
g_sprintf(uri, "#%s", reference_uri);
1452
reference = xmlSecTmplSignatureAddReference(signature,
1453
xmlSecTransformSha1Id,
1456
if (reference == NULL) {
1457
message(G_LOG_LEVEL_CRITICAL, "Failed to add reference to signature template\n");
1458
xmlFreeNode(signature);
1459
return LASSO_DS_ERROR_SIGNATURE_TMPL_CREATION_FAILED;
1462
/* add enveloped transform */
1463
if (xmlSecTmplReferenceAddTransform(reference, xmlSecTransformEnvelopedId) == NULL) {
1464
message(G_LOG_LEVEL_CRITICAL, "Failed to add enveloped transform to reference\n");
1465
xmlFreeNode(signature);
1466
return LASSO_DS_ERROR_SIGNATURE_TMPL_CREATION_FAILED;
1469
/* add <dsig:KeyInfo/> */
1470
key_info = xmlSecTmplSignatureEnsureKeyInfo(signature, NULL);
1471
if (key_info == NULL) {
1472
message(G_LOG_LEVEL_CRITICAL, "Failed to add key info\n");
1473
xmlFreeNode(signature);
1474
return LASSO_DS_ERROR_SIGNATURE_TMPL_CREATION_FAILED;
1477
/* add <dsig:X509Data/> */
1478
if (sign_type == lassoSignatureTypeWithX509) {
1479
if (xmlSecTmplKeyInfoAddX509Data(key_info) == NULL) {
1480
message(G_LOG_LEVEL_CRITICAL, "Failed to add X509Data node\n");
1481
xmlFreeNode(signature);
1482
return LASSO_DS_ERROR_SIGNATURE_TMPL_CREATION_FAILED;
1486
sign_node = lasso_node_new();
1487
lasso_node_set_xmlNode(sign_node, signature);
1488
lasso_node_add_child(node, sign_node, TRUE);
1489
lasso_node_destroy(sign_node);
1491
/* xmlUnlinkNode(lasso_node_get_xmlNode(node)); */
1492
/* xmlFreeDoc(doc); */
1498
gdata_build_query_foreach_func(GQuark key_id,
1506
array = g_ptr_array_new();
1507
str = g_string_new("");
1508
for (i=0; i<((GPtrArray *)data)->len; i++) {
1509
str = g_string_append(str, g_ptr_array_index((GPtrArray *)data, i));
1510
if (i<((GPtrArray *)data)->len - 1) {
1511
str = g_string_append(str, " ");
1514
g_ptr_array_add(array, g_strdup((gpointer)g_quark_to_string(key_id)));
1515
g_ptr_array_add(array, str->str);
1516
g_string_free(str, FALSE);
1517
g_ptr_array_add((GPtrArray *)user_data, array);
1521
lasso_node_impl_build_query(LassoNode *node)
1527
xmlChar *str_escaped;
1530
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
1532
gd = lasso_node_serialize(node, NULL);
1533
a = g_ptr_array_new();
1534
/* transform dict into array
1535
each key => [val1, val2, ...] of dict become [key, "val1 val2 ..."] */
1536
g_datalist_foreach(&gd, gdata_build_query_foreach_func, a);
1538
query = g_string_new("");
1539
for (i=0; i<a->len; i++) {
1540
aa = g_ptr_array_index(a, i);
1541
query = g_string_append(query, g_ptr_array_index(aa, 0));
1542
query = g_string_append(query, "=");
1543
str_escaped = lasso_str_escape(g_ptr_array_index(aa, 1));
1544
query = g_string_append(query, str_escaped);
1545
xmlFree(str_escaped);
1548
query = g_string_append(query, "&");
1550
/* free allocated memory for array aa */
1551
for (j=0; j<aa->len; j++) {
1552
g_free(aa->pdata[j]);
1554
g_ptr_array_free(aa, TRUE);
1556
/* free allocated memory for array a */
1557
g_ptr_array_free(a, TRUE);
1558
g_datalist_clear(&gd);
1560
ret = g_strdup(query->str);
1561
g_string_free(query, TRUE);
1567
lasso_node_impl_get_xmlNode(LassoNode *node)
1569
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
1571
return node->private->node;
1575
lasso_node_impl_new_child(LassoNode *node,
1576
const xmlChar *name,
1577
const xmlChar *content,
1580
/* LassoNode *old_child = NULL; */
1581
xmlNodePtr old_child = NULL;
1582
const xmlChar *href = NULL;
1584
g_return_if_fail (LASSO_IS_NODE(node));
1585
g_return_if_fail (name != NULL);
1586
g_return_if_fail (content != NULL);
1589
if (node->private->node->ns != NULL) {
1590
href = node->private->node->ns->href;
1592
old_child = xmlSecFindNode(node->private->node, name, href);
1593
/* old_child = lasso_node_get_child(node, name); */
1596
if (!unbounded && old_child != NULL) {
1597
/* xmlNodeSetContent(old_child->private->node, content); */
1598
xmlNodeSetContent(old_child, content);
1601
xmlNewTextChild(node->private->node, NULL, name, content);
1606
lasso_node_impl_new_ns_prop(LassoNode *node,
1607
const xmlChar *name,
1608
const xmlChar *value,
1609
const xmlChar *href,
1610
const xmlChar *prefix)
1614
g_return_if_fail (LASSO_IS_NODE(node));
1615
g_return_if_fail (href != NULL || prefix != NULL);
1616
g_return_if_fail (name != NULL || value != NULL);
1618
ns = xmlNewNs(node->private->node, href, prefix);
1619
xmlNewNsProp(node->private->node, ns, name, value);
1623
gdata_serialize_destroy_notify(gpointer data)
1626
GPtrArray *array = data;
1628
for (i=0; i<array->len; i++) {
1629
xmlFree(array->pdata[i]);
1630
array->pdata[i] = NULL;
1632
g_ptr_array_free(array, TRUE);
1636
lasso_node_impl_serialize(LassoNode *node,
1639
GPtrArray *attrs, *children;
1645
g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
1648
g_datalist_init(&gd);
1651
attrs = lasso_node_get_attrs(node);
1652
if (attrs != NULL) {
1653
for(i=0; i<attrs->len; i++) {
1654
values = g_ptr_array_new();
1655
name = (xmlChar *)((LassoAttr *)g_ptr_array_index(attrs, i))->name;
1656
/* xmlGetProp returns a COPY of attr value
1657
each val must be xmlFree in gdata_serialize_destroy_notify()
1658
which is called by g_datalist_clear() */
1659
val = xmlGetProp(node->private->node, name);
1660
g_ptr_array_add(values, val);
1661
g_datalist_set_data_full(&gd, name, values, gdata_serialize_destroy_notify);
1663
g_ptr_array_free(attrs, TRUE);
1666
children = lasso_node_get_children(node);
1667
if (children != NULL) {
1668
for(i=0; i<children->len; i++) {
1669
xmlNodePtr xml_node = ((LassoNode *)g_ptr_array_index(children, i))->private->node;
1670
switch (xml_node->type) {
1671
case XML_ELEMENT_NODE:
1672
gd = lasso_node_serialize(g_ptr_array_index(children, i), gd);
1675
name = lasso_node_get_name(node);
1676
/* xmlNodeGetContent returns a COPY of node content
1677
each val must be xmlFree in gdata_serialize_destroy_notify()
1678
which is called by g_datalist_clear() */
1679
val = xmlNodeGetContent(node->private->node);
1683
values = (GPtrArray *)g_datalist_get_data(&gd, name);
1684
if (values == NULL) {
1685
values = g_ptr_array_new();
1686
g_ptr_array_add(values, val);
1687
g_datalist_set_data_full(&gd, name, values,
1688
gdata_serialize_destroy_notify);
1691
g_ptr_array_add(values, val);
1699
lasso_node_destroy((LassoNode *)g_ptr_array_index(children, i));
1701
g_ptr_array_free(children, TRUE);
1708
lasso_node_impl_set_name(LassoNode *node,
1709
const xmlChar *name)
1711
g_return_if_fail (LASSO_IS_NODE(node));
1712
g_return_if_fail (name != NULL);
1714
xmlNodeSetName(node->private->node, name);
1718
lasso_node_impl_set_ns(LassoNode *node,
1719
const xmlChar *href,
1720
const xmlChar *prefix)
1724
g_return_if_fail (LASSO_IS_NODE(node));
1725
g_return_if_fail (href != NULL || prefix != NULL);
1728
/* cur = node->private->node->ns; */
1729
/* while (cur != NULL) { */
1730
/* printf("%s:%s\n", cur->prefix, cur->href); */
1731
/* cur = cur->next; */
1733
/* cur = node->private->node->nsDef; */
1734
/* while (cur != NULL) { */
1735
/* printf("%s:%s\n", cur->prefix, cur->href); */
1736
/* cur = cur->next; */
1739
new_ns = xmlNewNs(node->private->node, href, prefix);
1740
xmlFreeNs(node->private->node->ns);
1741
xmlSetNs(node->private->node, new_ns);
1742
node->private->node->nsDef = new_ns;
1746
lasso_node_impl_set_prop(LassoNode *node,
1747
const xmlChar *name,
1748
const xmlChar *value)
1750
g_return_if_fail (LASSO_IS_NODE(node));
1751
g_return_if_fail (name != NULL);
1752
g_return_if_fail (value != NULL);
1754
xmlSetProp(node->private->node, name, value);
1758
lasso_node_impl_set_xmlNode(LassoNode *node,
1759
xmlNodePtr libxml_node)
1761
g_return_if_fail (LASSO_IS_NODE(node));
1762
g_return_if_fail (libxml_node != NULL);
1764
xmlFreeNode(node->private->node);
1765
node->private->node = libxml_node;
1769
lasso_node_impl_sign_signature_tmpl(LassoNode *node,
1770
const xmlChar *private_key_file,
1771
const xmlChar *certificate_file)
1774
xmlNodePtr signature_tmpl;
1775
xmlSecDSigCtxPtr dsig_ctx;
1778
g_return_val_if_fail(private_key_file != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
1780
doc = xmlNewDoc("1.0");
1781
xmlAddChild((xmlNodePtr)doc, lasso_node_get_xmlNode(node));
1782
signature_tmpl = xmlSecFindNode(lasso_node_get_xmlNode(node),
1783
xmlSecNodeSignature,
1786
/* create signature context */
1787
dsig_ctx = xmlSecDSigCtxCreate(NULL);
1788
if (dsig_ctx == NULL) {
1789
message(G_LOG_LEVEL_CRITICAL,
1790
lasso_strerror(LASSO_DS_ERROR_CONTEXT_CREATION_FAILED));
1791
return LASSO_DS_ERROR_CONTEXT_CREATION_FAILED;
1794
/* load private key, assuming that there is not password */
1795
dsig_ctx->signKey = xmlSecCryptoAppKeyLoad(private_key_file,
1796
xmlSecKeyDataFormatPem,
1798
if (dsig_ctx->signKey == NULL) {
1799
message(G_LOG_LEVEL_CRITICAL,
1800
lasso_strerror(LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED),
1802
ret = LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED;
1806
/* load certificate and add to the key */
1807
if (certificate_file != NULL) {
1808
if (xmlSecCryptoAppKeyCertLoad(dsig_ctx->signKey, certificate_file,
1809
xmlSecKeyDataFormatPem) < 0) {
1810
message(G_LOG_LEVEL_CRITICAL,
1811
lasso_strerror(LASSO_DS_ERROR_CERTIFICATE_LOAD_FAILED),
1813
ret = LASSO_DS_ERROR_CERTIFICATE_LOAD_FAILED;
1818
/* sign the template */
1819
if (xmlSecDSigCtxSign(dsig_ctx, signature_tmpl) < 0) {
1820
message(G_LOG_LEVEL_CRITICAL,
1821
lasso_strerror(LASSO_DS_ERROR_SIGNATURE_FAILED),
1822
node->private->node->name);
1823
ret = LASSO_DS_ERROR_SIGNATURE_FAILED;
1827
xmlSecDSigCtxDestroy(dsig_ctx);
1829
/* xmlUnlinkNode(lasso_node_get_xmlNode(node)); */
1830
/* xmlFreeDoc(doc); */
1835
/*****************************************************************************/
1836
/* overrided parent class methods */
1837
/*****************************************************************************/
1840
lasso_node_dispose(LassoNode *node)
1842
if (node->private->dispose_has_run == TRUE) {
1845
node->private->dispose_has_run = TRUE;
1847
if (node->private->node->name != NULL) {
1848
debug("%s 0x%x disposed ...\n", node->private->node->name, node);
1850
/* unref reference counted objects */
1851
/* we don't have any here */
1853
parent_class->dispose(G_OBJECT(node));
1857
lasso_node_finalize(LassoNode *node)
1859
if (node->private->node->name != NULL) {
1860
debug("%s 0x%x finalized ...\n", node->private->node->name, node);
1863
if (node->private->node_is_weak_ref == FALSE) {
1864
xmlUnlinkNode(node->private->node);
1865
xmlFreeNode(node->private->node);
1866
node->private->node = NULL;
1869
g_free (node->private);
1870
node->private = NULL;
1872
parent_class->finalize(G_OBJECT(node));
1875
/*****************************************************************************/
1876
/* instance and class init functions */
1877
/*****************************************************************************/
1880
lasso_node_instance_init(LassoNode *instance)
1882
LassoNode *node = LASSO_NODE(instance);
1884
node->private = g_new (LassoNodePrivate, 1);
1885
node->private->dispose_has_run = FALSE;
1886
node->private->node_is_weak_ref = FALSE;
1887
node->private->node = xmlNewNode(NULL, "no-name-set");
1891
lasso_node_class_init(LassoNodeClass *class)
1893
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
1895
parent_class = g_type_class_peek_parent(class);
1896
/* virtual public methods */
1897
class->copy = lasso_node_impl_copy;
1898
class->destroy = lasso_node_impl_destroy;
1899
class->dump = lasso_node_impl_dump;
1900
class->export = lasso_node_impl_export;
1901
class->export_to_base64 = lasso_node_impl_export_to_base64;
1902
class->export_to_query = lasso_node_impl_export_to_query;
1903
class->export_to_soap = lasso_node_impl_export_to_soap;
1904
class->get_attr = lasso_node_impl_get_attr;
1905
class->get_attr_value = lasso_node_impl_get_attr_value;
1906
class->get_attrs = lasso_node_impl_get_attrs;
1907
class->get_child = lasso_node_impl_get_child;
1908
class->get_child_content = lasso_node_impl_get_child_content;
1909
class->get_children = lasso_node_impl_get_children;
1910
class->get_content = lasso_node_impl_get_content;
1911
class->get_name = lasso_node_impl_get_name;
1912
class->import = lasso_node_impl_import;
1913
class->import_from_node = lasso_node_impl_import_from_node;
1914
class->rename_prop = lasso_node_impl_rename_prop;
1915
class->verify_signature = lasso_node_impl_verify_signature;
1916
class->verify_x509_signature = lasso_node_impl_verify_x509_signature;
1917
/* virtual private methods */
1918
class->add_child = lasso_node_impl_add_child;
1919
class->add_signature = lasso_node_impl_add_signature;
1920
class->add_signature_tmpl = lasso_node_impl_add_signature_tmpl;
1921
class->build_query = lasso_node_impl_build_query;
1922
class->get_xmlNode = lasso_node_impl_get_xmlNode;
1923
class->new_child = lasso_node_impl_new_child;
1924
class->new_ns_prop = lasso_node_impl_new_ns_prop;
1925
class->serialize = lasso_node_impl_serialize;
1926
class->set_name = lasso_node_impl_set_name;
1927
class->set_ns = lasso_node_impl_set_ns;
1928
class->set_prop = lasso_node_impl_set_prop;
1929
class->set_xmlNode = lasso_node_impl_set_xmlNode;
1930
class->sign_signature_tmpl = lasso_node_impl_sign_signature_tmpl;
1931
/* override parent class methods */
1932
gobject_class->dispose = (void *)lasso_node_dispose;
1933
gobject_class->finalize = (void *)lasso_node_finalize;
1936
GType lasso_node_get_type() {
1937
static GType this_type = 0;
1940
static const GTypeInfo this_info = {
1941
sizeof (LassoNodeClass),
1944
(GClassInitFunc) lasso_node_class_init,
1949
(GInstanceInitFunc) lasso_node_instance_init,
1952
this_type = g_type_register_static(G_TYPE_OBJECT , "LassoNode",
1961
* The main LassoNode constructor.
1963
* Return value: a new node
1968
return LASSO_NODE(g_object_new(LASSO_TYPE_NODE, NULL));
1972
* lasso_node_new_from_dump:
1975
* Builds a new LassoNode from an LassoNode dump.
1977
* Return value: a new node
1980
lasso_node_new_from_dump(const gchar *buffer)
1986
g_return_val_if_fail (buffer != NULL, NULL);
1988
doc = xmlParseMemory(buffer, strlen(buffer));
1989
g_return_val_if_fail (doc != NULL, NULL);
1990
/* get root element of doc and duplicate it */
1991
node = LASSO_NODE(g_object_new(LASSO_TYPE_NODE, NULL));
1992
root = xmlCopyNode(xmlDocGetRootElement(doc), 1);
1993
lasso_node_set_xmlNode(node, root);
2001
* lasso_node_new_from_xmlNode:
2004
* Builds a new LassoNode from an xmlNode.
2006
* Return value: a new node
2009
lasso_node_new_from_xmlNode(xmlNodePtr node)
2011
LassoNode *lasso_node;
2013
g_return_val_if_fail (node != NULL, NULL);
2015
lasso_node = LASSO_NODE(g_object_new(LASSO_TYPE_NODE, NULL));
2016
lasso_node_set_xmlNode(lasso_node, node);
2017
lasso_node->private->node_is_weak_ref = TRUE;