~ubuntu-branches/ubuntu/utopic/lasso/utopic-proposed

« back to all changes in this revision

Viewing changes to lasso/xml/xml.c

  • Committer: Bazaar Package Importer
  • Author(s): Frederic Peters
  • Date: 2004-09-13 09:26:34 UTC
  • Revision ID: james.westby@ubuntu.com-20040913092634-01vdfl8j9cp94exa
Tags: upstream-0.4.1
ImportĀ upstreamĀ versionĀ 0.4.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: xml.c,v 1.83 2004/09/06 17:49:19 fpeters Exp $ 
 
2
 *
 
3
 * Lasso - A free implementation of the Liberty Alliance specifications.
 
4
 *
 
5
 * Copyright (C) 2004 Entr'ouvert
 
6
 * http://lasso.entrouvert.org
 
7
 * 
 
8
 * Authors: Nicolas Clapies <nclapies@entrouvert.com>
 
9
 *          Valery Febvre <vfebvre@easter-eggs.com>
 
10
 *
 
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.
 
15
 * 
 
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.
 
20
 * 
 
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
 
24
 */
 
25
 
 
26
#include <string.h>
 
27
 
 
28
#include <glib/gprintf.h>
 
29
 
 
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>
 
35
 
 
36
#include <lasso/xml/errors.h>
 
37
#include <lasso/xml/xml.h>
 
38
 
 
39
struct _LassoNodePrivate
 
40
{
 
41
  gboolean   dispose_has_run;
 
42
  gboolean   node_is_weak_ref;
 
43
  xmlNodePtr node;
 
44
};
 
45
 
 
46
static GObjectClass *parent_class = NULL;
 
47
 
 
48
/*****************************************************************************/
 
49
/* virtual public methods                                                    */
 
50
/*****************************************************************************/
 
51
 
 
52
static void lasso_node_impl_set_xmlNode(LassoNode  *node, xmlNodePtr libxml_node);
 
53
 
 
54
/**
 
55
 * lasso_node_copy:
 
56
 * @node: a LassoNode
 
57
 * 
 
58
 * Build a copy of the node.
 
59
 * 
 
60
 * Return value: a copy of the node
 
61
 **/
 
62
LassoNode *
 
63
lasso_node_copy(LassoNode *node)
 
64
{
 
65
  LassoNodeClass *class;
 
66
 
 
67
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
68
 
 
69
  class = LASSO_NODE_GET_CLASS(node);
 
70
  return class->copy(node);
 
71
}
 
72
 
 
73
/**
 
74
 * lasso_node_dump:
 
75
 * @node: a LassoNode
 
76
 * @encoding: the name of the encoding to use or NULL.
 
77
 * @format: is formatting allowed
 
78
 * 
 
79
 * Dumps @node. All datas in object are dumped in an XML format.
 
80
 * 
 
81
 * Return value: a full XML dump of @node
 
82
 **/
 
83
gchar *
 
84
lasso_node_dump(LassoNode     *node,
 
85
                const xmlChar *encoding,
 
86
                int            format)
 
87
{
 
88
  LassoNodeClass *class;
 
89
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
90
 
 
91
  class = LASSO_NODE_GET_CLASS(node);
 
92
  return class->dump(node, encoding, format);
 
93
}
 
94
 
 
95
/**
 
96
 * lasso_node_destroy:
 
97
 * @node: a LassoNode
 
98
 * 
 
99
 * Destroys the LassoNode.
 
100
 **/
 
101
void
 
102
lasso_node_destroy(LassoNode *node)
 
103
{
 
104
  if (LASSO_IS_NODE(node)) {
 
105
    LassoNodeClass *class = LASSO_NODE_GET_CLASS(node);
 
106
    class->destroy(node);
 
107
  }
 
108
}
 
109
 
 
110
/**
 
111
 * lasso_node_export:
 
112
 * @node: a LassoNode
 
113
 * 
 
114
 * Exports the LassoNode.
 
115
 * 
 
116
 * Return value: an XML dump of the LassoNode (UTF-8 encoding)
 
117
 **/
 
118
gchar *
 
119
lasso_node_export(LassoNode *node)
 
120
{
 
121
  LassoNodeClass *class;
 
122
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
123
 
 
124
  class = LASSO_NODE_GET_CLASS(node);
 
125
  return class->export(node);
 
126
}
 
127
 
 
128
/**
 
129
 * lasso_node_export_to_base64:
 
130
 * @node: a LassoNode
 
131
 * 
 
132
 * Like lasso_node_export() method except that result is Base64 encoded.
 
133
 * 
 
134
 * Return value: a Base64 encoded export of the LassoNode
 
135
 **/
 
136
gchar *
 
137
lasso_node_export_to_base64(LassoNode *node)
 
138
{
 
139
  LassoNodeClass *class;
 
140
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
141
 
 
142
  class = LASSO_NODE_GET_CLASS(node);
 
143
  return class->export_to_base64(node);
 
144
}
 
145
 
 
146
/**
 
147
 * lasso_node_export_to_query:
 
148
 * @node: a LassoNode
 
149
 * @sign_method: the Signature transform method
 
150
 * @private_key_file: a private key (may be NULL)
 
151
 * 
 
152
 * URL-encodes and signes the LassoNode.
 
153
 * If private_key_file is NULL, query won't be signed.
 
154
 * 
 
155
 * Return value: URL-encoded and signed LassoNode
 
156
 **/
 
157
gchar *
 
158
lasso_node_export_to_query(LassoNode            *node,
 
159
                           lassoSignatureMethod  sign_method,
 
160
                           const gchar          *private_key_file)
 
161
{
 
162
  LassoNodeClass *class;
 
163
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
164
 
 
165
  class = LASSO_NODE_GET_CLASS(node);
 
166
  return class->export_to_query(node, sign_method, private_key_file);
 
167
}
 
168
 
 
169
/**
 
170
 * lasso_node_export_to_soap:
 
171
 * @node: a LassoNode
 
172
 * 
 
173
 * Like lasso_node_export() method except that result is SOAP enveloped.
 
174
 * 
 
175
 * Return value: a SOAP enveloped export of the LassoNode
 
176
 **/
 
177
gchar *
 
178
lasso_node_export_to_soap(LassoNode *node)
 
179
{
 
180
  LassoNodeClass *class;
 
181
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
182
 
 
183
  class = LASSO_NODE_GET_CLASS(node);
 
184
  return class->export_to_soap(node);
 
185
}
 
186
 
 
187
/**
 
188
 * lasso_node_get_attr:
 
189
 * @node: a LassoNode
 
190
 * @name: the attribute name
 
191
 * @err: return location for an allocated GError, or NULL to ignore errors
 
192
 * 
 
193
 * Gets an attribute associated with the node.
 
194
 * 
 
195
 * Return value: the attribute or NULL if not found.
 
196
 **/
 
197
LassoAttr *
 
198
lasso_node_get_attr(LassoNode      *node,
 
199
                    const xmlChar  *name,
 
200
                    GError        **err)
 
201
{
 
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);
 
208
  }
 
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);
 
214
  }
 
215
  /* don't check @name here, it's checked in impl method */
 
216
 
 
217
  class = LASSO_NODE_GET_CLASS(node);
 
218
  return class->get_attr(node, name, err);
 
219
}
 
220
 
 
221
/**
 
222
 * lasso_node_get_attr_value:
 
223
 * @node: a LassoNode
 
224
 * @name: the attribute name
 
225
 * @err: return location for an allocated GError, or NULL to ignore errors
 
226
 * 
 
227
 * Gets the value of an attribute associated to a node.
 
228
 * 
 
229
 * Return value: the attribute value or NULL if not found. It's up to the caller
 
230
 * to free the memory with xmlFree().
 
231
 **/
 
