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

« back to all changes in this revision

Viewing changes to lasso/environs/logout.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: logout.c,v 1.124 2004/09/07 14:25:55 nclapies 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 <lasso/environs/logout.h>
 
31
#include <lasso/xml/errors.h>
 
32
 
 
33
#define LASSO_LOGOUT_NODE            "LassoLogout"
 
34
#define LASSO_REMOTE_PROVIDERID_NODE "RemoteProviderID"
 
35
 
 
36
static GObjectClass *parent_class = NULL;
 
37
 
 
38
struct _LassoLogoutPrivate
 
39
{
 
40
  gboolean dispose_has_run;
 
41
};
 
42
 
 
43
/*****************************************************************************/
 
44
/* public methods                                                            */
 
45
/*****************************************************************************/
 
46
 
 
47
/**
 
48
 * lasso_logout_build_request_msg:
 
49
 * @logout: the logout object
 
50
 * 
 
51
 * This method builds the logout request message.
 
52
 *
 
53
 * It gets the single logout protocol profile of the remote provider and :
 
54
 *    if it is a SOAP method, then it builds the logout request SOAP message,
 
55
 *    sets the msg_body attribute, gets the single logout service url
 
56
 *    and sets the msg_url attribute of the logout object.
 
57
 *
 
58
 *    if it is a HTTP-Redirect method, then it builds the logout request QUERY message,
 
59
 *    builds the logout request url, sets the msg_url to the logout request url,
 
60
 *    sets the msg_body to NULL
 
61
 *
 
62
 * Optionaly ( if private key and certificates paths are set in server object )
 
63
 *    it signs the message (with X509 if a SOAP message,
 
64
 *    else with simple signature if a QUERY message )
 
65
 * 
 
66
 * Return value: 0 if ok, else < 0
 
67
 **/
 
68
gint
 
69
lasso_logout_build_request_msg(LassoLogout *logout)
 
70
{
 
71
  LassoProfile     *profile;
 
72
  LassoProvider    *provider;
 
73
  xmlChar          *protocolProfile = NULL;
 
74
  GError           *err = NULL;
 
75
  gchar            *url = NULL, *query = NULL;
 
76
  lassoProviderType remote_provider_type;
 
77
  gint              ret = 0;
 
78
 
 
79
  g_return_val_if_fail(LASSO_IS_LOGOUT(logout), -1);
 
80
  
 
81
  profile = LASSO_PROFILE(logout);
 
82
 
 
83
  /* get the remote provider type and get the remote provider object */
 
84
  if (profile->provider_type == lassoProviderTypeSp) {
 
85
    remote_provider_type = lassoProviderTypeIdp;
 
86
  }
 
87
  else if (profile->provider_type == lassoProviderTypeIdp) {
 
88
    remote_provider_type = lassoProviderTypeSp;
 
89
  }
 
90
  else {
 
91
    message(G_LOG_LEVEL_CRITICAL, "Invalid provider type\n");
 
92
    ret = -1;
 
93
    goto done;
 
94
  }
 
95
  provider = lasso_server_get_provider_ref(profile->server, profile->remote_providerID, &err);
 
96
  if (provider == NULL) {
 
97
    message(G_LOG_LEVEL_CRITICAL, err->message);
 
98
    ret = err->code;
 
99
    g_error_free(err);
 
100
    goto done;
 
101
  }
 
102
 
 
103
  /* get the prototocol profile of the logout request */
 
104
  protocolProfile = lasso_provider_get_singleLogoutProtocolProfile(provider,
 
105
                                                                   remote_provider_type,
 
106
                                                                   NULL);
 
107
  if (protocolProfile == NULL) {
 
108
    message(G_LOG_LEVEL_CRITICAL, "Single logout protocol profile not found\n");
 
109
    ret = -1;
 
110
    goto done;
 
111
  }
 
112
  
 
113
  /* build the logout request message */
 
114
  if (xmlStrEqual(protocolProfile, lassoLibProtocolProfileSloSpSoap) || \
 
115
      xmlStrEqual(protocolProfile, lassoLibProtocolProfileSloIdpSoap)) {
 
116
    /* sign the request message */
 
117
    lasso_samlp_request_abstract_sign_signature_tmpl(LASSO_SAMLP_REQUEST_ABSTRACT(profile->request),
 
118
                                                     profile->server->private_key,
 
119
                                                     profile->server->certificate);
 
120
 
 
121
    /* build the logout request message */
 
122
    profile->msg_url  = lasso_provider_get_soapEndpoint(provider,
 
123
                                                        remote_provider_type,
 
124
                                                        NULL);
 
125
    profile->msg_body = lasso_node_export_to_soap(profile->request);
 
126
  }
 
127
  else if (xmlStrEqual(protocolProfile,lassoLibProtocolProfileSloSpHttp) || \
 
128
           xmlStrEqual(protocolProfile,lassoLibProtocolProfileSloIdpHttp)) {
 
129
    /* build and optionaly sign the logout request QUERY message */
 
130
    url = lasso_provider_get_singleLogoutServiceURL(provider, remote_provider_type, NULL);
 
131
    query = lasso_node_export_to_query(profile->request,
 
132
                                       profile->server->signature_method,
 
133
                                       profile->server->private_key);
 
134
    if ( (url == NULL) || (query == NULL) ) {
 
135
      message(G_LOG_LEVEL_CRITICAL, "Error while building url and query\n");
 
136
      ret = -1;
 
137
      goto done;
 
138
    }
 
139
 
 
140
    /* build the msg_url */
 
141
    profile->msg_url = g_new(gchar, strlen(url)+strlen(query)+1+1);
 
142
    g_sprintf(profile->msg_url, "%s?%s", url, query);
 
143
    profile->msg_body = NULL;
 
144
  }
 
145
  else {
 
146
    message(G_LOG_LEVEL_CRITICAL, "Invalid logout protocol profile\n");
 
147
    ret = -1;
 
148
    goto done;
 
149
  }
 
150
 
 
151
  done:
 
152
  if (protocolProfile != NULL) {
 
153
    xmlFree(protocolProfile);
 
154
  }
 
155
  if (url != NULL) {
 
156
    xmlFree(url);
 
157
  }
 
158
  if (query != NULL) {
 
159
    xmlFree(query);
 
160
  }
 
161
 
 
162
  return ret;
 
163
}
 
164
 
 
165
/**
 
166
 * lasso_logout_build_response_msg:
 
167
 * @logout: the logout object
 
168
 * 
 
169
 * This method builds the logout response message.
 
170
 *
 
171
 * It gets the request message method and :
 
172
 *    if it is a SOAP method, then it builds the logout response SOAP message,
 
173
 *    sets the msg_body attribute, gets the single logout service return url
 
174
 *    and sets the msg_url attribute of the logout object.
 
175
 *
 
176
 *    if it is a HTTP-Redirect method, then it builds the logout response QUERY message,
 
177
 *    builds the logout response url, sets the msg_url with the logout response url,
 
178
 *    sets the msg_body with NULL
 
179
 *
 
180
 * Optionaly ( if private key and certificates paths are set in server object )
 
181
 *    it signs the message (with X509 if a SOAP message,
 
182
 *    else with simple signature if a QUERY message )
 
183
 * 
 
184
 * Return value: 0 if ok, else < 0
 
185
 **/
 
