1
/* $Id: name_registration.c,v 1.5 2004/09/04 10:36:32 fpeters Exp $
3
* Lasso - A free implementation of the Liberty Alliance specifications.
5
* Copyright (C) 2004 Entr'ouvert
6
* http://lasso.entrouvert.org
8
* Authors: Nicolas Clapies <nclapies@entrouvert.com>
9
* Valery Febvre <vfebvre@easter-eggs.com>
11
* This program is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; either version 2 of the License, or
14
* (at your option) any later version.
16
* This program is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU General Public License for more details.
21
* You should have received a copy of the GNU General Public License
22
* along with this program; if not, write to the Free Software
23
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
#include <glib/gprintf.h>
29
#include <lasso/environs/name_registration.h>
31
static GObjectClass *parent_class = NULL;
33
/*****************************************************************************/
35
/*****************************************************************************/
38
* lasso_name_registration_dump:
39
* @name_registration: the register name identifier object
41
* This method builds a dump of the register name identifier object
43
* Return value: a newly allocated string or NULL
46
lasso_name_registration_dump(LassoNameRegistration *name_registration)
50
g_return_val_if_fail(LASSO_IS_NAME_REGISTRATION(name_registration), NULL);
58
* lasso_name_registration_build_request_msg:
59
* @name_registration: the register name identifier object
61
* This method build a register name identifier request message.
63
* It gets the register name identifier protocol profile and :
64
* if it is a SOAP method, then it builds the register name identifier request SOAP message,
65
* optionaly signs his node, set the msg_body attribute, gets the SoapEndpoint
66
* url and set the msg_url attribute.
68
* if it is a HTTP-Redirect method, then it builds the register name identifier request QUERY message
69
* ( optionaly signs the request message ), builds the request url with register name identifier url
70
* with register name identifier service url, set the msg_url attribute of the register name identifier
71
* object, set the msg_body to NULL.
73
* Return value: 0 if OK else < 0
76
lasso_name_registration_build_request_msg(LassoNameRegistration *name_registration)
78
LassoProfile *profile;
79
LassoProvider *provider;
80
xmlChar *protocolProfile;
83
g_return_val_if_fail(LASSO_IS_NAME_REGISTRATION(name_registration), -1);
85
profile = LASSO_PROFILE(name_registration);
87
/* get the provider */
88
provider = lasso_server_get_provider_ref(profile->server,
89
profile->remote_providerID,
91
if (provider == NULL) {
92
message(G_LOG_LEVEL_CRITICAL, "Provider %s not found\n", profile->remote_providerID);
97
/* get the prototocol profile of the name_registration */
98
protocolProfile = lasso_provider_get_registerNameIdentifierProtocolProfile(provider,
101
if (protocolProfile == NULL) {
102
message(G_LOG_LEVEL_CRITICAL, "Name_Registration Protocol profile not found\n");
107
if (xmlStrEqual(protocolProfile, lassoLibProtocolProfileRniIdpSoap) || \
108
xmlStrEqual(protocolProfile, lassoLibProtocolProfileRniSpSoap)) {
109
profile->request_type = lassoHttpMethodSoap;
110
/* sign the request message */
111
lasso_samlp_request_abstract_set_signature(LASSO_SAMLP_REQUEST_ABSTRACT(profile->request),
112
profile->server->signature_method,
113
profile->server->private_key,
114
profile->server->certificate);
116
/* build the registration request message */
117
profile->msg_url = lasso_provider_get_soapEndpoint(provider,
118
lassoProviderTypeIdp,
120
profile->msg_body = lasso_node_export_to_soap(profile->request);
122
else if (xmlStrEqual(protocolProfile,lassoLibProtocolProfileRniIdpHttp) || \
123
xmlStrEqual(protocolProfile,lassoLibProtocolProfileRniSpHttp)) {
124
/* temporary vars to store url, query and separator */
127
/* build and optionaly sign the query message and build the register name
128
* identifier request url */
129
url = lasso_provider_get_registerNameIdentifierServiceURL(provider, profile->provider_type, NULL);
130
query = lasso_node_export_to_query(profile->request,
131
profile->server->signature_method,
132
profile->server->private_key);
134
profile->msg_url = g_new(gchar, strlen(url)+strlen(query)+1+1);
135
g_sprintf(profile->msg_url, "%s?%s", url, query);
136
profile->msg_body = NULL;
142
message(G_LOG_LEVEL_CRITICAL, "Invalid protocol Profile for register name identifier\n");
153
lasso_name_registration_build_response_msg(LassoNameRegistration *name_registration)
155
LassoProfile *profile;
156
LassoProvider *provider;
157
xmlChar *protocolProfile;
159
g_return_val_if_fail(LASSO_IS_NAME_REGISTRATION(name_registration), -1);
161
profile = LASSO_PROFILE(name_registration);
163
provider = lasso_server_get_provider_ref(profile->server,
164
profile->remote_providerID,
166
if (provider == NULL) {
167
message(G_LOG_LEVEL_CRITICAL, "Provider not found (ProviderID = %s)\n", profile->remote_providerID);
171
protocolProfile = lasso_provider_get_registerNameIdentifierProtocolProfile(provider,
174
if (protocolProfile == NULL) {
175
message(G_LOG_LEVEL_CRITICAL, "Register name identifier protocol profile not found\n");
179
if (xmlStrEqual(protocolProfile, lassoLibProtocolProfileSloSpSoap) || \
180
xmlStrEqual(protocolProfile, lassoLibProtocolProfileSloIdpSoap)) {
181
debug("building a soap response message\n");
182
profile->msg_url = lasso_provider_get_registerNameIdentifierServiceURL(provider,
185
profile->msg_body = lasso_node_export_to_soap(profile->response);
187
else if (xmlStrEqual(protocolProfile,lassoLibProtocolProfileSloSpHttp) || \
188
xmlStrEqual(protocolProfile,lassoLibProtocolProfileSloIdpHttp)) {
189
debug("building a http get response message\n");
196
lasso_name_registration_destroy(LassoNameRegistration *name_registration)
198
g_object_unref(G_OBJECT(name_registration));
202
lasso_name_registration_init_request(LassoNameRegistration *name_registration,
203
gchar *remote_providerID)
205
LassoProfile *profile;
206
LassoNode *nameIdentifier_node;
207
LassoFederation *federation;
209
xmlChar *spNameIdentifier, *spNameQualifier, *spFormat;
210
xmlChar *idpNameIdentifier, *idpNameQualifier, *idpFormat;
211
xmlChar *oldNameIdentifier = NULL, *oldNameQualifier = NULL, *oldFormat = NULL;
215
g_return_val_if_fail(LASSO_IS_NAME_REGISTRATION(name_registration), -1);
217
profile = LASSO_PROFILE(name_registration);
219
if (remote_providerID == NULL) {
220
message(G_LOG_LEVEL_INFO, "No remote provider id, get the next federation peer provider id\n");
221
profile->remote_providerID = lasso_identity_get_next_federation_remote_providerID(profile->identity);
224
message(G_LOG_LEVEL_INFO, "A remote provider id for register name identifier request : %s\n", remote_providerID);
225
profile->remote_providerID = g_strdup(remote_providerID);
227
if (profile->remote_providerID == NULL) {
228
message(G_LOG_LEVEL_CRITICAL, "No provider id for init request\n");
234
federation = lasso_identity_get_federation(profile->identity, profile->remote_providerID);
235
if (federation == NULL) {
236
message(G_LOG_LEVEL_CRITICAL, "Federation not found\n");
240
switch (profile->provider_type) {
241
case lassoProviderTypeSp:
242
/* set the new name identifier */
243
spNameIdentifier = lasso_build_unique_id(32);
244
spNameQualifier = g_strdup(profile->remote_providerID);
245
spFormat = "federated";
247
/* set the old name identifier */
248
nameIdentifier_node = lasso_federation_get_local_nameIdentifier(federation);
249
if (nameIdentifier_node != NULL) {
250
oldNameIdentifier = lasso_node_get_content(nameIdentifier_node, NULL);
251
oldNameQualifier = lasso_node_get_attr_value(nameIdentifier_node, "NameQualifier", NULL);
252
oldFormat = lasso_node_get_attr_value(nameIdentifier_node, "Format", NULL);
254
lasso_node_destroy(nameIdentifier_node);
256
/* idp name identifier */
257
nameIdentifier_node = lasso_federation_get_remote_nameIdentifier(federation);
258
if (nameIdentifier_node == NULL) {
259
message(G_LOG_LEVEL_CRITICAL, "Remote NameIdentifier for service provider not found\n");
263
idpNameIdentifier = lasso_node_get_content(nameIdentifier_node, NULL);
264
idpNameQualifier = lasso_node_get_attr_value(nameIdentifier_node, "NameQualifier", NULL);
265
idpFormat = lasso_node_get_attr_value(nameIdentifier_node, "Format", NULL);
266
lasso_node_destroy(nameIdentifier_node);
268
/* if old name identifier (Service provider) not found, set with federation provider */
269
if (oldNameIdentifier == NULL) {
270
oldNameIdentifier = g_strdup(idpNameIdentifier);
271
oldNameQualifier = g_strdup(idpNameQualifier);
272
oldFormat = g_strdup(idpFormat);
276
case lassoProviderTypeIdp:
277
debug("Federation Provider\n");
278
idpNameIdentifier = lasso_build_unique_id(32);
279
idpNameQualifier = g_strdup(profile->remote_providerID);
280
idpFormat = "federated";
282
nameIdentifier_node = lasso_federation_get_local_nameIdentifier(federation);
283
oldNameIdentifier = lasso_node_get_content(nameIdentifier_node, NULL);
284
oldNameQualifier = lasso_node_get_attr_value(nameIdentifier_node, "NameQualifier", NULL);
285
oldFormat = lasso_node_get_attr_value(nameIdentifier_node, "Format", NULL);
287
nameIdentifier_node = lasso_federation_get_remote_nameIdentifier(federation);
288
if (nameIdentifier_node != NULL) {
289
spNameIdentifier = lasso_node_get_content(nameIdentifier_node, NULL);
290
spNameQualifier = lasso_node_get_attr_value(nameIdentifier_node, "NameQualifier", NULL);
291
spFormat = lasso_node_get_attr_value(nameIdentifier_node, "Format", NULL);
294
spNameIdentifier = g_strdup(oldNameIdentifier);
295
spNameQualifier = g_strdup(oldNameQualifier);
296
spFormat = g_strdup(oldFormat);
301
message(G_LOG_LEVEL_CRITICAL, "Invalid provider type (%d)\n", profile->provider_type);
305
lasso_federation_destroy(federation);
307
debug("old name identifier : %s, old name qualifier : %s, old format : %s\n", oldNameIdentifier, oldNameQualifier, oldFormat);
308
debug("sp name identifier : %s, sp name qualifier : %s, sp format : %s\n", spNameIdentifier, spNameQualifier, spFormat);
309
debug("idp name identifier : %s, idp name qualifier : %s, idp format : %s\n", idpNameIdentifier, idpNameQualifier, idpFormat);
311
profile->request = lasso_register_name_identifier_request_new(profile->server->providerID,
322
if (profile->request == NULL) {
323
message(G_LOG_LEVEL_CRITICAL, "Error while creating the request\n");
333
gint lasso_name_registration_process_request_msg(LassoNameRegistration *name_registration,
335
lassoHttpMethod request_method)
337
LassoProfile *profile;
340
g_return_val_if_fail(LASSO_IS_NAME_REGISTRATION(name_registration), -1);
341
g_return_val_if_fail(request_msg!=NULL, -1);
343
profile = LASSO_PROFILE(name_registration);
345
switch (request_method) {
346
case lassoHttpMethodSoap:
347
debug("Build a register name identifier request from soap msg\n");
348
profile->request = lasso_register_name_identifier_request_new_from_export(request_msg, lassoNodeExportTypeSoap);
350
case lassoHttpMethodRedirect:
351
debug("Build a register name identifier request from query msg\n");
352
profile->request = lasso_register_name_identifier_request_new_from_export(request_msg, lassoNodeExportTypeQuery);
354
case lassoHttpMethodGet:
355
debug("TODO, implement the get method\n");
358
message(G_LOG_LEVEL_CRITICAL, "Invalid request method\n");
362
if (profile->request == NULL) {
363
message(G_LOG_LEVEL_CRITICAL, "Error while building the request from msg\n");
368
/* get the NameIdentifier to load identity dump */
369
profile->nameIdentifier = lasso_node_get_child_content(profile->request,
370
"NameIdentifier", NULL, NULL);
372
/* get the RelayState */
373
profile->msg_relayState = lasso_node_get_child_content(profile->request,
374
"RelayState", NULL, NULL);
382
lasso_name_registration_validate_request(LassoNameRegistration *name_registration)
384
LassoProfile *profile;
385
LassoFederation *federation;
386
LassoNode *nameIdentifier, *assertion;
387
LassoNode *statusCode;
388
LassoNodeClass *statusCode_class;
391
g_return_val_if_fail(LASSO_IS_NAME_REGISTRATION(name_registration), -1);
393
profile = LASSO_PROFILE(name_registration);
395
/* set the remote provider id from the request */
396
profile->remote_providerID = lasso_node_get_child_content(profile->request, "ProviderID", NULL, NULL);
397
if (profile->remote_providerID == NULL) {
398
message(G_LOG_LEVEL_CRITICAL, "No provider id found in name_registration request\n");
403
/* set NameRegistrationResponse */
404
profile->response = lasso_register_name_identifier_response_new(profile->server->providerID,
405
(gchar *)lassoSamlStatusCodeSuccess,
408
if (profile->response == NULL) {
409
message(G_LOG_LEVEL_CRITICAL, "Error while building response\n");
414
statusCode = lasso_node_get_child(profile->response, "StatusCode", NULL, NULL);
415
statusCode_class = LASSO_NODE_GET_CLASS(statusCode);
417
nameIdentifier = lasso_node_get_child(profile->request, "NameIdentifier", NULL, NULL);
418
if (nameIdentifier == NULL) {
419
message(G_LOG_LEVEL_CRITICAL, "No name identifier found in name_registration request\n");
420
statusCode_class->set_prop(statusCode, "Value", lassoLibStatusCodeFederationDoesNotExist);
425
/* Verify federation */
426
federation = lasso_identity_get_federation(profile->identity, profile->remote_providerID);
427
if (federation == NULL) {
428
message(G_LOG_LEVEL_WARNING, "No federation for %s\n", profile->remote_providerID);
429
statusCode_class->set_prop(statusCode, "Value", lassoLibStatusCodeFederationDoesNotExist);
434
if (lasso_federation_verify_nameIdentifier(federation, nameIdentifier) == FALSE) {
435
message(G_LOG_LEVEL_WARNING, "No name identifier for %s\n", profile->remote_providerID);
436
statusCode_class->set_prop(statusCode, "Value", lassoLibStatusCodeFederationDoesNotExist);
440
lasso_federation_destroy(federation);
442
/* verify authentication (if ok, delete assertion) */
443
assertion = lasso_session_get_assertion(profile->session, profile->remote_providerID);
444
if (assertion == NULL) {
445
message(G_LOG_LEVEL_WARNING, "%s has no assertion\n", profile->remote_providerID);
446
statusCode_class->set_prop(statusCode, "Value", lassoSamlStatusCodeRequestDenied);
447
lasso_node_destroy(assertion);
458
lasso_name_registration_process_response_msg(LassoNameRegistration *name_registration,
460
lassoHttpMethod response_method)
462
LassoProfile *profile;
463
xmlChar *statusCodeValue;
464
LassoNode *statusCode;
467
g_return_val_if_fail(LASSO_IS_NAME_REGISTRATION(name_registration), -1);
468
g_return_val_if_fail(response_msg != NULL, -1);
470
profile = LASSO_PROFILE(name_registration);
472
/* parse NameRegistrationResponse */
473
switch (response_method) {
474
case lassoHttpMethodSoap:
475
profile->response = lasso_register_name_identifier_response_new_from_export(response_msg, lassoNodeExportTypeSoap);
477
case lassoHttpMethodRedirect:
478
profile->response = lasso_register_name_identifier_response_new_from_export(response_msg, lassoNodeExportTypeQuery);
481
message(G_LOG_LEVEL_CRITICAL, "Unknown response method\n");
486
statusCode = lasso_node_get_child(profile->response, "StatusCode", NULL, NULL);
487
if (statusCode == NULL) {
488
message(G_LOG_LEVEL_CRITICAL, "StatusCode not found\n");
492
statusCodeValue = lasso_node_get_attr_value(statusCode, "Value", NULL);
493
if (statusCodeValue == NULL) {
494
message(G_LOG_LEVEL_CRITICAL, "StatusCodeValue not found\n");
499
if(!xmlStrEqual(statusCodeValue, lassoSamlStatusCodeSuccess)) {
509
/*****************************************************************************/
510
/* overrided parent class methods */
511
/*****************************************************************************/
514
lasso_name_registration_finalize(LassoNameRegistration *name_registration)
516
message(G_LOG_LEVEL_INFO, "Register Name Identifier object 0x%x finalized ...\n", name_registration);
518
parent_class->finalize(G_OBJECT(name_registration));
521
/*****************************************************************************/
522
/* instance and class init functions */
523
/*****************************************************************************/
526
lasso_name_registration_instance_init(LassoNameRegistration *name_registration)
531
lasso_name_registration_class_init(LassoNameRegistrationClass *class)
533
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
535
parent_class = g_type_class_peek_parent(class);
536
/* override parent class methods */
537
gobject_class->finalize = (void *)lasso_name_registration_finalize;
540
GType lasso_name_registration_get_type() {
541
static GType this_type = 0;
544
static const GTypeInfo this_info = {
545
sizeof (LassoNameRegistrationClass),
548
(GClassInitFunc) lasso_name_registration_class_init,
551
sizeof(LassoNameRegistration),
553
(GInstanceInitFunc) lasso_name_registration_instance_init,
556
this_type = g_type_register_static(LASSO_TYPE_PROFILE,
557
"LassoNameRegistration",
563
LassoNameRegistration *
564
lasso_name_registration_new(LassoServer *server,
565
lassoProviderType provider_type)
567
LassoNameRegistration *name_registration;
569
g_return_val_if_fail(LASSO_IS_SERVER(server), NULL);
571
/* set the name_registration object */
572
name_registration = g_object_new(LASSO_TYPE_NAME_REGISTRATION,
573
"server", lasso_server_copy(server),
574
"provider_type", provider_type,
577
return name_registration;