232
xmlChar *
 
233
lasso_node_get_attr_value(LassoNode      *node,
 
234
                          const xmlChar  *name,
 
235
                          GError        **err)
 
236
{
 
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);
 
243
  }
 
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);
 
249
  }
 
250
  /* don't check @name here, it's checked in impl method */
 
251
 
 
252
  class = LASSO_NODE_GET_CLASS(node);
 
253
  return class->get_attr_value(node, name, err);
 
254
}
 
255
 
 
256
/**
 
257
 * lasso_node_get_attrs:
 
258
 * @node: a LassoNode
 
259
 * 
 
260
 * Gets attributes associated with the node.
 
261
 * 
 
262
 * Return value: an array of attributes or NULL if no attribute found. 
 
263
 **/
 
264
GPtrArray *
 
265
lasso_node_get_attrs(LassoNode *node)
 
266
{
 
267
  LassoNodeClass *class;
 
268
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
269
 
 
270
  class = LASSO_NODE_GET_CLASS(node);
 
271
  return class->get_attrs(node);
 
272
}
 
273
 
 
274
/**
 
275
 * lasso_node_get_child:
 
276
 * @node: a LassoNode
 
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
 
280
 * 
 
281
 * Gets child of node having given @name and namespace @href.
 
282
 * 
 
283
 * Return value: a child node
 
284
 **/
 
285
LassoNode *
 
286
lasso_node_get_child(LassoNode      *node,
 
287
                     const xmlChar  *name,
 
288
                     const xmlChar  *href,
 
289
                     GError        **err)
 
290
{
 
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);
 
297
  }
 
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);
 
303
  }
 
304
  /* don't check @name here, it's checked in impl method */
 
305
 
 
306
  class = LASSO_NODE_GET_CLASS(node);
 
307
  return class->get_child(node, name, href, err);
 
308
}
 
309
 
 
310
/**
 
311
 * lasso_node_get_child_content:
 
312
 * @node: a LassoNode
 
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
 
316
 * 
 
317
 * Gets child content of node having given @name and namespace @href.
 
318
 * 
 
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().
 
321
 **/
 
322
xmlChar *
 
323
lasso_node_get_child_content(LassoNode      *node,
 
324
                             const xmlChar  *name,
 
325
                             const xmlChar  *href,
 
326
                             GError        **err)
 
327
{
 
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);
 
334
  }
 
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);
 
340
  }
 
341
  /* don't check @name here, it's checked in impl method */
 
342
 
 
343
  class = LASSO_NODE_GET_CLASS(node);
 
344
  return class->get_child_content(node, name, href, err);
 
345
}
 
346
 
 
347
/**
 
348
 * lasso_node_get_children:
 
349
 * @node: a LassoNode
 
350
 * 
 
351
 * Gets direct children of node.
 
352
 * 
 
353
 * Return value: an array of node or NULL if no children found.
 
354
 **/
 
355
GPtrArray *
 
356
lasso_node_get_children(LassoNode *node)
 
357
{
 
358
  LassoNodeClass *class;
 
359
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
360
 
 
361
  class = LASSO_NODE_GET_CLASS(node);
 
362
  return class->get_children(node);
 
363
}
 
364
 
 
365
/**
 
366
 * lasso_node_get_content:
 
367
 * @node: a LassoNode
 
368
 * @err: return location for an allocated GError, or NULL to ignore errors
 
369
 * 
 
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
 
373
 * substituted.
 
374
 * 
 
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().
 
377
 **/
 
378
xmlChar *
 
379
lasso_node_get_content(LassoNode  *node,
 
380
                       GError    **err)
 
381
{
 
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);
 
388
  }
 
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);
 
394
  }
 
395
 
 
396
  class = LASSO_NODE_GET_CLASS(node);
 
397
  return class->get_content(node, err);
 
398
}
 
399
 
 
400
/**
 
401
 * lasso_node_get_name:
 
402
 * @node: a LassoNode
 
403
 * 
 
404
 * Gets the name of the node.
 
405
 * 
 
406
 * Return value: the name of the node
 
407
 **/
 
408
xmlChar *
 
409
lasso_node_get_name(LassoNode *node)
 
410
{
 
411
  LassoNodeClass *class;
 
412
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
413
 
 
414
  class = LASSO_NODE_GET_CLASS(node);
 
415
  return class->get_name(node);
 
416
}
 
417
 
 
418
/**
 
419
 * lasso_node_import:
 
420
 * @node: a LassoNode
 
421
 * @buffer: an XML buffer
 
422
 * 
 
423
 * Parses the XML buffer and loads it into the node.
 
424
 **/
 
425
void
 
426
lasso_node_import(LassoNode   *node,
 
427
                  const gchar *buffer)
 
428
{
 
429
  LassoNodeClass *class;
 
430
  g_return_if_fail(LASSO_IS_NODE(node));
 
431
 
 
432
  class = LASSO_NODE_GET_CLASS(node);
 
433
  class->import(node, buffer);
 
434
}
 
435
 
 
436
/**
 
437
 * lasso_node_import_from_node:
 
438
 * @node: a LassoNode
 
439
 * @imported_node: a LassoNode
 
440
 * 
 
441
 * Put a copy of node->private->node into imported_node->private->node
 
442
 **/
 
443
void
 
444
lasso_node_import_from_node(LassoNode *node,
 
445
                            LassoNode *imported_node)
 
446
{
 
447
  LassoNodeClass *class;
 
448
  g_return_if_fail(LASSO_IS_NODE(node));
 
449
 
 
450
  class = LASSO_NODE_GET_CLASS(node);
 
451
  class->import_from_node(node, imported_node);
 
452
}
 
453
 
 
454
/**
 
455
 * lasso_node_rename_prop:
 
456
 * @node: a LassoNode
 
457
 * @old_name: the attribute name
 
458
 * @new_name: the new attribute name
 
459
 * 
 
460
 * Renames an attribute of the node.
 
461
 **/
 
462
void
 
463
lasso_node_rename_prop(LassoNode     *node,
 
464
                       const xmlChar *old_name,
 
465
                       const xmlChar *new_name)
 
466
{
 
467
  LassoNodeClass *class;
 
468
  g_return_if_fail(LASSO_IS_NODE(node));
 
469
 
 
470
  class = LASSO_NODE_GET_CLASS(node);
 
471
  class->rename_prop(node, old_name, new_name);
 
472
}
 
473
 
 
474
/**
 
475
 * lasso_node_verify_signature:
 
476
 * @node: a LassoNode
 
477
 * @public_key_file: the public key
 
478
 * 
 
479
 * Verifys the node signature.
 
480
 * 
 
481
 * Return value: 1 if signature is valid, 0 if invalid or a negative value
 
482
 * if an error occurs.
 
483
 **/
 
484
gint
 
485
lasso_node_verify_signature(LassoNode   *node,
 
486
                            const gchar *public_key_file)
 
487
{
 
488
  LassoNodeClass *class;
 
489
 
 
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 */
 
493
 
 
494
  class = LASSO_NODE_GET_CLASS(node);
 
495
  return class->verify_signature(node, public_key_file);
 
496
}
 
497
 
 
498
/**
 
499
 * lasso_node_verify_x509_signature:
 
500
 * @node: a LassoNode
 
501
 * @ca_certificate_file: the trusted certificate
 
502
 * 
 
503
 * Verifys the node signature with X509 certificate.
 
504
 * 
 
505
 * Return value: 1 if signature is valid, 0 if invalid or a negative value
 
506
 * if an error occurs.
 
507
 **/
 