186
gint
 
187
lasso_logout_build_response_msg(LassoLogout *logout)
 
188
{
 
189
  LassoProfile  *profile;
 
190
  LassoProvider *provider;
 
191
  gchar         *url = NULL, *query = NULL;
 
192
  GError        *err = NULL;
 
193
  gint           ret = 0;
 
194
  gint           remote_provider_type;
 
195
 
 
196
  g_return_val_if_fail(LASSO_IS_LOGOUT(logout), -1);
 
197
  
 
198
  profile = LASSO_PROFILE(logout);
 
199
 
 
200
  /* get the provider */
 
201
  provider = lasso_server_get_provider_ref(profile->server, profile->remote_providerID, &err);
 
202
  if (provider == NULL) {
 
203
    message(G_LOG_LEVEL_CRITICAL, err->message);
 
204
    ret = err->code;
 
205
    g_error_free(err);
 
206
    goto done;
 
207
  }
 
208
 
 
209
  /* get the remote provider type */
 
210
  if (profile->provider_type == lassoProviderTypeSp) {
 
211
    remote_provider_type = lassoProviderTypeIdp;
 
212
  }
 
213
  else if (profile->provider_type == lassoProviderTypeIdp) {
 
214
    remote_provider_type = lassoProviderTypeSp;
 
215
  }
 
216
  else {
 
217
    message(G_LOG_LEVEL_CRITICAL, "Invalid provider type\n");
 
218
    ret = -1;
 
219
    goto done;
 
220
  }
 
221
 
 
222
  /* build logout response message */
 
223
  switch (profile->http_request_method) {
 
224
  case lassoHttpMethodSoap:
 
225
    /* optionaly sign the response message */
 
226
    if (profile->server->private_key) {
 
227
      lasso_samlp_response_abstract_set_signature(LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response),
 
228
                                                  profile->server->signature_method,
 
229
                                                  profile->server->private_key,
 
230
                                                  profile->server->certificate);
 
231
    }
 
232
 
 
233
    profile->msg_url = NULL;
 
234
    profile->msg_body = lasso_node_export_to_soap(profile->response);
 
235
    break;
 
236
  case lassoHttpMethodRedirect:
 
237
    url = lasso_provider_get_singleLogoutServiceReturnURL(provider, remote_provider_type, NULL);
 
238
    query = lasso_node_export_to_query(profile->response,
 
239
                                       profile->server->signature_method,
 
240
                                       profile->server->private_key);
 
241
    if ( (url == NULL) || (query == NULL) ) {
 
242
      message(G_LOG_LEVEL_CRITICAL, "Url %s or query %s not found\n", url, query);
 
243
      ret = -1;
 
244
      goto done;
 
245
    }
 
246
 
 
247
    profile->msg_url = g_new(gchar, strlen(url)+strlen(query)+1+1);
 
248
    g_sprintf(profile->msg_url, "%s?%s", url, query);
 
249
    profile->msg_body = NULL;
 
250
    break;
 
251
  default:
 
252
    ret = LASSO_PROFILE_ERROR_MISSING_REQUEST;
 
253
    goto done;
 
254
  }
 
255
 
 
256
  done:
 
257
  if (url != NULL) {
 
258
    xmlFree(url);
 
259
  }
 
260
  if (query != NULL) {
 
261
    xmlFree(query);
 
262
  }
 
263
 
 
264
  return ret;
 
265
}
 
266
 
 
267
/**
 
268
 * lasso_logout_destroy:
 
269
 * @logout: the logout object
 
270
 *
 
271
 * destroy the logout object
 
272
 * 
 
273
 **/
 
274
void
 
275
lasso_logout_destroy(LassoLogout *logout)
 
276
{
 
277
  g_object_unref(G_OBJECT(logout));
 
278
}
 
279
 
 
280
/**
 
281
 * lasso_logout_dump:
 
282
 * @logout: the logout object
 
283
 * 
 
284
 * This method dumps the logout object in string a xml message.
 
285
 * it first adds profile informations.
 
286
 * Next, it adds his logout informations (initial_request, initial_response,
 
287
 * initial_remote_providerID and providerID_index).
 
288
 * 
 
289
 * Return value: a newly allocated string or NULL
 
290
 **/
 
291
gchar *
 
292
lasso_logout_dump(LassoLogout *logout)
 
293
{
 
294
  LassoNode      *initial_node = NULL, *child_node = NULL;
 
295
  gchar          *dump = NULL, *parent_dump = NULL, *providerID_index_str;
 
296
  LassoNode      *node = NULL;
 
297
 
 
298
  g_return_val_if_fail(LASSO_IS_LOGOUT(logout), NULL);
 
299
 
 
300
  parent_dump = lasso_profile_dump(LASSO_PROFILE(logout), "Logout");
 
301
  node = lasso_node_new_from_dump(parent_dump);
 
302
  g_free(parent_dump);
 
303
 
 
304
  if (logout->initial_request != NULL) {
 
305
    initial_node = lasso_node_new();
 
306
    LASSO_NODE_GET_CLASS(initial_node)->set_name(initial_node, "InitialLogoutResquest");
 
307
    child_node = lasso_node_copy(logout->initial_request);
 
308
    LASSO_NODE_GET_CLASS(initial_node)->add_child(initial_node, child_node, FALSE);
 
309
    lasso_node_destroy(child_node);
 
310
 
 
311
    LASSO_NODE_GET_CLASS(node)->add_child(node, initial_node, FALSE);
 
312
  }
 
313
 
 
314
  if (logout->initial_response != NULL) {
 
315
    initial_node = lasso_node_new();
 
316
    LASSO_NODE_GET_CLASS(initial_node)->set_name(initial_node, "InitialLogoutResponse");
 
317
    child_node = lasso_node_copy(logout->initial_response);
 
318
    LASSO_NODE_GET_CLASS(initial_node)->add_child(initial_node, child_node, FALSE);
 
319
    lasso_node_destroy(child_node);
 
320
 
 
321
    LASSO_NODE_GET_CLASS(node)->add_child(node, initial_node, FALSE);
 
322
  }
 
323
 
 
324
  if (logout->initial_remote_providerID != NULL) {
 
325
    LASSO_NODE_GET_CLASS(node)->new_child(node, "InitialRemoteProviderID",
 
326
                                          logout->initial_remote_providerID, FALSE);
 
327
  }
 
328
  
 
329
  /* add providerID_index */
 
330
  providerID_index_str = g_strdup_printf("%d", logout->providerID_index);
 
331
  LASSO_NODE_GET_CLASS(node)->new_child(node, "ProviderIDIndex",
 
332
                                        providerID_index_str, FALSE);
 
333
 
 
334
  dump = lasso_node_export(node);
 
335
 
 
336
  lasso_node_destroy(node);
 
337
 
 
338
  return dump;
 
339
}
 
340
 
 
341
/**
 
342
 * lasso_logout_get_next_providerID:
 
343
 * @logout: the logout object
 
344
 * 
 
345
 * This method returns the provider id from providerID_index in list of providerIDs in session object.
 
346
 * excepted the initial service provider id :
 
347
 *    It gets the remote provider id in session from the logout providerID_index.
 
348
 *    If it is the initial remote provider id, then it asks the next provider id
 
349
 *    from providerID_index + 1;
 
350
 * 
 
351
 * Return value: a newly allocated string or NULL
 
352
 **/
 
353
gchar*
 
354
lasso_logout_get_next_providerID(LassoLogout *logout)
 
355
{
 
356
  LassoProfile *profile;
 
357
  gchar        *providerID;
 
358
 
 
359
  g_return_val_if_fail(LASSO_IS_LOGOUT(logout), NULL);
 
360
  profile = LASSO_PROFILE(logout);
 
361
 
 
362
  g_return_val_if_fail(LASSO_IS_SESSION(profile->session), NULL);
 
363
  providerID = lasso_session_get_provider_index(profile->session, logout->providerID_index);
 
364
  logout->providerID_index++;
 
365
  /* if it is the provider id of the SP requester, then get the next */
 
366
  if (logout->initial_remote_providerID && xmlStrEqual(providerID, logout->initial_remote_providerID)) {
 
367
    providerID = lasso_session_get_provider_index(profile->session, logout->providerID_index);
 
368
    logout->providerID_index++;
 
369
  }
 
370
  
 
371
  return providerID;
 
372
}
 
373
 
 
374
/**
 
375
 * lasso_logout_init_request:
 
376
 * @logout: 
 
377
 * @remote_providerID: 
 
378
 * @request_method: if set, then it get the protocol profile in metadata
 
379
 *                  corresponding of this HTTP request method.
 
380
 *
 
381
 * First it verifies session and identity are set.
 
382
 * Next, gets federation with the remote provider and gets the name identifier for the request.
 
383
 *       gets the protocol profile and build the logout request object.
 
384
 * If the local provider is a Service Provider and if the protocol profile is a HTTP Redirect / GET method,
 
385
 *       then removes the assertion.
 
386
 * 
 
387
 * Return value: 0 if ok, else < 0
 
388
 **/
 
389
gint
 
390
lasso_logout_init_request(LassoLogout    *logout,
 
391
                          gchar          *remote_providerID,
 
392
                          lassoHttpMethod request_method) /* FIXME : support this param to allow the user to choose the request method */
 
393
{
 
394
  LassoProfile      *profile        = NULL;
 
395
  LassoProvider     *provider       = NULL;
 
396
  LassoNode         *nameIdentifier = NULL;
 
397
  LassoFederation   *federation     = NULL;
 
398
  xmlChar           *content        = NULL, *nameQualifier = NULL, *format = NULL;
 
399
  xmlChar           *singleLogoutProtocolProfile = NULL;
 
400
  GError            *err = NULL;
 
401
  gboolean           is_http_redirect_get_method = FALSE;
 
402
  gint               ret = 0;
 
403
 
 
404
  g_return_val_if_fail(LASSO_IS_LOGOUT(logout), -1);
 
405
 
 
406
  profile = LASSO_PROFILE(logout);
 
407
 
 
408
  /* verify if the identity and session exist */
 
409
  if (profile->identity == NULL) {
 
410
    message(G_LOG_LEVEL_CRITICAL, "Identity not found\n");
 
411
    ret = -1;
 
412
    goto done;
 
413
  }
 
414
  if (profile->session == NULL) {
 
415
    message(G_LOG_LEVEL_CRITICAL, "Session not found\n");
 
416
    ret = -1;
 
417
    goto done;
 
418
  }
 
419
 
 
420
  /* get the remote provider id */
 
421
  /* If remote_providerID is NULL, then get the first remote provider id in session */
 
422
  if (remote_providerID == NULL) {
 
423
    profile->remote_providerID = lasso_session_get_first_providerID(profile->session);
 
424
  }
 
425
  else {
 
426
    profile->remote_providerID = g_strdup(remote_providerID);
 
427
  }
 
428
  if (profile->remote_providerID == NULL) {
 
429
    message(G_LOG_LEVEL_CRITICAL, "No remote provider id to send the logout request\n");
 
430
    ret = -1;
 
431
    goto done;
 
432
  }
 
433
 
 
434
  /* get federation */
 
435
  federation = lasso_identity_get_federation(profile->identity, profile->remote_providerID);
 
436
  if (federation == NULL) {
 
437
    message(G_LOG_LEVEL_CRITICAL, "Federation not found\n");
 
438
    ret = -1;
 
439
    goto done;
 
440
  }
 
441
 
 
442
  /* get the name identifier */
 
443
  switch (profile->provider_type) {
 
444
  case lassoProviderTypeSp:
 
445
    /* SP : get the local name identifier, if it is NULL, then get the remote name identifier */
 
446
    nameIdentifier = lasso_federation_get_local_nameIdentifier(federation);
 
447
    if (nameIdentifier == NULL) {
 
448
      nameIdentifier = lasso_federation_get_remote_nameIdentifier(federation);
 
449
    }
 
450
    break;
 
451
  case lassoProviderTypeIdp:
 
452
    /* IDP : get the remote name identifier, if it is NULL, then get the local name identifier */
 
453
    nameIdentifier = lasso_federation_get_remote_nameIdentifier(federation);
 
454
    if (nameIdentifier == NULL) {
 
455
      nameIdentifier = lasso_federation_get_local_nameIdentifier(federation);
 
456
    }
 
457
    break;
 
458
  default:
 
459
    message(G_LOG_LEVEL_CRITICAL, "Invalid provider type\n");
 
460
    ret = -1;
 
461
    goto done;
 
462
  }
 
463
 
 
464
  if (nameIdentifier == NULL) {
 
465
    message(G_LOG_LEVEL_CRITICAL, "Name identifier not found for %s\n",
 
466
            profile->remote_providerID);
 
467
    ret = -1;
 
468
    goto done;
 
469
  }
 
470
 
 
471
  /* get name identifier attributes */
 
472
  content = lasso_node_get_content(nameIdentifier, NULL);
 
473
  nameQualifier = lasso_node_get_attr_value(nameIdentifier, "NameQualifier", NULL);
 
474
  format = lasso_node_get_attr_value(nameIdentifier, "Format", NULL);
 
475
  
 
476
  /* get the provider */
 
477
  provider = lasso_server_get_provider_ref(profile->server, profile->remote_providerID, &err);
 
478
  if (provider == NULL) {
 
479
    message(G_LOG_LEVEL_CRITICAL, err->message);
 
480
    ret = err->code;
 
481
    g_error_free(err);
 
482
    goto done;
 
483
  }
 
484
 
 
485
  /* Get the single logout protocol profile */
 
486
  if (profile->provider_type == lassoProviderTypeIdp) {
 
487
    singleLogoutProtocolProfile = lasso_provider_get_singleLogoutProtocolProfile(provider, lassoProviderTypeSp, NULL);
 
488
  }
 
489
  else if (profile->provider_type == lassoProviderTypeSp) {
 
490
    singleLogoutProtocolProfile = lasso_provider_get_singleLogoutProtocolProfile(provider, lassoProviderTypeIdp, NULL);
 
491
  }
 
492
  else {
 
493
    message(G_LOG_LEVEL_CRITICAL, "Invalid provider type\n");
 
494
    ret = -1;
 
495
    goto done;
 
496
  }
 
497
  if (singleLogoutProtocolProfile == NULL) {
 
498
    message(G_LOG_LEVEL_CRITICAL, "Single logout protocol profile not found\n");
 
499
    ret = -1;
 
500
    goto done;
 
501
  }
 
502
 
 
503
  /* before setting profile->request, verify if it is already set */
 
504
  if (LASSO_IS_LOGOUT_REQUEST(profile->request) == TRUE) {
 
505
    lasso_node_destroy(profile->request);
 
506
    profile->request = NULL;
 
507
  }
 
508
 
 
509
  /* build a new request object from single logout protocol profile */
 
510
  if (xmlStrEqual(singleLogoutProtocolProfile, lassoLibProtocolProfileSloSpSoap) || \
 
511
      xmlStrEqual(singleLogoutProtocolProfile, lassoLibProtocolProfileSloIdpSoap)) {
 
512
    profile->request = lasso_logout_request_new(profile->server->providerID,
 
513
                                                content,
 
514
                                                nameQualifier,
 
515
                                                format,
 
516
                                                lassoSignatureTypeWithX509,
 
517
                                                lassoSignatureMethodRsaSha1);
 
518
  }
 
519
  else if (xmlStrEqual(singleLogoutProtocolProfile, lassoLibProtocolProfileSloSpHttp) || \
 
520
           xmlStrEqual(singleLogoutProtocolProfile, lassoLibProtocolProfileSloIdpHttp)) {
 
521
    is_http_redirect_get_method = TRUE;
 
522
    profile->request = lasso_logout_request_new(profile->server->providerID,
 
523
                                                content,
 
524
                                                nameQualifier,
 
525
                                                format,
 
526
                                                lassoSignatureTypeNone,
 
527
                                                0);
 
528
  }
 
529
  else {
 
530
    message(G_LOG_LEVEL_CRITICAL, "Invalid single logout protocol profile : %s\n", singleLogoutProtocolProfile);
 
531
    ret = -1;
 
532
    goto done;
 
533
  }
 
534
  if (LASSO_IS_LOGOUT_REQUEST(profile->request) == FALSE) {
 
535
    message(G_LOG_LEVEL_CRITICAL, "Error while building the request\n");
 
536
    ret = -1;
 
537
    goto done;
 
538
  }
 
539
 
 
540
  /* set the name identifier in logout object */
 
541
  profile->nameIdentifier = content;
 
542
 
 
543
  /* if logout request from a SP and if an HTTP Redirect / GET method, then remove assertion */
 
544
  if (profile->provider_type == lassoProviderTypeSp && is_http_redirect_get_method == TRUE) {
 
545
    lasso_session_remove_assertion(profile->session, profile->remote_providerID);
 
546
  }
 
547
 
 
548
  done:
 
549
  if (federation != NULL) {
 
550
    lasso_federation_destroy(federation);
 
551
  }
 
552
  if (nameIdentifier != NULL ) {
 
553
    lasso_node_destroy(nameIdentifier);
 
554
  }
 
555
  if (nameQualifier != NULL) {
 
556
    xmlFree(nameQualifier);
 
557
  }
 
558
  if (format != NULL) {
 
559
    xmlFree(format);
 
560
  }
 
561
  if (singleLogoutProtocolProfile != NULL) {
 
562
    xmlFree(singleLogoutProtocolProfile);
 
563
  }
 
564
 
 
565
  return ret;
 
566
}
 