508
gint
 
509
lasso_node_verify_x509_signature(LassoNode   *node,
 
510
                                 const gchar *ca_certificate_file)
 
511
{
 
512
  LassoNodeClass *class;
 
513
 
 
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 */
 
517
 
 
518
  class = LASSO_NODE_GET_CLASS(node);
 
519
  return class->verify_x509_signature(node, ca_certificate_file);
 
520
}
 
521
 
 
522
/*****************************************************************************/
 
523
/* virtual private methods                                                   */
 
524
/*****************************************************************************/
 
525
 
 
526
static void
 
527
lasso_node_add_child(LassoNode *node,
 
528
                     LassoNode *child,
 
529
                     gboolean   unbounded)
 
530
{
 
531
  LassoNodeClass *class;
 
532
  g_return_if_fail(LASSO_IS_NODE(node));
 
533
 
 
534
  class = LASSO_NODE_GET_CLASS(node);
 
535
  class->add_child(node, child, unbounded);
 
536
}
 
537
 
 
538
static gint
 
539
lasso_node_add_signature(LassoNode     *node,
 
540
                         gint           sign_method,
 
541
                         const xmlChar *private_key_file,
 
542
                         const xmlChar *certificate_file)
 
543
{
 
544
  LassoNodeClass *class;
 
545
 
 
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 */
 
550
 
 
551
  class = LASSO_NODE_GET_CLASS(node);
 
552
  return (class->add_signature(node, sign_method, private_key_file,
 
553
                               certificate_file));
 
554
}
 
555
 
 
556
static gint
 
557
lasso_node_add_signature_tmpl(LassoNode            *node,
 
558
                              lassoSignatureType    sign_type,
 
559
                              lassoSignatureMethod  sign_method,
 
560
                              xmlChar              *reference_id)
 
561
{
 
562
  LassoNodeClass *class;
 
563
 
 
564
  g_return_val_if_fail(LASSO_IS_NODE(node),
 
565
                       LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
 
566
 
 
567
  class = LASSO_NODE_GET_CLASS(node);
 
568
  return class->add_signature_tmpl(node, sign_type, sign_method, reference_id);
 
569
}
 
570
 
 
571
static gchar *
 
572
lasso_node_build_query(LassoNode *node)
 
573
{
 
574
  LassoNodeClass *class;
 
575
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
576
 
 
577
  class = LASSO_NODE_GET_CLASS(node);
 
578
  return class->build_query(node);
 
579
}
 
580
 
 
581
static xmlNodePtr
 
582
lasso_node_get_xmlNode(LassoNode *node)
 
583
{
 
584
  LassoNodeClass *class;
 
585
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
586
 
 
587
  class = LASSO_NODE_GET_CLASS(node);
 
588
  return class->get_xmlNode(node);
 
589
}
 
590
 
 
591
/**
 
592
 * lasso_node_new_child:
 
593
 * @node: a LassoNode
 
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.
 
598
 * 
 
599
 * Add a new child in node.
 
600
 * This is an internal function and should not be called by application
 
601
 * directly.
 
602
 **/
 
603
static void
 
604
lasso_node_new_child(LassoNode     *node,
 
605
                     const xmlChar *name,
 
606
                     const xmlChar *content,
 
607
                     gboolean       unbounded)
 
608
{
 
609
  LassoNodeClass *class;
 
610
  g_return_if_fail(LASSO_IS_NODE(node)); 
 
611
 
 
612
  class = LASSO_NODE_GET_CLASS(node);
 
613
  class->new_child(node, name, content, unbounded);
 
614
}
 
615
 
 
616
static void
 
617
lasso_node_new_ns_prop(LassoNode     *node,
 
618
                       const xmlChar *name,
 
619
                       const xmlChar *value,
 
620
                       const xmlChar *href,
 
621
                       const xmlChar *prefix)
 
622
{
 
623
  LassoNodeClass *class;
 
624
  g_return_if_fail(LASSO_IS_NODE(node));
 
625
 
 
626
  class = LASSO_NODE_GET_CLASS(node);
 
627
  class->new_ns_prop(node, name, value, href, prefix);
 
628
}
 
629
 
 
630
static GData *
 
631
lasso_node_serialize(LassoNode *node,
 
632
                     GData     *gd)
 
633
{
 
634
  LassoNodeClass *class;
 
635
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
636
 
 
637
  class = LASSO_NODE_GET_CLASS(node);
 
638
  return class->serialize(node, gd);
 
639
}
 
640
 
 
641
static void
 
642
lasso_node_set_name(LassoNode     *node,
 
643
                    const xmlChar *name)
 
644
{
 
645
  LassoNodeClass *class;
 
646
  g_return_if_fail(LASSO_IS_NODE(node));
 
647
 
 
648
  class = LASSO_NODE_GET_CLASS(node);
 
649
  class->set_name(node, name);
 
650
}
 
651
 
 
652
static void
 
653
lasso_node_set_ns(LassoNode     *node,
 
654
                  const xmlChar *href,
 
655
                  const xmlChar *prefix)
 
656
{
 
657
  LassoNodeClass *class;
 
658
  g_return_if_fail(LASSO_IS_NODE(node));
 
659
 
 
660
  class = LASSO_NODE_GET_CLASS(node);
 
661
  class->set_ns(node, href, prefix);
 
662
}
 
663
 
 
664
static void
 
665
lasso_node_set_prop(LassoNode     *node,
 
666
                    const xmlChar *name,
 
667
                    const xmlChar *value)
 
668
{
 
669
  LassoNodeClass *class;
 
670
  g_return_if_fail(LASSO_IS_NODE(node));
 
671
 
 
672
  class = LASSO_NODE_GET_CLASS(node);
 
673
  class->set_prop(node, name, value);
 
674
}
 
675
 
 
676
static void
 
677
lasso_node_set_xmlNode(LassoNode *node,
 
678
                       xmlNodePtr libxml_node)
 
679
{
 
680
  LassoNodeClass *class;
 
681
  g_return_if_fail(LASSO_IS_NODE(node));
 
682
 
 
683
  class = LASSO_NODE_GET_CLASS(node);
 
684
  class->set_xmlNode(node, libxml_node);
 
685
}
 
686
 
 
687
static gint
 
688
lasso_node_sign_signature_tmpl(LassoNode     *node,
 
689
                               const xmlChar *private_key_file,
 
690
                               const xmlChar *certificate_file)
 
691
{
 
692
  LassoNodeClass *class;
 
693
 
 
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 */
 
698
 
 
699
  class = LASSO_NODE_GET_CLASS(node);
 
700
  class->sign_signature_tmpl(node, private_key_file, certificate_file);
 
701
 
 
702
  return 0;
 
703
}
 
704
 
 
705
/*****************************************************************************/
 
706
/* implementation methods                                                    */
 
707
/*****************************************************************************/
 
708
 
 
709
static LassoNode *
 
710
lasso_node_impl_copy(LassoNode *node)
 
711
{
 
712
  LassoNode *copy;
 
713
  
 
714
  copy = LASSO_NODE(g_object_new(G_OBJECT_TYPE(node), NULL));
 
715
  lasso_node_set_xmlNode(copy, xmlCopyNode(node->private->node, 1));
 
716
 
 
717
  return copy;
 
718
}
 
719
 
 
720
static void
 
721
lasso_node_impl_destroy(LassoNode *node)
 
722
{
 
723
  g_object_unref(G_OBJECT(node));
 
724
}
 
725
 
 
726
static gchar *
 
727
lasso_node_impl_dump(LassoNode     *node,
 
728
                     const xmlChar *encoding,
 
729
                     int            format)
 
730
{
 
731
  gchar *ret;
 
732
  xmlOutputBufferPtr buf;
 
733
  xmlCharEncodingHandlerPtr handler = NULL;
 
734
 
 
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);
 
738
 
 
739
  if (encoding != NULL) {
 
740
    handler = xmlFindCharEncodingHandler(encoding);
 
741
    if (handler == NULL) {
 
742
      return NULL;
 
743
    }
 
744
  }
 
745
  buf = xmlAllocOutputBuffer(handler);
 
746
  if (buf == NULL) {
 
747
    return NULL;
 
748
  }
 
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);
 