567
 
 
568
/**
 
569
 * lasso_logout_process_request_msg:
 
570
 * @logout: the logout object
 
571
 * @request_msg: the logout request message
 
572
 * @request_method: the logout request method
 
573
 * 
 
574
 * Processes a logout request.
 
575
 *    if it is a SOAP request method then it builds the logout request object
 
576
 *    from the SOAP message and optionaly verifies the signature of the logout request.
 
577
 * 
 
578
 *    if it is a HTTP-Redirect request method then it builds the logout request object
 
579
 *    from the QUERY message and verify the signature. If there is an error while parsing the query,
 
580
 *    then returns the code error LASSO_PROFILE_ERROR_INVALID_QUERY.
 
581
 *
 
582
 *    Saves the HTTP request method.
 
583
 *    Saves the name identifier.
 
584
 *
 
585
 * Return value: 0 if OK else LASSO_PROFILE_ERROR_INVALID_QUERY or < 0
 
586
 **/
 
587
gint lasso_logout_process_request_msg(LassoLogout     *logout,
 
588
                                      gchar           *request_msg,
 
589
                                      lassoHttpMethod  request_method)
 
590
{
 
591
  LassoProfile  *profile;
 
592
  LassoProvider *provider;
 
593
  gchar         *remote_providerID = NULL;
 
594
  gint           ret = 0;
 
595
  GError        *err = NULL;
 
596
 
 
597
  g_return_val_if_fail(LASSO_IS_LOGOUT(logout), -1);
 
598
  g_return_val_if_fail(request_msg != NULL, -1);
 
599
 
 
600
  profile = LASSO_PROFILE(logout);
 
601
 
 
602
  /* rebuild the request message and optionaly verify the signature */
 
603
  switch (request_method) {
 
604
  case lassoHttpMethodSoap:
 
605
    profile->request = lasso_logout_request_new_from_export(request_msg,
 
606
                                                            lassoNodeExportTypeSoap);
 
607
 
 
608
    /* verify requets is a LogoutRequest */
 
609
    if (LASSO_IS_LOGOUT_REQUEST(profile->request) == FALSE) {
 
610
      message(G_LOG_LEVEL_CRITICAL, "Message is not a LogoutRequest\n");
 
611
      ret = -1;
 
612
      goto done;
 
613
    }
 
614
 
 
615
    /* verify signature  */
 
616
    remote_providerID = lasso_node_get_child_content(profile->request, "ProviderID", NULL, NULL);
 
617
    if (remote_providerID == NULL) {
 
618
      message(G_LOG_LEVEL_CRITICAL, "ProviderID not found\n");
 
619
      ret = -1;
 
620
      goto done;
 
621
    }
 
622
    provider = lasso_server_get_provider_ref(profile->server, remote_providerID, &err);
 
623
    if (provider == NULL) {
 
624
      message(G_LOG_LEVEL_CRITICAL, err->message);
 
625
      ret = err->code;
 
626
      g_error_free(err);
 
627
      goto done;
 
628
    }
 
629
    if (provider->ca_certificate != NULL) {
 
630
      ret = lasso_node_verify_x509_signature(profile->request, provider->ca_certificate);
 
631
    }
 
632
    break;
 
633
  case lassoHttpMethodRedirect:
 
634
    profile->request = lasso_logout_request_new_from_export(request_msg,
 
635
                                                            lassoNodeExportTypeQuery);
 
636
    /* if problem while rebuilding the response, then return invalid query code error */
 
637
    if (LASSO_IS_LOGOUT_REQUEST(profile->request) == FALSE) {
 
638
      ret = LASSO_PROFILE_ERROR_INVALID_QUERY;
 
639
      goto done;
 
640
    }
 
641
 
 
642
    break;
 
643
  default:
 
644
    message(G_LOG_LEVEL_CRITICAL, "Invalid request method\n");
 
645
    ret = -1;
 
646
    goto done;
 
647
  }
 
648
 
 
649
  /* set the http request method */
 
650
  profile->http_request_method = request_method;
 
651
 
 
652
  /* Set the NameIdentifier */
 
653
  profile->nameIdentifier = lasso_node_get_child_content(profile->request,
 
654
                                                         "NameIdentifier",
 
655
                                                         NULL, NULL);
 
656
 
 
657
  done:
 
658
  if (remote_providerID != NULL ) {
 
659
    xmlFree(remote_providerID);
 
660
  }
 
661
 
 
662
  return ret;
 
663
}
 
664
 
 
665
/**
 
666
 * lasso_logout_process_response_msg:
 
667
 * @logout: the logout object
 
668
 * @response_msg: the response message
 
669
 * @response_method: the response method
 
670
 * 
 
671
 * Parses the response message and builds the response object :
 
672
 *      if there is an error while parsing the HTTP Redirect / GET message,
 
673
 *          then returns a LASSO_PROFILE_ERROR_INVALID_QUERY code error.
 
674
 * Get the status code value :
 
675
 *     if it is not success, then if the local provider is a Service Provider and response method is SOAP,
 
676
 *         then builds a new logout request message for HTTP Redirect / GET method and returns the code error
 
677
 *         LASSO_LOGOUT_ERROR_UNSUPPORTED_PROFILE and exits.
 
678
 *
 
679
 * Sets the remote provider id.
 
680
 * Sets the relay state.
 
681
 * 
 
682
 * if it is a SOAP method or, IDP provider type and http method is Redirect / GET, then removes assertion.
 
683
 * 
 
684
 * If local server is an Identity Provider and if there is no more assertion (Identity Provider has logged out every Service Providers),
 
685
 *     then restores the initial response.
 
686
 * Return value: 0 if OK else LASSO_LOGOUT_ERROR_UNSUPPORTED_PROFILE or < 0
 
687
 **/
 
688
gint
 
689
lasso_logout_process_response_msg(LassoLogout     *logout,
 
690
                                  gchar           *response_msg,
 
691
                                  lassoHttpMethod  response_method)
 
692
{
 
693
  gchar        *last_providerID = NULL;
 
694
  xmlChar      *statusCodeValue = NULL;
 
695
  LassoNode    *statusCode = NULL;
 
696
  LassoProfile *profile = NULL;
 
697
  GError       *err = NULL;
 
698
  gint          ret = 0;
 
699
 
 
700
  g_return_val_if_fail(LASSO_IS_LOGOUT(logout), -1);
 
701
  g_return_val_if_fail(response_msg != NULL, -1);
 
702
 
 
703
  profile = LASSO_PROFILE(logout);
 
704
 
 
705
  /* before verify if profile->response is set */
 
706
  if (LASSO_IS_LOGOUT_RESPONSE(profile->response) == TRUE) {
 
707
    lasso_node_destroy(profile->response);
 
708
    profile->response = NULL;
 
709
  }
 
710
 
 
711
  /* build logout response object */
 
712
  switch (response_method) {
 
713
  case lassoHttpMethodSoap:
 
714
    profile->response = lasso_logout_response_new_from_export(response_msg, lassoNodeExportTypeSoap);
 
715
    break;
 
716
  case lassoHttpMethodRedirect:
 
717
    profile->response = lasso_logout_response_new_from_export(response_msg, lassoNodeExportTypeQuery);
 
718
    /* if problem while rebuilding the response, then return invalid query code error */
 
719
    if (LASSO_IS_LOGOUT_RESPONSE(profile->response) == FALSE) {
 
720
      ret = LASSO_PROFILE_ERROR_INVALID_QUERY;
 
721
      goto done;
 
722
    }
 
723
    break;
 
724
  default:
 
725
    message(G_LOG_LEVEL_CRITICAL, "Invalid response method\n");
 
726
    ret = -1;
 
727
    goto done;
 
728
  }
 
729
  if (LASSO_IS_LOGOUT_RESPONSE(profile->response) == FALSE) {
 
730
    message(G_LOG_LEVEL_CRITICAL, "Message is not a LogoutResponse\n");
 
731
    ret = -1;
 
732
    goto done;
 
733
  }
 
734
 
 
735
  /* get the status code */
 
736
  statusCode = lasso_node_get_child(profile->response, "StatusCode", NULL, NULL);
 
737
  if (statusCode == NULL) {
 
738
    message(G_LOG_LEVEL_CRITICAL, "StatusCode node not found\n");
 
739
    ret = -1;
 
740
    goto done;
 
741
  }
 
742
  statusCodeValue = lasso_node_get_attr_value(statusCode, "Value", NULL);
 
743
 
 
744
  if (!xmlStrEqual(statusCodeValue, lassoSamlStatusCodeSuccess)) {
 
745
 
 
746
    /* At SP, if the request method was a SOAP type, then rebuild the request message with HTTP method */
 
747
    if (xmlStrEqual(statusCodeValue, lassoLibStatusCodeUnsupportedProfile) && \
 
748
        profile->provider_type == lassoProviderTypeSp && \
 
749
        profile->http_request_method == lassoHttpMethodSoap) {
 
750
      /* temporary vars */
 
751
      LassoProvider *provider;
 
752
      gchar *url, *query;
 
753
 
 
754
      provider = lasso_server_get_provider_ref(profile->server, profile->remote_providerID, &err);
 
755
      if (provider == NULL) {
 
756
        message(G_LOG_LEVEL_CRITICAL, err->message);
 
757
        ret = err->code;
 
758
        g_error_free(err);
 
759
        goto done;
 
760
      }
 
761
 
 
762
      /* FIXME : verify the IDP support a HTTP method */
 
763
 
 
764
      /* Build and optionaly sign the logout request QUERY message */
 
765
      url = lasso_provider_get_singleLogoutServiceURL(provider, lassoProviderTypeIdp, NULL);
 
766
      query = lasso_node_export_to_query(profile->request,
 
767
                                         profile->server->signature_method,
 
768
                                         profile->server->private_key);
 
769
      profile->msg_url = g_new(gchar, strlen(url)+strlen(query)+1+1);
 
770
      g_sprintf(profile->msg_url, "%s?%s", url, query);
 
771
      profile->msg_body = NULL;
 
772
 
 
773
      /* send a HTTP Redirect / GET method, so first remove session */
 
774
      lasso_session_remove_assertion(profile->session, profile->remote_providerID);
 
775
 
 
776
      ret = LASSO_LOGOUT_ERROR_UNSUPPORTED_PROFILE;
 
777
    }
 
778
    else {
 
779
      message(G_LOG_LEVEL_CRITICAL, "Status code is not success : %s\n", statusCodeValue);
 
780
      ret = -1;
 
781
    }
 
782
 
 
783
    goto done;
 
784
  }
 
785
 
 
786
  /* LogoutResponse status code value is ok */
 
787
 
 
788
  /* set the remote provider id */
 
789
  profile->remote_providerID = lasso_node_get_child_content(profile->response,
 
790
                                                            "ProviderID",
 
791
                                                            lassoLibHRef,
 
792
                                                            NULL);
 
793
 
 
794
  /* set the msg_relayState */
 
795
  profile->msg_relayState = lasso_node_get_child_content(profile->response, "RelayState", lassoLibHRef, NULL);
 
796
 
 
797
  /* if SOAP method or, if IDP provider type and HTTP Redirect, then remove assertion */
 
798
  if ( (response_method == lassoHttpMethodSoap) || (profile->provider_type == lassoProviderTypeIdp && response_method == lassoHttpMethodRedirect) ) {
 
799
    ret = lasso_session_remove_assertion(profile->session, profile->remote_providerID);
 
800
    if (profile->provider_type == lassoProviderTypeIdp && logout->providerID_index >= 0) {
 
801
      logout->providerID_index--;
 
802
    }
 
803
  }
 
804
 
 
805
  /* If at IDP and if there is no more assertion, IDP a logged out every SPs, return the initial response to initial SP */
 
806
  if (profile->provider_type == lassoProviderTypeIdp && logout->initial_remote_providerID && profile->session->providerIDs->len == 0) {
 
807
    if (profile->remote_providerID != NULL) {
 
808
      g_free(profile->remote_providerID);
 
809
    }
 
810
    if (profile->request != NULL) {
 
811
      lasso_node_destroy(profile->request);
 
812
    }
 
813
    if (profile->response != NULL) {
 
814
      lasso_node_destroy(profile->response);
 
815
    }
 
816
 
 
817
    profile->remote_providerID = logout->initial_remote_providerID;
 
818
    profile->request = logout->initial_request;
 
819
    profile->response = logout->initial_response;
 
820
 
 
821
    logout->initial_remote_providerID = NULL;
 
822
    logout->initial_request = NULL;
 
823
    logout->initial_response = NULL;
 
824
  }
 
825
 
 
826
  done:
 
827
  if (last_providerID != NULL) {
 
828
    g_free(last_providerID);
 
829
  }
 
830
 
 
831
  return ret;
 
832
}
 