754
  }
 
755
  else {
 
756
    ret = g_strdup(buf->buffer->content);
 
757
  }
 
758
  xmlOutputBufferClose(buf);
 
759
 
 
760
  return ret;
 
761
}
 
762
 
 
763
static gchar *
 
764
lasso_node_impl_export(LassoNode *node)
 
765
{
 
766
  /* using lasso_node_impl_dump because dump method can be overrided */
 
767
  return lasso_node_impl_dump(node, "utf-8", 0);
 
768
}
 
769
 
 
770
static gchar *
 
771
lasso_node_impl_export_to_base64(LassoNode *node)
 
772
{
 
773
  gchar *buffer, *ret;
 
774
 
 
775
  buffer = lasso_node_impl_dump(node, "utf-8", 0);
 
776
  ret = xmlSecBase64Encode((const xmlSecByte *) buffer,
 
777
                           (xmlSecSize)strlen((const char *)buffer), 0);
 
778
  g_free(buffer);
 
779
  buffer = NULL;
 
780
 
 
781
  return ret;
 
782
}
 
783
 
 
784
static gchar *
 
785
lasso_node_impl_export_to_query(LassoNode            *node,
 
786
                                lassoSignatureMethod  sign_method,
 
787
                                const gchar          *private_key_file)
 
788
{
 
789
  GString *query;
 
790
  xmlDocPtr doc;
 
791
  xmlChar *str1, *str2, *str_escaped = NULL;
 
792
  gchar *unsigned_query, *ret;
 
793
 
 
794
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
795
  g_return_val_if_fail (private_key_file != NULL, NULL);
 
796
 
 
797
  unsigned_query = lasso_node_build_query(node);
 
798
  query = g_string_new(unsigned_query);
 
799
  g_free(unsigned_query);
 
800
  unsigned_query = NULL;
 
801
 
 
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);
 
808
      break;
 
809
    case lassoSignatureMethodDsaSha1:
 
810
      str_escaped = lasso_str_escape((xmlChar *)xmlSecHrefDsaSha1);
 
811
      break;
 
812
    }
 
813
    query = g_string_append(query, str_escaped);
 
814
    xmlFree(str_escaped);
 
815
    str_escaped = NULL;
 
816
 
 
817
    /* try to sign query */
 
818
    doc = lasso_str_sign(query->str, sign_method, private_key_file);
 
819
    if (doc != NULL) {
 
820
      /* get signature (base64 encoded) */
 
821
      str1 = lasso_doc_get_node_content(doc, xmlSecNodeSignatureValue);
 
822
      str2 = lasso_str_escape(str1);
 
823
      xmlFree(str1);
 
824
      str1 = NULL;
 
825
      xmlFreeDoc(doc);
 
826
    }
 
827
    else {
 
828
      g_string_free(query, TRUE);
 
829
      return NULL;
 
830
    }
 
831
 
 
832
    /* add signature in query */
 
833
    query = g_string_append(query, "&Signature=");
 
834
    query = g_string_append(query, str2);
 
835
    xmlFree(str2);
 
836
    str2 = NULL;
 
837
  }
 
838
 
 
839
  ret = g_strdup(query->str);
 
840
  g_string_free(query, TRUE);
 
841
  return ret;
 
842
}
 
843
 
 
844
static gchar *
 
845
lasso_node_impl_export_to_soap(LassoNode *node)
 
846
{
 
847
  LassoNode *envelope, *body, *copy_node;
 
848
  gchar *buffer;
 
849
 
 
850
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
851
  
 
852
  envelope = lasso_node_new();
 
853
  lasso_node_set_name(envelope, "Envelope");
 
854
  lasso_node_set_ns(envelope, lassoSoapEnvHRef, lassoSoapEnvPrefix);
 
855
 
 
856
  copy_node = lasso_node_copy(node);
 
857
  
 
858
  body = lasso_node_new();
 
859
  lasso_node_set_name(body, "Body");
 
860
  lasso_node_set_ns(body, lassoSoapEnvHRef, lassoSoapEnvPrefix);
 
861
  
 
862
  lasso_node_add_child(body, copy_node, FALSE);
 
863
  lasso_node_add_child(envelope, body, FALSE);
 
864
 
 
865
  buffer = lasso_node_export(envelope);
 
866
 
 
867
  lasso_node_destroy(copy_node);
 
868
  lasso_node_destroy(body);
 
869
  lasso_node_destroy(envelope);
 
870
  
 
871
  return buffer;
 
872
}
 
873
 
 
874
static LassoAttr*
 
875
lasso_node_impl_get_attr(LassoNode      *node,
 
876
                         const xmlChar  *name,
 
877
                         GError        **err)
 
878
{
 
879
  LassoAttr *prop;
 
880
 
 
881
  if (name == NULL) {
 
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);
 
886
  }
 
887
 
 
888
  prop = node->private->node->properties;
 
889
  while (prop != NULL) {
 
890
    if (xmlStrEqual(prop->name, name)) {
 
891
      return prop;
 
892
    }
 
893
    prop = prop->next;
 
894
  }
 
895
 
 
896
  /* attr not found */
 
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);
 
901
  return NULL;
 
902
}
 
903
 
 
904
static xmlChar *
 
905
lasso_node_impl_get_attr_value(LassoNode      *node,
 
906
                               const xmlChar  *name,
 
907
                               GError        **err)
 
908
{
 
909
  xmlChar *value;
 
910
  if (name == NULL) {
 
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);
 
915
  }
 
916
 
 
917
  value = xmlGetProp(node->private->node, name);
 
918
 
 
919
  if (value == NULL) {
 
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);
 
924
  }
 
925
 
 
926
  return value;
 
927
}
 
928
 
 
929
static GPtrArray *
 
930
lasso_node_impl_get_attrs(LassoNode *node)
 
931
{
 
932
  GPtrArray *attributes = NULL;
 
933
  LassoAttr *prop;
 
934
 
 
935
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
936
 
 
937
  prop = node->private->node->properties;
 
938
  if (prop != NULL)
 
939
    attributes = g_ptr_array_new();
 
940
 
 
941
  while (prop != NULL) {
 
942
    g_ptr_array_add(attributes, prop);
 
943
    prop = prop->next;
 
944
  }
 
945
 
 
946
  return attributes;
 
947
}
 
948
 
 
949
static LassoNode *
 
950
lasso_node_impl_get_child(LassoNode      *node,
 
951
                          const xmlChar  *name,
 
952
                          const xmlChar  *href,
 
953
                          GError        **err)
 
954
{
 
955
  xmlNodePtr child;
 
956
 
 
957
  if (name == NULL) {
 
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);
 
962
  }
 
963
 
 
964
  /*   /\* No recurssive version *\/ */
 