833
 
 
834
/**
 
835
 * lasso_logout_reset_providerID_index:
 
836
 * @logout: the logout object
 
837
 * 
 
838
 * Reset the providerID_index attribute (set to 0).
 
839
 * 
 
840
 * Return value: 0
 
841
 **/
 
842
gint lasso_logout_reset_providerID_index(LassoLogout *logout)
 
843
{
 
844
  g_return_val_if_fail(LASSO_IS_LOGOUT(logout), -1);
 
845
 
 
846
  logout->providerID_index = 0;
 
847
 
 
848
  return 0;
 
849
}
 
850
 
 
851
/**
 
852
 * lasso_logout_validate_request:
 
853
 * @logout: the logout object
 
854
 * 
 
855
 * Sets the remote provider id
 
856
 * Sets a logout response with status code value to success.
 
857
 * Verifies federation and authentication.
 
858
 * If the request http method is a SOAP method, then verifies every other
 
859
 *     Service Providers supports SOAP method : if not, then sets status code value to
 
860
 *     UnsupportedProfile and returns a code error with LASSO_LOGOUT_ERROR_UNSUPPORTED_PROFILE.
 
861
 *
 
862
 * Every tests are ok, then removes assertion.
 
863
 * (profile->provider_type == lassoProviderTypeIdp && profile->session->providerIDs->len >= 1)
 
864
 * If local server is an Identity Provider and if there is more than one Service Provider
 
865
 *     (except the initial Service Provider),
 
866
 *     then saves the initial request, response and remote provider id.
 
867
 *
 
868
 * Return value: O if OK else < 0
 
869
 **/
 
870
gint
 
871
lasso_logout_validate_request(LassoLogout *logout)
 