965
  /*   xmlNodePtr cur; */
 
966
  
 
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)); */
 
972
  /*       } */
 
973
  /*     } */
 
974
  /*     cur = cur->next; */
 
975
  /*   } */
 
976
  /*   return (NULL); */
 
977
 
 
978
  /*   /\* Recurssive version *\/ */
 
979
  /*   xmlNodePtr cur; */
 
980
  /*   LassoNode *ret, *child; */
 
981
  
 
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)); */
 
986
  /*     } */
 
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) { */
 
991
  /*    return (ret); */
 
992
  /*       } */
 
993
  /*     } */
 
994
  /*     cur = cur->next; */
 
995
  /*   } */
 
996
  /*   return (NULL); */
 
997
 
 
998
  if (href != NULL) {
 
999
    child = xmlSecFindNode(node->private->node, name, href);
 
1000
  }
 
1001
  else {
 
1002
    child = xmlSecFindNode(node->private->node, name, href);
 
1003
    if (child == NULL)
 
1004
      child = xmlSecFindNode(node->private->node, name, lassoLibHRef);
 
1005
    if (child == NULL)
 
1006
      child = xmlSecFindNode(node->private->node, name, lassoSamlAssertionHRef);
 
1007
    if (child == NULL)
 
1008
      child = xmlSecFindNode(node->private->node, name, lassoSamlProtocolHRef);
 
1009
    if (child == NULL)
 
1010
      child = xmlSecFindNode(node->private->node, name, lassoSoapEnvHRef);
 
1011
    if (child == NULL)
 
1012
      child = xmlSecFindNode(node->private->node, name, lassoMetadataHRef);
 
1013
    if (child == NULL)
 
1014
      child = xmlSecFindNode(node->private->node, name, lassoLassoHRef);
 
1015
  }
 
1016
  if (child != NULL) {
 
1017
    return lasso_node_new_from_xmlNode(child);
 
1018
  }
 
1019
  else {
 
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);
 
1024
    return NULL;
 
1025
  }
 
1026
}
 
1027
 
 
1028
static xmlChar *
 
1029
lasso_node_impl_get_child_content(LassoNode      *node,
 
1030
                                  const xmlChar  *name,
 
1031
                                  const xmlChar  *href,
 
1032
                                  GError        **err)
 
1033
{
 
1034
  GError    *tmp_err = NULL;
 
1035
  LassoNode *child;
 
1036
  xmlChar   *content = NULL;
 
1037
 
 
1038
  if (name == 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);
 
1043
  }
 
1044
 
 
1045
  child = lasso_node_get_child(node, name, href, &tmp_err);
 
1046
 
 
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);
 
1052
    }
 
1053
  }
 
1054
  else {
 
1055
    g_propagate_error (err, tmp_err);
 
1056
  }
 
1057
 
 
1058
  return content;
 
1059
}
 
1060
 
 
1061
static GPtrArray *
 
1062
lasso_node_impl_get_children(LassoNode *node)
 
1063
{
 
1064
  GPtrArray *children = NULL;
 
1065
  xmlNodePtr cur;
 
1066
 
 
1067
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
1068
 
 
1069
  cur = node->private->node->children;
 
1070
  if (cur != NULL)
 
1071
    children = g_ptr_array_new();
 
1072
  
 
1073
  while (cur != NULL) {
 
1074
    g_ptr_array_add(children, lasso_node_new_from_xmlNode(cur));
 
1075
    cur = cur->next;
 
1076
  }
 
1077
 
 
1078
  return children;
 
1079
}
 
1080
 
 
1081
static xmlChar *
 
1082
lasso_node_impl_get_content(LassoNode  *node,
 
1083
                            GError    **err)
 
1084
{
 
1085
  xmlChar *content;
 
1086
 
 
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);
 
1093
  }
 
1094
 
 
1095
  return content;
 
1096
}
 
1097
 
 
1098
static xmlChar *
 
1099
lasso_node_impl_get_name(LassoNode *node)
 
1100
{
 
1101
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
1102
 
 
1103
  return xmlStrdup(node->private->node->name);
 
1104
}
 
1105
 
 
1106
static void
 
1107
lasso_node_impl_import(LassoNode   *node,
 
1108
                       const gchar *buffer)
 
1109
{
 
1110
  xmlDocPtr doc;
 
1111
  xmlNodePtr root;
 
1112
 
 
1113
  g_return_if_fail (LASSO_IS_NODE(node));
 
1114
  g_return_if_fail (buffer != NULL);
 
1115
 
 
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);
 
1120
  /* free doc */
 
1121
  xmlFreeDoc(doc);
 
1122
}
 
1123
 
 
1124
static void
 
1125
lasso_node_impl_import_from_node(LassoNode *node,
 
1126
                                 LassoNode *imported_node)
 
1127
{
 
1128
  g_return_if_fail (LASSO_IS_NODE(node));
 
1129
  g_return_if_fail (LASSO_IS_NODE(imported_node));
 
1130
 
 
1131
  lasso_node_set_xmlNode(node, xmlCopyNode(imported_node->private->node, 1));
 
1132
}
 
1133
 
 
1134
static void
 
1135
lasso_node_impl_rename_prop(LassoNode     *node,
 
1136
                            const xmlChar *old_name,
 
1137
                            const xmlChar *new_name)
 
1138
{
 
1139
  xmlChar *value;
 
1140
 
 
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);
 
1144
 
 
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);
 
1149
  }
 
1150
}
 
1151
 
 
1152
static gint
 
1153
lasso_node_impl_verify_signature(LassoNode   *node,
 
1154
                                 const gchar *public_key_file)
 
1155
{
 
1156
  xmlDocPtr doc = NULL;
 
1157
  xmlNodePtr xmlNode = NULL;
 
1158
  xmlNodePtr signature = NULL;
 
1159
  xmlSecDSigCtxPtr dsigCtx = NULL;
 
1160
  xmlIDPtr id;
 
1161
  xmlAttrPtr id_attr;
 
1162
  xmlChar *id_value;
 
1163
  gint ret = 0;
 
1164
 
 
1165
  g_return_val_if_fail(public_key_file != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
 
1166
 
 
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);
 
1171
 
 
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);
 
1177
    xmlFree(id_value);
 
1178
  }
 
1179
 
 
1180
  /* find start node */
 
1181
  signature = xmlSecFindNode(xmlNode, xmlSecNodeSignature, 
 
1182
                             xmlSecDSigNs);
 
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;
 
1188
    goto done;  
 
1189
  }
 
1190
 
 
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;
 
1197
    goto done;
 
1198
  }
 
1199
 
 
1200
  /* load public key */
 
1201
  dsigCtx->signKey = xmlSecCryptoAppKeyLoad(public_key_file,
 
1202
                                            xmlSecKeyDataFormatPem,
 
1203
                                            NULL, NULL, NULL);
 
1204
  if(dsigCtx->signKey == NULL) {
 
1205
    message(G_LOG_LEVEL_CRITICAL,
 
1206
            lasso_strerror(LASSO_DS_ERROR_PUBLIC_KEY_LOAD_FAILED),
 
1207
            public_key_file);
 
1208
    ret = LASSO_DS_ERROR_PUBLIC_KEY_LOAD_FAILED;
 
1209
    goto done;
 
1210
  }
 
1211
 
 
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;
 
1218
    goto done;
 
1219
  }
 
1220
 
 
1221
  if (dsigCtx->status == xmlSecDSigStatusSucceeded) {
 
1222
    ret = 0;
 
1223
  }
 
1224
  else {
 
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;
 
1229
  }
 
1230
 
 
1231
 done:
 
1232
  /* cleanup */
 
1233
  if(dsigCtx != NULL) {
 
1234
    xmlSecDSigCtxDestroy(dsigCtx);
 
1235
  }
 
1236
  /* FIXME xmlFreeDoc(doc); */
 
1237
  return ret;
 
1238
}
 
1239
 
 
1240
static gint
 
1241
lasso_node_impl_verify_x509_signature(LassoNode   *node,
 
1242
                                      const gchar *ca_certificate_file)
 
1243
{
 
1244
  xmlDocPtr doc = NULL;
 
1245
  xmlNodePtr xmlNode = NULL;
 
1246
  xmlNodePtr signature = NULL;
 
1247
  xmlSecKeysMngrPtr mngr = NULL;
 
1248
  xmlSecDSigCtxPtr dsigCtx = NULL;
 
1249
  xmlIDPtr id;
 
1250
  xmlAttrPtr id_attr;
 
1251
  xmlChar *id_value;
 
1252
  gint ret = 0;
 
1253
 
 
1254
  g_return_val_if_fail(ca_certificate_file != NULL,
 
1255
                       LASSO_PARAM_ERROR_INVALID_VALUE);
 
1256
 
 
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);
 
1261
 
 
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);
 
1267
    xmlFree(id_value);
 
1268
  }
 
1269
 
 
1270
  /* find start node */
 
1271
  signature = xmlSecFindNode(xmlNode, xmlSecNodeSignature, 
 
1272
                             xmlSecDSigNs);
 
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;
 
1278
    goto done;  
 
1279
  }
 
1280
 
 
1281
  /* create simple keys mngr */
 
1282
  mngr = xmlSecKeysMngrCreate();
 
1283
  if (mngr == NULL) {
 
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;
 
1287
    goto done;
 
1288
  }
 
1289
 
 
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;
 
1294
    goto done;
 
1295
  }
 
1296
  
 
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;
 
1305
    goto done;
 
1306
  }
 
1307
 
 
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;
 
1314
    goto done;
 
1315
  }
 
1316
 
 
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;
 
1323
    goto done;
 
1324
  }
 
1325
 
 
1326
  if (dsigCtx->status == xmlSecDSigStatusSucceeded) {
 
1327
    ret = 0;
 
1328
  }
 
1329
  else {
 
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;
 
1334
  }
 
1335
 
 
1336
 done:
 
1337
  /* cleanup */
 
1338
  if(dsigCtx != NULL) {
 
1339
    xmlSecDSigCtxDestroy(dsigCtx);
 
1340
  }
 
1341
  if(mngr != NULL) {
 
1342
    xmlSecKeysMngrDestroy(mngr);
 
1343
  }
 
1344
  /* FIXME xmlFreeDoc(doc); */
 
1345
  return ret;
 
1346
}
 
1347
 
 
1348
/*** private methods **********************************************************/
 
1349
 
 
1350
static void
 
1351
lasso_node_impl_add_child(LassoNode *node,
 
1352
                          LassoNode *child,
 
1353
                          gboolean   unbounded)
 
1354
{
 
1355
  xmlNodePtr old_child = NULL;
 
1356
  const xmlChar *href = NULL;
 
1357
 
 
1358
  g_return_if_fail (LASSO_IS_NODE(node));
 
1359
  g_return_if_fail (LASSO_IS_NODE(child));
 
1360
 
 
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;
 
1365
    }
 
1366
    old_child = xmlSecFindNode(node->private->node,
 
1367
                               child->private->node->name,
 
1368
                               href);
 
1369
  }
 
1370
 
 
1371
  if (unbounded == FALSE && old_child != NULL) {
 
1372
    /* child replace old child */
 
1373
    xmlReplaceNode(old_child, child->private->node);
 
1374
  }
 
1375
  else {
 
1376
    /* else child is added */
 
1377
    xmlAddChild(node->private->node, child->private->node);
 
1378
  }
 
1379
  child->private->node_is_weak_ref = TRUE;
 
1380
}
 
1381
 
 
1382
static gint
 
1383
lasso_node_impl_add_signature(LassoNode     *node,
 
1384
                              gint           sign_method,
 
1385
                              const xmlChar *private_key_file,
 
1386
                              const xmlChar *certificate_file)
 
1387
{
 
1388
  gint ret = 0;
 
1389
 
 
1390
  g_return_val_if_fail (private_key_file != NULL,
 
1391
                        LASSO_PARAM_ERROR_INVALID_VALUE);
 
1392
 
 
1393
  if (certificate_file != NULL) {
 
1394
    ret = lasso_node_add_signature_tmpl(node, lassoSignatureTypeWithX509, sign_method, 0);
 
1395
  }
 
1396
  else {
 
1397
    ret = lasso_node_add_signature_tmpl(node, lassoSignatureTypeSimple, sign_method, 0);
 
1398
  }
 
1399
  if (ret == 0) {
 
1400
    ret = lasso_node_sign_signature_tmpl(node, private_key_file, certificate_file);
 
1401
  }
 
1402
 
 
1403
  return ret;
 
1404
}
 
1405
 
 
1406
static gint
 
1407
lasso_node_impl_add_signature_tmpl(LassoNode            *node,
 
1408
                                   lassoSignatureType    sign_type,
 
1409
                                   lassoSignatureMethod  sign_method,
 
1410
                                   xmlChar              *reference_uri)
 
1411
{
 
1412
  LassoNode *sign_node;
 
1413
  xmlDocPtr  doc;
 
1414
  xmlNodePtr signature, reference, key_info;
 
1415
  char   *uri;
 
1416
 
 
1417
  g_return_val_if_fail(sign_method == lassoSignatureMethodRsaSha1 || \
 
1418
                       sign_method == lassoSignatureMethodDsaSha1,
 
1419
                       LASSO_PARAM_ERROR_INVALID_VALUE);
 
1420
 
 
1421
  doc = xmlNewDoc("1.0");
 
1422
  xmlAddChild((xmlNodePtr)doc, lasso_node_get_xmlNode(node));
 
1423
 
 
1424
  switch (sign_method) {
 
1425
  case lassoSignatureMethodRsaSha1:
 
1426
    signature = xmlSecTmplSignatureCreate(doc, xmlSecTransformExclC14NId,
 
1427
                                          xmlSecTransformRsaSha1Id, NULL);
 
1428
    break;
 
1429
  case lassoSignatureMethodDsaSha1:
 
1430
    signature = xmlSecTmplSignatureCreate(doc, xmlSecTransformExclC14NId,
 
1431
                                          xmlSecTransformDsaSha1Id, NULL);
 
1432
    break;
 
1433
  default:
 
1434
    signature = NULL;
 
1435
  }
 
1436
 
 
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;
 
1440
  }
 
1441
 
 
1442
/*   uri = xmlMalloc(strlen(reference_uri)+1+1); */
 
1443
/*   g_sprintf(uri, "#%s", reference_uri); */
 
1444
 
 
1445
  if (reference_uri != NULL) {
 
1446
    uri = xmlMalloc(strlen(reference_uri)+1+1);
 
1447
    g_sprintf(uri, "#%s", reference_uri);
 
1448
  }
 
1449
  else {
 
1450
    uri = NULL;
 
1451
  }
 
1452
  reference = xmlSecTmplSignatureAddReference(signature,
 
1453
                                              xmlSecTransformSha1Id,
 
1454
                                              NULL, uri, NULL);
 
1455
 
 
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;
 
1460
  }
 
1461
 
 
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;
 
1467
  }
 