872
{
 
873
  LassoProfile    *profile;
 
874
  LassoFederation *federation = NULL;
 
875
  LassoNode       *nameIdentifier, *assertion;
 
876
  LassoNode       *statusCode;
 
877
  LassoNodeClass  *statusCode_class;
 
878
  xmlChar         *remote_providerID;
 
879
  gint             ret = 0;
 
880
 
 
881
  g_return_val_if_fail(LASSO_IS_LOGOUT(logout), -1);
 
882
 
 
883
  profile = LASSO_PROFILE(logout);
 
884
 
 
885
  /* verify logout request */
 
886
  if (profile->request == NULL) {
 
887
    ret = LASSO_PROFILE_ERROR_MISSING_REQUEST;
 
888
    goto done;
 
889
  }
 
890
 
 
891
  /* Set the remote provider id from the request */
 
892
  remote_providerID = lasso_node_get_child_content(profile->request, "ProviderID",
 
893
                                                   NULL, NULL);
 
894
  if (remote_providerID == NULL) {
 
895
    message(G_LOG_LEVEL_CRITICAL, "ProviderID in LogoutRequest not found\n");
 
896
    ret = -1;
 
897
    goto done;
 
898
  }
 
899
  profile->remote_providerID = remote_providerID;
 
900
 
 
901
  /* Set LogoutResponse */
 
902
  switch (profile->http_request_method) {
 
903
  case lassoHttpMethodSoap:
 
904
    profile->response = lasso_logout_response_new(profile->server->providerID,
 
905
                                                  lassoSamlStatusCodeSuccess,
 
906
                                                  profile->request,
 
907
                                                  lassoSignatureTypeWithX509,
 
908
                                                  lassoSignatureMethodRsaSha1);
 
909
    break;
 
910
  case lassoHttpMethodRedirect:
 
911
    profile->response = lasso_logout_response_new(profile->server->providerID,
 
912
                                                  lassoSamlStatusCodeSuccess,
 
913
                                                  profile->request,
 
914
                                                  lassoSignatureTypeNone,
 
915
                                                  0);
 
916
    break;
 
917
  default:
 
918
    message(G_LOG_LEVEL_CRITICAL, "Invalid HTTP request method\n");
 
919
    ret = -1;
 
920
    goto done;
 
921
  }
 
922
  if (LASSO_IS_LOGOUT_RESPONSE(profile->response) == FALSE) {
 
923
    message(G_LOG_LEVEL_CRITICAL, "Error while building response\n");
 
924
    ret = -1;
 
925
    goto done;
 
926
  }
 
927
 
 
928
  /* Get the name identifier */
 
929
  nameIdentifier = lasso_node_get_child(profile->request, "NameIdentifier",
 
930
                                        NULL, NULL);
 
931
  if (nameIdentifier == NULL) {
 
932
    message(G_LOG_LEVEL_CRITICAL, "Name identifier not found in logout request\n");
 
933
    lasso_profile_set_response_status(profile, lassoLibStatusCodeFederationDoesNotExist);
 
934
    ret = -1;
 
935
    goto done;
 
936
  }
 
937
 
 
938
  /* verify authentication */
 
939
  if (profile->identity == NULL) {
 
940
    message(G_LOG_LEVEL_WARNING, "Identity not found\n");
 
941
    /* FIXME : use RequestDenied if no identity found ? */
 
942
    lasso_profile_set_response_status(profile, lassoSamlStatusCodeRequestDenied);
 
943
    ret = -1;
 
944
    goto done;
 
945
  }
 
946
  assertion = lasso_session_get_assertion(profile->session, remote_providerID);
 
947
  if (assertion == NULL) {
 
948
    message(G_LOG_LEVEL_WARNING, "%s has no assertion\n", remote_providerID);
 
949
    lasso_profile_set_response_status(profile, lassoSamlStatusCodeRequestDenied);
 
950
    ret = -1;
 
951
    goto done;
 
952
  }
 
953
  lasso_node_destroy(assertion);
 
954
 
 
955
  /* Verify federation */
 
956
  federation = lasso_identity_get_federation(profile->identity, remote_providerID);
 
957
  if (federation == NULL) {
 
958
    message(G_LOG_LEVEL_WARNING, "No federation for %s\n", remote_providerID);
 
959
    lasso_profile_set_response_status(profile, lassoLibStatusCodeFederationDoesNotExist);
 
960
    ret = -1;
 
961
    goto done;
 
962
  }
 
963
 
 
964
  if (lasso_federation_verify_nameIdentifier(federation, nameIdentifier) == FALSE) {
 
965
    message(G_LOG_LEVEL_WARNING, "No name identifier for %s\n", remote_providerID);
 
966
    lasso_profile_set_response_status(profile, lassoLibStatusCodeFederationDoesNotExist);
 
967
    ret = -1;
 
968
    goto done;
 
969
  }
 
970
 
 
971
  /* if SOAP request method at IDP then verify all the remote service providers support SOAP protocol profile.
 
972
     If one remote authenticated principal service provider doesn't support SOAP
 
973
     then return UnsupportedProfile to original service provider */
 
974
  if (profile->provider_type == lassoProviderTypeIdp && profile->http_request_method == lassoHttpMethodSoap) {
 
975
    gboolean all_http_soap;
 
976
    LassoProvider *provider;
 
977
    gchar *providerID, *protocolProfile;
 
978
    int i;
 
979
    
 
980
    all_http_soap = TRUE;
 
981
 
 
982
    for (i = 0; i<profile->server->providers->len; i++) {
 
983
      provider = g_ptr_array_index(profile->server->providers, i);
 
984
      providerID = lasso_provider_get_providerID(provider);
 
985
 
 
986
      /* if the original service provider then continue */
 
987
      if (xmlStrEqual(remote_providerID, providerID)) {
 
988
        continue;
 
989
      }
 
990
 
 
991
      /* if principal is not authenticated with this remote service provider, continue */
 
992
      assertion = lasso_session_get_assertion(profile->session, providerID);
 
993
      if (assertion == NULL) {
 
994
        continue;
 
995
      }
 
996
 
 
997
      /* if protocolProfile is SOAP continue else break */
 
998
      protocolProfile = lasso_provider_get_singleLogoutProtocolProfile(provider, lassoProviderTypeSp, NULL);
 
999
      if (protocolProfile == NULL || !xmlStrEqual(protocolProfile, lassoLibProtocolProfileSloSpSoap)) {
 
1000
        all_http_soap = FALSE;
 
1001
        break;
 
1002
      }
 
1003
      if (protocolProfile != NULL) {
 
1004
        xmlFree(protocolProfile);
 
1005
      }
 
1006
      if (providerID != NULL) {
 
1007
        xmlFree(providerID);
 
1008
      }
 
1009
    }
 
1010
 
 
1011
    if (all_http_soap==FALSE) {
 
1012
      lasso_profile_set_response_status(profile, lassoLibStatusCodeUnsupportedProfile);
 
1013
      ret = LASSO_LOGOUT_ERROR_UNSUPPORTED_PROFILE;
 
1014
      goto done;
 
1015
    }
 
1016
  }
 
1017
 
 
1018
  /* FIXME : set the status code in response */
 
1019
 
 
1020
  /* authentication is ok, federation is ok, propagation support is ok, remove federation */
 
1021
  lasso_session_remove_assertion(profile->session, profile->remote_providerID);
 
1022
 
 
1023
  /* if at IDP and nb sp logged > 1, then backup remote provider id,
 
1024
   * request and response
 
1025
   * REMARK : if only initial service provider was logged,
 
1026
   *   then profile->session->providerIDs->len == 0,
 
1027
   *   else profile->session->providerIDs->len >= 1
 
1028
   */
 
1029
  if (profile->provider_type == lassoProviderTypeIdp && profile->session->providerIDs->len >= 1) {
 
1030
    logout->initial_remote_providerID = profile->remote_providerID;
 
1031
    logout->initial_request = profile->request;
 
1032
    logout->initial_response = profile->response;
 
1033
 
 
1034
    profile->remote_providerID = NULL;
 
1035
    profile->request = NULL;
 
1036
    profile->response = NULL;
 
1037
  }
 
1038
 
 
1039
  done:
 
1040
  if (federation != NULL) {
 
1041
    lasso_federation_destroy(federation);
 
1042
  }
 
1043
 
 
1044
  return ret;
 
1045
}
 
1046
 
 
1047
/*****************************************************************************/
 
1048
/* overrided parent class methods                                            */
 
1049
/*****************************************************************************/
 
1050
 
 
1051
static void
 
1052
lasso_logout_dispose(LassoLogout *logout)
 
1053
{
 
1054
  if (logout->private->dispose_has_run) {
 
1055
    return;
 
1056
  }
 
1057
  logout->private->dispose_has_run = TRUE;
 
1058
 
 
1059
  debug("Logout object 0x%x disposed ...\n", logout);
 
1060
 
 
1061
  /* unref reference counted objects */
 
1062
  lasso_node_destroy(logout->initial_request);
 
1063
  lasso_node_destroy(logout->initial_response);
 
1064
 
 
1065
  parent_class->dispose(G_OBJECT(logout));
 
1066
}
 
1067
 
 
1068
static void
 
1069
lasso_logout_finalize(LassoLogout *logout)
 
1070
{  
 
1071
  debug("Logout object 0x%x finalized ...\n", logout);
 
1072
 
 
1073
  g_free(logout->initial_remote_providerID);
 
1074
 
 
1075
  g_free(logout->private);
 
1076
 
 
1077
  parent_class->finalize(G_OBJECT(logout));
 
1078
}
 
1079
 
 
1080
/*****************************************************************************/
 
1081
/* instance and class init functions                                         */
 
1082
/*****************************************************************************/
 
1083
 
 
1084
static void
 
1085
lasso_logout_instance_init(GTypeInstance   *instance,
 
1086
                           gpointer         g_class)
 
1087
{
 
1088
  LassoLogout *logout = LASSO_LOGOUT(instance);
 
1089
 
 
1090
  logout->private = g_new (LassoLogoutPrivate, 1);
 
1091
  logout->private->dispose_has_run = FALSE;
 
1092
 
 
1093
  logout->initial_request = NULL;
 
1094
  logout->initial_response = NULL;
 
1095
  logout->initial_remote_providerID = NULL;
 
1096
 
 
1097
  logout->providerID_index = 0;
 
1098
}
 
1099
 
 
1100
static void
 
1101
lasso_logout_class_init(LassoLogoutClass *class)
 
1102
{
 
1103
  GObjectClass *gobject_class = G_OBJECT_CLASS(class);
 
1104
  
 
1105
  parent_class = g_type_class_peek_parent(class);
 
1106
  /* override parent class methods */
 
1107
  gobject_class->dispose  = (void *)lasso_logout_dispose;
 
1108
  gobject_class->finalize = (void *)lasso_logout_finalize;
 
1109
}
 
1110
 
 
1111
GType lasso_logout_get_type() {
 
1112
  static GType this_type = 0;
 
1113
 
 
1114
  if (!this_type) {
 
1115
    static const GTypeInfo this_info = {
 
1116
      sizeof (LassoLogoutClass),
 
1117
      NULL,
 
1118
      NULL,
 
1119
      (GClassInitFunc) lasso_logout_class_init,
 
1120
      NULL,
 
1121
      NULL,
 
1122
      sizeof(LassoLogout),
 
1123
      0,
 
1124
      (GInstanceInitFunc) lasso_logout_instance_init,
 
1125
    };
 
1126
    
 
1127
    this_type = g_type_register_static(LASSO_TYPE_PROFILE,
 
1128
                                       "LassoLogout",
 
1129
                                       &this_info, 0);
 
1130
  }
 
1131
  return this_type;
 
1132
}
 
1133
 
 
1134
/**
 
1135
 * lasso_logout_new:
 
1136
 * @server: the logout object
 
1137
 * @provider_type: the provider type (service provider or identity provider)
 
1138
 * 
 
1139
 * initialises a new logout object
 
1140
 * 
 
1141
 * Return value: a new instance of logout object or NULL
 
1142
 **/
 
1143
LassoLogout*
 
1144
lasso_logout_new(LassoServer       *server,
 
1145
                 lassoProviderType  provider_type)
 
1146
{
 
1147
  LassoLogout *logout;
 
1148
 
 
1149
  g_return_val_if_fail(LASSO_IS_SERVER(server), NULL);
 
1150
 
 
1151
  /* set the logout object */
 
1152
  logout = g_object_new(LASSO_TYPE_LOGOUT,
 
1153
                        "server", lasso_server_copy(server),
 
1154
                        "provider_type", provider_type,
 
1155
                        NULL);
 
1156
 
 
1157
  return logout;
 
1158
}
 
1159
 
 
1160
LassoLogout*
 
1161
lasso_logout_new_from_dump(LassoServer *server,
 
1162
                           gchar       *dump)
 
1163
{
 
1164
  LassoLogout  *logout;
 
1165
  LassoProfile *profile;
 
1166
  LassoNode    *node_dump, *request_node, *response_node;
 
1167
  LassoNode    *initial_request_node, *initial_response_node;
 
1168
  gchar        *type, *export, *providerID_index_str;
 
1169
 
 
1170
  g_return_val_if_fail(LASSO_IS_SERVER(server), NULL);
 
1171
  g_return_val_if_fail(dump != NULL, NULL);
 
1172
 
 
1173
  logout = LASSO_LOGOUT(g_object_new(LASSO_TYPE_LOGOUT,
 
1174
                                     "server", lasso_server_copy(server),
 
1175
                                     NULL));
 
1176
 
 
1177
  profile = LASSO_PROFILE(logout);
 
1178
 
 
1179
  node_dump = lasso_node_new_from_dump(dump);
 
1180
 
 
1181
  /* profile attributes */
 
1182
  profile->nameIdentifier    = lasso_node_get_child_content(node_dump, "NameIdentifier",
 
1183
                                                            lassoLassoHRef, NULL);
 
1184
  profile->remote_providerID = lasso_node_get_child_content(node_dump, "RemoteProviderID",
 
1185
                                                            lassoLassoHRef, NULL);
 
1186
  profile->msg_url           = lasso_node_get_child_content(node_dump, "MsgUrl",
 
1187
                                                            lassoLassoHRef, NULL);
 
1188
  profile->msg_body          = lasso_node_get_child_content(node_dump, "MsgBody",
 
1189
                                                            lassoLassoHRef, NULL);
 
1190
  profile->msg_relayState    = lasso_node_get_child_content(node_dump, "MsgRelayState",
 
1191
                                                            lassoLassoHRef, NULL);
 
1192
 
 
1193
  /* rebuild request */
 
1194
  request_node = lasso_node_get_child(node_dump, "LogoutRequest", lassoLibHRef, NULL);
 
1195
 
 
1196
  if (LASSO_IS_NODE(request_node) == TRUE) {
 
1197
    export = lasso_node_export(request_node);
 
1198
    profile->request = lasso_logout_request_new_from_export(export,
 
1199
                                                            lassoNodeExportTypeXml);
 
1200
    g_free(export);
 
1201
    lasso_node_destroy(request_node);
 
1202
  }
 
1203
 
 
1204
 
 
1205
  /* rebuild response */
 
1206
  response_node = lasso_node_get_child(node_dump, "LogoutResponse", lassoLibHRef, NULL);
 
1207
  if (response_node != NULL) {
 
1208
    export = lasso_node_export(response_node);
 
1209
    profile->response = lasso_logout_response_new_from_export(export,
 
1210
                                                              lassoNodeExportTypeXml);
 
1211
    g_free(export);
 
1212
    lasso_node_destroy(response_node);
 
1213
  }
 
1214
  
 
1215
  /* provider type */
 
1216
  type = lasso_node_get_child_content(node_dump, "ProviderType", lassoLassoHRef, NULL);
 
1217
  profile->provider_type = atoi(type);
 
1218
  xmlFree(type);
 
1219
 
 
1220
  /* logout attributes */
 
1221
  /* Initial logout request */
 
1222
  initial_request_node = lasso_node_get_child(node_dump, "InitialRequest", lassoLassoHRef, NULL);
 
1223
  if (initial_request_node != NULL) {
 
1224
    request_node = lasso_node_get_child(node_dump, "LogoutRequest", lassoLibHRef, NULL);
 
1225
    export = lasso_node_export(request_node);
 
1226
    profile->request = lasso_logout_request_new_from_export(export,
 
1227
                                                            lassoNodeExportTypeXml);
 
1228
    g_free(export);
 
1229
    lasso_node_destroy(request_node);
 
1230
  }
 
1231
 
 
1232
  /* Initial logout response */
 
1233
  initial_response_node = lasso_node_get_child(node_dump, "InitialResponse", lassoLassoHRef, NULL);
 
1234
  if (initial_response_node != NULL) {
 
1235
    response_node = lasso_node_get_child(node_dump, "LogoutResponse", lassoLibHRef, NULL);
 
1236
    export = lasso_node_export(response_node);
 
1237
    profile->response = lasso_logout_response_new_from_export(export,
 
1238
                                                              lassoNodeExportTypeXml);
 
1239
    g_free(export);
 
1240
    lasso_node_destroy(response_node);
 
1241
  }
 
1242
 
 
1243
  /* Initial logout remote provider id */
 
1244
  logout->initial_remote_providerID = lasso_node_get_child_content(node_dump, "InitialRemoteProviderID", lassoLassoHRef, NULL);
 
1245
 
 
1246
  /* index provider id */
 
1247
 
 
1248
  providerID_index_str = lasso_node_get_child_content(node_dump, "ProviderIDIndex", NULL, NULL);
 
1249
 
 
1250
  if (providerID_index_str == NULL) {
 
1251
    message(G_LOG_LEVEL_CRITICAL, "Index ProviderID not found\n");
 
1252
  }
 
1253
  else {
 
1254
    logout->providerID_index = atoi(providerID_index_str);
 
1255
  }
 
1256
 
 
1257
  return logout;
 
1258
}