1468
 
 
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;
 
1475
  }
 
1476
  
 
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;
 
1483
    }
 
1484
  }
 
1485
 
 
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);
 
1490
 
 
1491
  /* xmlUnlinkNode(lasso_node_get_xmlNode(node)); */
 
1492
  /* xmlFreeDoc(doc); */
 
1493
 
 
1494
  return 0;
 
1495
}
 
1496
 
 
1497
static void
 
1498
gdata_build_query_foreach_func(GQuark   key_id,
 
1499
                               gpointer data,
 
1500
                               gpointer user_data)
 
1501
{
 
1502
  guint i;
 
1503
  GString *str;
 
1504
  GPtrArray *array;
 
1505
 
 
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, " ");
 
1512
    }
 
1513
  }
 
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);
 
1518
}
 
1519
 
 
1520
static gchar *
 
1521
lasso_node_impl_build_query(LassoNode *node)
 
1522
{
 
1523
  guint i, j;
 
1524
  GData *gd;
 
1525
  GPtrArray *a, *aa;
 
1526
  GString *query;
 
1527
  xmlChar *str_escaped;
 
1528
  gchar   *ret;
 
1529
 
 
1530
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
1531
 
 
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);
 
1537
  
 
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);
 
1546
    str_escaped = NULL;
 
1547
    if (i<a->len - 1) {
 
1548
      query = g_string_append(query, "&");
 
1549
    }
 
1550
    /* free allocated memory for array aa */
 
1551
    for (j=0; j<aa->len; j++) {
 
1552
      g_free(aa->pdata[j]);
 
1553
    }
 
1554
    g_ptr_array_free(aa, TRUE);
 
1555
  }
 
1556
  /* free allocated memory for array a */
 
1557
  g_ptr_array_free(a, TRUE);
 
1558
  g_datalist_clear(&gd);
 
1559
 
 
1560
  ret = g_strdup(query->str);
 
1561
  g_string_free(query, TRUE);
 
1562
  
 
1563
  return ret;
 
1564
}
 
1565
 
 
1566
static xmlNodePtr
 
1567
lasso_node_impl_get_xmlNode(LassoNode *node)
 
1568
{
 
1569
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
1570
 
 
1571
  return node->private->node;
 
1572
}
 
1573
 
 
1574
static void
 
1575
lasso_node_impl_new_child(LassoNode     *node,
 
1576
                          const xmlChar *name,
 
1577
                          const xmlChar *content,
 
1578
                          gboolean       unbounded)
 
1579
{
 
1580
  /* LassoNode *old_child = NULL; */
 
1581
  xmlNodePtr old_child = NULL;
 
1582
  const xmlChar *href = NULL;
 
1583
 
 
1584
  g_return_if_fail (LASSO_IS_NODE(node));
 
1585
  g_return_if_fail (name != NULL);
 
1586
  g_return_if_fail (content != NULL);
 
1587
  
 
1588
  if (!unbounded) {
 
1589
    if (node->private->node->ns != NULL) {
 
1590
      href = node->private->node->ns->href;
 
1591
    }
 
1592
    old_child = xmlSecFindNode(node->private->node, name, href);
 
1593
    /* old_child = lasso_node_get_child(node, name); */
 
1594
  }
 
1595
 
 
1596
  if (!unbounded && old_child != NULL) {
 
1597
    /* xmlNodeSetContent(old_child->private->node, content); */
 
1598
    xmlNodeSetContent(old_child, content);
 
1599
  }
 
1600
  else {
 
1601
    xmlNewTextChild(node->private->node, NULL, name, content);
 
1602
  }
 
1603
}
 
1604
 
 
1605
static void
 
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)
 
1611
{
 
1612
  xmlNsPtr ns;
 
1613
 
 
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);
 
1617
 
 
1618
  ns = xmlNewNs(node->private->node, href, prefix);
 
1619
  xmlNewNsProp(node->private->node, ns, name, value);
 
1620
}
 
1621
 
 
1622
static void
 
1623
gdata_serialize_destroy_notify(gpointer data)
 
1624
{
 
1625
  gint i;
 
1626
  GPtrArray *array = data;
 
1627
 
 
1628
  for (i=0; i<array->len; i++) {
 
1629
    xmlFree(array->pdata[i]);
 
1630
    array->pdata[i] = NULL;
 
1631
  }
 
1632
  g_ptr_array_free(array, TRUE);
 
1633
}
 
1634
 
 
1635
static GData *
 
1636
lasso_node_impl_serialize(LassoNode *node,
 
1637
                          GData     *gd)
 
1638
{
 
1639
  GPtrArray *attrs, *children;
 
1640
  GPtrArray *values;
 
1641
  xmlChar *name;
 
1642
  xmlChar *val;
 
1643
  int i;
 
1644
 
 
1645
  g_return_val_if_fail (LASSO_IS_NODE(node), NULL);
 
1646
 
 
1647
  if (gd == NULL) {
 
1648
    g_datalist_init(&gd);
 
1649
  }
 
1650
 
 
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);
 
1662
    }
 
1663
    g_ptr_array_free(attrs, TRUE);
 
1664
  }
 
1665
 
 
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);
 
1673
        break;
 
1674
      case XML_TEXT_NODE:
 
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);
 
1680
        if (val == NULL) {
 
1681
          break;
 
1682
        }
 
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);
 
1689
        }
 
1690
        else {
 
1691
          g_ptr_array_add(values, val);
 
1692
        }
 
1693
        xmlFree(name);
 
1694
        name = NULL;
 
1695
        break;
 
1696
      default:
 
1697
        break;
 
1698
      }
 
1699
      lasso_node_destroy((LassoNode *)g_ptr_array_index(children, i));
 
1700
    }
 
1701
    g_ptr_array_free(children, TRUE);
 
1702
  }
 
1703
    
 
1704
  return gd;
 
1705
}
 
1706
 
 
1707
static void
 
1708
lasso_node_impl_set_name(LassoNode     *node,
 
1709
                         const xmlChar *name)
 
1710
{
 
1711
  g_return_if_fail (LASSO_IS_NODE(node));
 
1712
  g_return_if_fail (name != NULL);
 
1713
 
 
1714
  xmlNodeSetName(node->private->node, name);
 
1715
}
 
1716
 
 
1717
static void
 
1718
lasso_node_impl_set_ns(LassoNode     *node,
 
1719
                       const xmlChar *href,
 
1720
                       const xmlChar *prefix)
 
1721
{
 
1722
  xmlNsPtr new_ns;
 
1723
 
 
1724
  g_return_if_fail (LASSO_IS_NODE(node));
 
1725
  g_return_if_fail (href != NULL || prefix != NULL);
 
1726
 
 
1727
  /*   xmlNsPtr cur; */
 
1728
  /*   cur = node->private->node->ns; */
 
1729
  /*   while (cur != NULL) { */
 
1730
  /*     printf("%s:%s\n", cur->prefix, cur->href); */
 
1731
  /*     cur = cur->next; */
 
1732
  /*   } */
 
1733
  /*   cur = node->private->node->nsDef; */
 
1734
  /*   while (cur != NULL) { */
 
1735
  /*     printf("%s:%s\n", cur->prefix, cur->href); */
 
1736
  /*     cur = cur->next; */
 
1737
  /*   } */
 
1738
 
 
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;
 
1743
}
 
1744
 
 
1745
static void
 
1746
lasso_node_impl_set_prop(LassoNode     *node,
 
1747
                         const xmlChar *name,
 
1748
                         const xmlChar *value)
 
1749
{
 
1750
  g_return_if_fail (LASSO_IS_NODE(node));
 
1751
  g_return_if_fail (name != NULL);
 
1752
  g_return_if_fail (value != NULL);
 
1753
 
 
1754
  xmlSetProp(node->private->node, name, value);
 
1755
}
 
1756
 
 
1757
static void
 
1758
lasso_node_impl_set_xmlNode(LassoNode  *node,
 
1759
                            xmlNodePtr  libxml_node)
 
1760
{
 
1761
  g_return_if_fail (LASSO_IS_NODE(node));
 
1762
  g_return_if_fail (libxml_node != NULL);
 
1763
 
 
1764
  xmlFreeNode(node->private->node);
 
1765
  node->private->node = libxml_node;
 
1766
}
 
1767
 
 
1768
gint
 
1769
lasso_node_impl_sign_signature_tmpl(LassoNode     *node,
 
1770
                                    const xmlChar *private_key_file,
 
1771
                                    const xmlChar *certificate_file)
 
1772
{
 
1773
  xmlDocPtr doc;
 
1774
  xmlNodePtr signature_tmpl;
 
1775
  xmlSecDSigCtxPtr dsig_ctx;
 
1776
  gint ret = 0;
 
1777
 
 
1778
  g_return_val_if_fail(private_key_file != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
 
1779
 
 
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, 
 
1784
                                  xmlSecDSigNs);
 
1785
 
 
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;
 
1792
  }
 
1793
  
 
1794
  /* load private key, assuming that there is not password */
 
1795
  dsig_ctx->signKey = xmlSecCryptoAppKeyLoad(private_key_file,
 
1796
                                             xmlSecKeyDataFormatPem,
 
1797
                                             NULL, NULL, NULL);
 
1798
  if (dsig_ctx->signKey == NULL) {
 
1799
    message(G_LOG_LEVEL_CRITICAL,
 
1800
            lasso_strerror(LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED),
 
1801
            private_key_file);
 
1802
    ret = LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED;
 
1803
    goto done;
 
1804
  }
 
1805
  
 
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),
 
1812
              certificate_file);
 
1813
      ret = LASSO_DS_ERROR_CERTIFICATE_LOAD_FAILED;
 
1814
      goto done;
 
1815
    }
 
1816
  }
 
1817
 
 
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;
 
1824
  }
 
1825
 
 
1826
 done:
 
1827
  xmlSecDSigCtxDestroy(dsig_ctx);
 
1828
  /* FIXME */
 
1829
  /* xmlUnlinkNode(lasso_node_get_xmlNode(node)); */
 
1830
  /* xmlFreeDoc(doc); */
 
1831
 
 
1832
  return ret;
 
1833
}
 
1834
 
 
1835
/*****************************************************************************/
 
1836
/* overrided parent class methods                                            */
 
1837
/*****************************************************************************/
 
1838
 
 
1839
static void
 
1840
lasso_node_dispose(LassoNode *node)
 
1841
{
 
1842
  if (node->private->dispose_has_run == TRUE) {
 
1843
    return;
 
1844
  }
 
1845
  node->private->dispose_has_run = TRUE;
 
1846
 
 
1847
  if (node->private->node->name != NULL) {
 
1848
    debug("%s 0x%x disposed ...\n", node->private->node->name, node);
 
1849
  }
 
1850
  /* unref reference counted objects */
 
1851
  /* we don't have any here */
 
1852
 
 
1853
  parent_class->dispose(G_OBJECT(node));
 
1854
}
 
1855
 
 
1856
static void
 
1857
lasso_node_finalize(LassoNode *node)
 
1858
{
 
1859
  if (node->private->node->name != NULL) {
 
1860
    debug("%s 0x%x finalized ...\n", node->private->node->name, node);
 
1861
  }
 
1862
 
 
1863
  if (node->private->node_is_weak_ref == FALSE) {
 
1864
    xmlUnlinkNode(node->private->node);
 
1865
    xmlFreeNode(node->private->node);
 
1866
    node->private->node = NULL;
 
1867
  }
 
1868
 
 
1869
  g_free (node->private);
 
1870
  node->private = NULL;
 
1871
 
 
1872
  parent_class->finalize(G_OBJECT(node));
 
1873
}
 
1874
 
 
1875
/*****************************************************************************/
 
1876
/* instance and class init functions                                         */
 
1877
/*****************************************************************************/
 
1878
 
 
1879
static void
 
1880
lasso_node_instance_init(LassoNode *instance)
 
1881
{
 
1882
  LassoNode *node = LASSO_NODE(instance);
 
1883
 
 
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");
 
1888
}
 
1889
 
 
1890
static void
 
1891
lasso_node_class_init(LassoNodeClass *class)
 
1892
{
 
1893
  GObjectClass *gobject_class = G_OBJECT_CLASS(class);
 
1894
  
 
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;
 
1934
}
 
1935
 
 
1936
GType lasso_node_get_type() {
 
1937
  static GType this_type = 0;
 
1938
 
 
1939
  if (!this_type) {
 
1940
    static const GTypeInfo this_info = {
 
1941
      sizeof (LassoNodeClass),
 
1942
      NULL,
 
1943
      NULL,
 
1944
      (GClassInitFunc) lasso_node_class_init,
 
1945
      NULL,
 
1946
      NULL,
 
1947
      sizeof(LassoNode),
 
1948
      0,
 
1949
      (GInstanceInitFunc) lasso_node_instance_init,
 
1950
    };
 
1951
    
 
1952
    this_type = g_type_register_static(G_TYPE_OBJECT , "LassoNode",
 
1953
                                       &this_info, 0);
 
1954
  }
 
1955
  return this_type;
 
1956
}
 
1957
 
 
1958
/**
 
1959
 * lasso_node_new:
 
1960
 * 
 
1961
 * The main LassoNode constructor.
 
1962
 * 
 
1963
 * Return value: a new node
 
1964
 **/
 
1965
LassoNode*
 
1966
lasso_node_new()
 
1967
{
 
1968
  return LASSO_NODE(g_object_new(LASSO_TYPE_NODE, NULL));
 
1969
}
 
1970
 
 
1971
/**
 
1972
 * lasso_node_new_from_dump:
 
1973
 * @buffer: a buffer
 
1974
 * 
 
1975
 * Builds a new LassoNode from an LassoNode dump.
 
1976
 * 
 
1977
 * Return value: a new node
 
1978
 **/
 
1979
LassoNode*
 
1980
lasso_node_new_from_dump(const gchar *buffer)
 
1981
{
 
1982
  LassoNode *node;
 
1983
  xmlDocPtr  doc;
 
1984
  xmlNodePtr root;
 
1985
 
 
1986
  g_return_val_if_fail (buffer != NULL, NULL);
 
1987
 
 
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);
 
1994
  /* free doc */
 
1995
  xmlFreeDoc(doc);
 
1996
 
 
1997
  return node;
 
1998
}
 
1999
 
 
2000
/**
 
2001
 * lasso_node_new_from_xmlNode:
 
2002
 * @node: an xmlNode
 
2003
 * 
 
2004
 * Builds a new LassoNode from an xmlNode.
 
2005
 * 
 
2006
 * Return value: a new node
 
2007
 **/
 
2008
LassoNode*
 
2009
lasso_node_new_from_xmlNode(xmlNodePtr node)
 
2010
{
 
2011
  LassoNode *lasso_node;
 
2012
 
 
2013
  g_return_val_if_fail (node != NULL, NULL);
 
2014
 
 
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;
 
2018
 
 
2019
  return lasso_node;
 
2020
}