summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-02-22 13:30:33 +0000
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-02-22 13:30:33 +0000
commit1ee8f53663dc8eb96c2671412c27dddc96a7a831 (patch)
tree8fcc12682ad2016c86e1053cc71cee93097d4049
parent432b54a79dae62687c7eeee6d8cf2da90d38a7cb (diff)
downloadlasso-1ee8f53663dc8eb96c2671412c27dddc96a7a831.tar.gz
lasso-1ee8f53663dc8eb96c2671412c27dddc96a7a831.tar.xz
lasso-1ee8f53663dc8eb96c2671412c27dddc96a7a831.zip
ID-WSF 2.0: reorganize EPR minting, add a process_request method to disco service
* data_service.c: remove dependency on discovery.h * discovery.{c,h}: - add a lasso_idwsf2_discovery_process_request_msg to extract request data before validate request (SvcMDID, SvcMD or RequestService). - store SvcMDID in a private field, add a setter for it. - SvcMDID is now used for building response to MDAssociationQuery and parsing request for MDQuery, MDDelete, MDAssociationAdd and MDAssociationDelete. * idwsf2_helper.{c,h}: - change security mechanism argument of lasso_wsa_endpoint_reference_add_security_token from a NULL terminated string array to a GList. * saml2_login.{c,h}: - add a lasso_server_create_assertion_as_idwsf2_security_token for minting assertion for ID-WSF 2.0 security, to be used in Discovery bootstap EPR creation and EPR minting for Discovery service Query responses. - add a lasso_saml2_assertion_get_discovery_bootstrap_epr, and rewirte lasso_login_idwsf2_get_discovery_bootstrap_epr to use it. - make lasso_login_idwsf2_add_discovery_bootstrap_epr accept a list of security mechanisms, not just one. * tests/idwsf2_tests.c: - adapt to new argument type of lasso_login_idwsf2_add_discovery_bootstrap_epr.
-rw-r--r--lasso/id-wsf-2.0/data_service.c3
-rw-r--r--lasso/id-wsf-2.0/discovery.c249
-rw-r--r--lasso/id-wsf-2.0/discovery.h10
-rw-r--r--lasso/id-wsf-2.0/idwsf2_helper.c14
-rw-r--r--lasso/id-wsf-2.0/idwsf2_helper.h2
-rw-r--r--lasso/id-wsf-2.0/profile.c3
-rw-r--r--lasso/id-wsf-2.0/saml2_login.c148
-rw-r--r--lasso/id-wsf-2.0/saml2_login.h13
-rw-r--r--lasso/id-wsf-2.0/soap_binding.c2
-rw-r--r--tests/idwsf2_tests.c4
10 files changed, 315 insertions, 133 deletions
diff --git a/lasso/id-wsf-2.0/data_service.c b/lasso/id-wsf-2.0/data_service.c
index d323a48d..916a9700 100644
--- a/lasso/id-wsf-2.0/data_service.c
+++ b/lasso/id-wsf-2.0/data_service.c
@@ -34,8 +34,7 @@
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
-#include "discovery.h"
-#include "data_service.h"
+#include "./data_service.h"
#include "../xml/id-wsf-2.0/disco_service_type.h"
#include "../xml/id-wsf-2.0/dstref_query.h"
diff --git a/lasso/id-wsf-2.0/discovery.c b/lasso/id-wsf-2.0/discovery.c
index 5a4ef82a..25baedb1 100644
--- a/lasso/id-wsf-2.0/discovery.c
+++ b/lasso/id-wsf-2.0/discovery.c
@@ -85,6 +85,7 @@
#include "./discovery.h"
#include "./soap_binding.h"
#include "./idwsf2_helper.h"
+#include "./saml2_login.h"
#include "../utils.h"
struct _LassoIdWsf2DiscoveryPrivate
@@ -92,6 +93,7 @@ struct _LassoIdWsf2DiscoveryPrivate
gboolean dispose_has_run;
GList *metadatas; /* of LassoIdWsf2DiscoSvcMetadata* */
GList *requested_services; /* of LassoIdWsf2DiscoRequestedService */
+ GList *svcmdids; /* of utf8 */
};
#define LASSO_IDWSF2_DISCOVERY_ELEMENT_METADATAS "Metadatas"
@@ -99,11 +101,11 @@ struct _LassoIdWsf2DiscoveryPrivate
#define LASSO_IDWSF2_DISCOVERY_ELEMENT_REQUESTED_SERVICES "RequestedServices"
-static void
+static int
lasso_idwsf2_discovery_add_identity_to_epr(LassoIdWsf2Discovery *discovery,
LassoWsAddrMetadata *epr_metadata,
const char *provider_id,
- const char *security_mech_id)
+ const char *security_mechanism)
{
LassoIdentity *identity = discovery->parent.parent.identity;
LassoFederation *federation = NULL;
@@ -111,38 +113,34 @@ lasso_idwsf2_discovery_add_identity_to_epr(LassoIdWsf2Discovery *discovery,
LassoProvider *provider = NULL;
LassoIdWsf2DiscoSecurityContext *security_context;
LassoIdWsf2SecToken *sec_token;
- LassoSaml2NameID *name_id;
- if (LASSO_IS_IDENTITY(identity))
- return;
+ if (! LASSO_IS_IDENTITY(identity))
+ return LASSO_PROFILE_ERROR_IDENTITY_NOT_FOUND;
federation = lasso_identity_get_federation(identity, provider_id);
- if (federation == NULL || ! LASSO_IS_SAML2_NAME_ID(federation->remote_nameIdentifier))
- return;
- name_id = (LassoSaml2NameID*)federation->remote_nameIdentifier;
- assertion = (LassoSaml2Assertion*)lasso_saml2_assertion_new();
- lasso_server_saml2_assertion_setup_signature(discovery->parent.parent.server, assertion);
+ if (federation == NULL || ! LASSO_IS_SAML2_NAME_ID(federation->local_nameIdentifier))
+ return LASSO_PROFILE_ERROR_IDENTITY_NOT_FOUND;
provider = lasso_server_get_provider(discovery->parent.parent.server, provider_id);
- if (provider)
- lasso_saml2_assertion_set_subject_name_id(assertion,
- (LassoNode*)lasso_saml2_encrypted_element_build_encrypted_persistent_name_id(
- name_id->content,
- name_id->NameQualifier,
- provider));
- else
- lasso_saml2_assertion_set_subject_name_id(assertion,
- (LassoNode*)lasso_saml2_name_id_build_persistent(
- name_id->content,
- name_id->NameQualifier,
- provider_id));
+ if (! provider) {
+ return LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND;
+ }
+
+ assertion =
+ lasso_server_create_assertion_as_idwsf2_security_token(discovery->parent.parent.server,
+ LASSO_SAML2_NAME_ID(federation->local_nameIdentifier),
+ LASSO_DURATION_HOUR, 2 * LASSO_DURATION_DAY, provider ? TRUE :
+ FALSE, provider);
sec_token = (LassoIdWsf2SecToken*)lasso_idwsf2_sec_token_new();
sec_token->any = (LassoNode*)assertion;
security_context = (LassoIdWsf2DiscoSecurityContext*)
lasso_idwsf2_disco_security_context_new();
lasso_list_add_string(security_context->SecurityMechID,
- security_mech_id);
+ security_mechanism);
+ lasso_list_add_new_gobject(security_context->Token, sec_token);
lasso_list_add_new_gobject(epr_metadata->any, security_context);
+
+ return 0;
}
@@ -372,7 +370,8 @@ lasso_idwsf2_discovery_add_service_metadata(LassoIdWsf2Discovery *discovery,
* @service_types:(element-type utf8)(allow-none): an array of service type URIs
* @options:(element-type LassoIdWsf2DiscoOptions)(allow-none): an array of option string
* @address:(allow-none): the URI of the service endpoint for the default EndpointContext
- * @security_mech_ids:(allow-none)(element-type utf8): the security mechanisms supported by the service
+ * @security_mechanisms:(allow-none)(element-type utf8): the security mechanisms supported by the
+ * service
*
* Add new metadata to the current Metadata Register request.
*
@@ -381,7 +380,7 @@ lasso_idwsf2_discovery_add_service_metadata(LassoIdWsf2Discovery *discovery,
int
lasso_idwsf2_discovery_add_simple_service_metadata(LassoIdWsf2Discovery *idwsf2_discovery,
const char *abstract, const char *provider_id, GList *service_types, GList *options,
- const char *address, GList *security_mech_ids)
+ const char *address, GList *security_mechanisms)
{
LassoIdWsf2DiscoSvcMetadata *service_metadata;
LassoIdWsf2DiscoServiceContext *service_context;
@@ -408,9 +407,10 @@ lasso_idwsf2_discovery_add_simple_service_metadata(LassoIdWsf2Discovery *idwsf2_
if (address) {
lasso_list_add_string(endpoint_context->Address, address);
}
- lasso_list_add_new_gobject(endpoint_context->Framework, lasso_idwsf2_sbf_framework_new_full("2.0"));
- if (security_mech_ids) {
- lasso_assign_list_of_strings(endpoint_context->SecurityMechID, security_mech_ids);
+ lasso_list_add_new_gobject(endpoint_context->Framework,
+ lasso_idwsf2_sbf_framework_new_full("2.0"));
+ if (security_mechanisms) {
+ lasso_assign_list_of_strings(endpoint_context->SecurityMechID, security_mechanisms);
}
lasso_list_add_new_gobject(service_context->EndpointContext, endpoint_context);
@@ -472,54 +472,36 @@ cleanup:
*
* Return the list of SvcMDID, or service metadata ids, returned by the last discovery query.
*
- * Return value:(transfer none)(element-type utf8): a list of SvcMDID's.
+ * Return value:(transfer none)(element-type utf8)(allow-none): a list of SvcMDID's.
*/
GList*
lasso_idwsf2_discovery_get_svcmdids(LassoIdWsf2Discovery *discovery)
{
- GList *content;
- GList **svc_md_ids;
-
- if (! LASSO_IS_IDWSF2_DISCOVERY(discovery))
+ if (! LASSO_IS_IDWSF2_DISCOVERY(discovery) || ! discovery->private_data)
return NULL;
- content =
- lasso_soap_envelope_get_body_content(
- lasso_idwsf2_profile_get_soap_envelope_request(
- &discovery->parent));
- switch (lasso_idwsf2_discovery_get_request_type(discovery)) {
- case LASSO_IDWSF2_DISCOVERY_REQUEST_TYPE_MD_QUERY:
- svc_md_ids = &((LassoIdWsf2DiscoSvcMDQuery*)
- lasso_list_get_first_child(content))->SvcMDID;
- break;
- case LASSO_IDWSF2_DISCOVERY_REQUEST_TYPE_MD_DELETE:
- svc_md_ids = &((LassoIdWsf2DiscoSvcMDDelete*)
- lasso_list_get_first_child(content))->SvcMDID;
- case LASSO_IDWSF2_DISCOVERY_REQUEST_TYPE_MD_ASSOCIATION_ADD:
- svc_md_ids = &((LassoIdWsf2DiscoSvcMDAssociationAdd*)
- lasso_list_get_first_child(content))->SvcMDID;
- break;
- case LASSO_IDWSF2_DISCOVERY_REQUEST_TYPE_MD_ASSOCIATION_DELETE:
- svc_md_ids = &((LassoIdWsf2DiscoSvcMDAssociationDelete*)
- lasso_list_get_first_child(content))->SvcMDID;
- break;
- case LASSO_IDWSF2_DISCOVERY_REQUEST_TYPE_MD_ASSOCIATION_QUERY:
- svc_md_ids = &((LassoIdWsf2DiscoSvcMDAssociationQuery*)
- lasso_list_get_first_child(content))->SvcMDID;
- break;
- default:
- break;
- }
- if (svc_md_ids) {
- return *svc_md_ids;
- }
- return NULL;
+ return discovery->private_data->svcmdids;
}
+/**
+ * lasso_idwsf2_discovery_set_svcmdids:
+ * @discovery: a #LassoIdWsf2Discovery object
+ * @svcmdids:(element-type utf8)(allow-none): a list of service metadata IDs
+ *
+ * Set the list of SvcMDID, or service metadata ids.
+ *
+ */
+void
+lasso_idwsf2_discovery_set_svcmdids(LassoIdWsf2Discovery *discovery, GList *svcmdids)
+{
+ if (! LASSO_IS_IDWSF2_DISCOVERY(discovery) || ! discovery->private_data)
+ return;
+ lasso_assign_list_of_strings(discovery->private_data->svcmdids, svcmdids);
+}
/**
* lasso_idwsf2_discovery_build_request_msg:
* @discovery: a #LassoIdWsf2Discovery object
- * @security_mech_id:(allow-none):the security mech id to use, if NULL a Bearer mechanism is used.
+ * @security_mechanism:(allow-none):the security mech id to use, if NULL a Bearer mechanism is used.
*
* Build the request message using a security mechanism to authenticate the requester and the target
* identity. If none is given Bearer mechanism is used.
@@ -528,7 +510,7 @@ lasso_idwsf2_discovery_get_svcmdids(LassoIdWsf2Discovery *discovery)
*/
gint
lasso_idwsf2_discovery_build_request_msg(LassoIdWsf2Discovery *discovery,
- const char *security_mech_id)
+ const char *security_mechanism)
{
GList *content = NULL;
LassoIdWsf2DiscoQuery *query = NULL;
@@ -560,9 +542,11 @@ lasso_idwsf2_discovery_build_request_msg(LassoIdWsf2Discovery *discovery,
check_svcMDID = TRUE;
metadatas = &((LassoIdWsf2DiscoSvcMDReplace*)
lasso_list_get_first_child(content))->SvcMD;
+ break;
case LASSO_IDWSF2_DISCOVERY_REQUEST_TYPE_MD_DELETE:
svc_md_ids = &((LassoIdWsf2DiscoSvcMDDelete*)
lasso_list_get_first_child(content))->SvcMDID;
+ break;
case LASSO_IDWSF2_DISCOVERY_REQUEST_TYPE_MD_ASSOCIATION_ADD:
svc_md_ids = &((LassoIdWsf2DiscoSvcMDAssociationAdd*)
lasso_list_get_first_child(content))->SvcMDID;
@@ -598,21 +582,95 @@ lasso_idwsf2_discovery_build_request_msg(LassoIdWsf2Discovery *discovery,
}
}
if (svc_md_ids) {
- GList *i;
- lasso_foreach(i, discovery->private_data->metadatas)
- {
- if (LASSO_IS_IDWSF2_DISCO_SVC_METADATA(i->data)) {
- lasso_list_add_string(*svc_md_ids,
- ((LassoIdWsf2DiscoSvcMetadata*)i->data)->svcMDID);
- }
- }
+ lasso_assign_list_of_strings(*svc_md_ids, discovery->private_data->svcmdids);
}
- rc = lasso_idwsf2_profile_build_request_msg(&discovery->parent, security_mech_id);
+ rc = lasso_idwsf2_profile_build_request_msg(&discovery->parent, security_mechanism);
cleanup:
return rc;
}
/**
+ * lasso_idwsf2_discovery_process_request_msg:
+ * @discovery: a #LassoIdWsf2Discovery object
+ * @message: a received SOAP message
+ *
+ * Parse a Discovery service request.
+ *
+ * Return value: 0 if sucessful, an error code otherwise among:
+ * <itemizedlist>
+ * <listitem><para>LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if @profile is not a #LassoIdWsf2Profile
+ * object,</para></listitem>
+ * <listitem><para>LASSO_PARAM_ERROR_INVALID_VALUE if message is NULL,</para></listitem>
+ * <listitem><para>LASSO_PROFILE_ERROR_INVALID_MSG if we cannot parse the message,</para></listitem>
+ * <listitem><para>LASSO_SOAP_ERROR_MISSING_BODY if the message has no body
+ * content.</para></listitem>
+ * </itemizedlist>
+ */
+int
+lasso_idwsf2_discovery_process_request_msg(LassoIdWsf2Discovery *discovery, const char *message)
+{
+ LassoProfile *profile;
+ LassoIdWsf2Profile *idwsf2_profile;
+ GList *content;
+ GList **svc_md_ids = NULL, **metadatas = NULL, **service_types = NULL;
+ int rc;
+
+ lasso_bad_param(IDWSF2_DISCOVERY, discovery);
+ idwsf2_profile = &discovery->parent;
+ profile = &idwsf2_profile->parent;
+
+ lasso_check_good_rc(lasso_idwsf2_profile_process_request_msg(idwsf2_profile, message));
+
+ content =
+ lasso_soap_envelope_get_body_content(
+ lasso_idwsf2_profile_get_soap_envelope_request(
+ &discovery->parent));
+ switch (lasso_idwsf2_discovery_get_request_type(discovery)) {
+ case LASSO_IDWSF2_DISCOVERY_REQUEST_TYPE_MD_REGISTER:
+ metadatas = &((LassoIdWsf2DiscoSvcMDRegister*)
+ lasso_list_get_first_child(content))->SvcMD;
+ break;
+ case LASSO_IDWSF2_DISCOVERY_REQUEST_TYPE_QUERY:
+ service_types = &((LassoIdWsf2DiscoQuery*)
+ lasso_list_get_first_child(content))->RequestedService;
+ case LASSO_IDWSF2_DISCOVERY_REQUEST_TYPE_MD_QUERY:
+ svc_md_ids = &((LassoIdWsf2DiscoSvcMDQuery*)
+ lasso_list_get_first_child(content))->SvcMDID;
+ break;
+ case LASSO_IDWSF2_DISCOVERY_REQUEST_TYPE_MD_DELETE:
+ svc_md_ids = &((LassoIdWsf2DiscoSvcMDDelete*)
+ lasso_list_get_first_child(content))->SvcMDID;
+ case LASSO_IDWSF2_DISCOVERY_REQUEST_TYPE_MD_ASSOCIATION_ADD:
+ svc_md_ids = &((LassoIdWsf2DiscoSvcMDAssociationAdd*)
+ lasso_list_get_first_child(content))->SvcMDID;
+ break;
+ case LASSO_IDWSF2_DISCOVERY_REQUEST_TYPE_MD_ASSOCIATION_DELETE:
+ svc_md_ids = &((LassoIdWsf2DiscoSvcMDAssociationDelete*)
+ lasso_list_get_first_child(content))->SvcMDID;
+ break;
+ case LASSO_IDWSF2_DISCOVERY_REQUEST_TYPE_MD_ASSOCIATION_QUERY:
+ svc_md_ids = &((LassoIdWsf2DiscoSvcMDAssociationQuery*)
+ lasso_list_get_first_child(content))->SvcMDID;
+ break;
+ default:
+ break;
+ }
+ if (discovery->private_data && svc_md_ids) {
+ lasso_assign_list_of_strings(discovery->private_data->svcmdids, *svc_md_ids);
+ }
+ if (metadatas) {
+ lasso_assign_list_of_gobjects(discovery->private_data->metadatas, *metadatas);
+ }
+ if (service_types) {
+ lasso_assign_list_of_gobjects(discovery->private_data->requested_services, *service_types);
+ }
+
+cleanup:
+ return rc;
+}
+
+
+/**
* lasso_idwsf2_discovery_get_request_type:
* @discovery: a #LassoIdWsf2Discovery object
*
@@ -808,8 +866,8 @@ lasso_idwsf2_discovery_match_request_service_and_metadata2(
GList *i;
gboolean result = TRUE;
gboolean option_result = TRUE;
- LassoIdWsf2DiscoOptions *options;
- GList *service_options;
+ LassoIdWsf2DiscoOptions *options = NULL;
+ GList *service_options = NULL;
result = result &&
@@ -848,7 +906,14 @@ lasso_idwsf2_discovery_match_request_service_and_metadata2(
_string_list_intersect(requested_service->Framework, endpoint_context->Framework);
} else {
/* FIXME: should be the value of the query SOAP header sbf:Framework */
- result = result && _string_list_contains(endpoint_context->Framework, "2.0");
+ GList *k;
+ gboolean has20 = FALSE;
+ lasso_foreach (k, endpoint_context->Framework) {
+ LassoIdWsf2SbfFramework *framework = k->data;
+ if (LASSO_IS_IDWSF2_SBF_FRAMEWORK(framework) && g_strcmp0(framework->version, "2.0") == 0)
+ has20 = TRUE;
+ }
+ result = result && has20;
}
}
if (result) {
@@ -1020,6 +1085,9 @@ lasso_idwsf2_discovery_validate_request(LassoIdWsf2Discovery *discovery)
lasso_list_add_gobject(md_query_response->SvcMD, i->data);
}
}
+ } else {
+ lasso_assign_list_of_gobjects(md_query_response->SvcMD,
+ discovery->private_data->metadatas);
}
status = &md_query_response->Status;
break;
@@ -1119,6 +1187,9 @@ lasso_idwsf2_discovery_process_metadata_register_response_msg(LassoIdWsf2Discove
i = i->next;
j = j->next;
}
+ if (discovery->private_data && discovery->private_data->metadatas != request->SvcMD) {
+ lasso_assign_list_of_gobjects(discovery->private_data->metadatas, request->SvcMD);
+ }
cleanup:
return rc;
}
@@ -1130,10 +1201,11 @@ cleanup:
* @service_types:(element-type utf8)(allow-none): the service type (or data profile) requested
* @provider_ids:(element-type utf8)(allow-none): the providers ids to select
* @options:(element-type utf8)(allow-none): the options to select
- * @security_mech_ids:(element-type utf8)(allow-none): the security mechanisms to select
+ * @security_mechanisms:(element-type utf8)(allow-none): the security mechanisms to select
* @frameworks:(element-type utf8)(allow-none): the ID-WSF framework version to select
* @actions:(element-type utf8)(allow-none): the actions to select
- * @result_type:(allow-none)(default LASSO_IDWSF2_DISCOVERY_QUERY_RESULT_TYPE_NONE): how to filter the generated EPRs
+ * @result_type:(allow-none)(default LASSO_IDWSF2_DISCOVERY_QUERY_RESULT_TYPE_NONE): how to filter
+ * the generated EPRs
* @req_id:(allow-none): an eventual ID to put on the request, that can be matched with the
* generated EndpointReferences
*
@@ -1144,7 +1216,7 @@ cleanup:
**/
gint
lasso_idwsf2_discovery_add_requested_service(LassoIdWsf2Discovery *discovery,
- GList *service_types, GList *provider_ids, GList *options, GList *security_mech_ids,
+ GList *service_types, GList *provider_ids, GList *options, GList *security_mechanisms,
GList *frameworks, GList *actions, LassoIdWsf2DiscoveryQueryResultType result_type,
const char *req_id)
{
@@ -1159,7 +1231,7 @@ lasso_idwsf2_discovery_add_requested_service(LassoIdWsf2Discovery *discovery,
lasso_assign_list_of_strings(service->ProviderID, provider_ids);
lasso_assign_list_of_strings(service->Framework, frameworks);
lasso_assign_list_of_strings(service->Action, actions);
- lasso_assign_list_of_strings(service->SecurityMechID, security_mech_ids);
+ lasso_assign_list_of_strings(service->SecurityMechID, security_mechanisms);
lasso_assign_list_of_gobjects(service->Options, options);
switch (result_type) {
case LASSO_IDWSF2_DISCOVERY_QUERY_RESULT_TYPE_BEST:
@@ -1205,9 +1277,9 @@ lasso_idwsf2_discovery_process_response_msg(LassoIdWsf2Discovery *discovery,
lasso_bad_param(IDWSF2_DISCOVERY, discovery);
profile = &discovery->parent.parent;
- response = profile->response;
lasso_check_good_rc(lasso_idwsf2_profile_process_response_msg(&discovery->parent, msg));
+ response = profile->response;
switch (lasso_idwsf2_discovery_get_request_type(discovery)) {
case LASSO_IDWSF2_DISCOVERY_REQUEST_TYPE_QUERY:
@@ -1320,7 +1392,8 @@ get_xmlNode(LassoNode *node, gboolean lasso_dump)
if (pdata->requested_services) {
xmlNode *requested_services;
GList *i;
- requested_services = xmlNewChild(xmlnode, NULL, BAD_CAST LASSO_IDWSF2_DISCOVERY_ELEMENT_REQUESTED_SERVICES, NULL);
+ requested_services = xmlNewChild(xmlnode, NULL, BAD_CAST
+ LASSO_IDWSF2_DISCOVERY_ELEMENT_REQUESTED_SERVICES, NULL);
lasso_foreach(i, pdata->requested_services) {
xmlAddChild(requested_services, lasso_node_get_xmlNode(i->data, lasso_dump));
}
@@ -1345,8 +1418,12 @@ init_from_xml(LassoNode *node, xmlNode *xmlnode)
if (xmlnode == NULL)
return LASSO_XML_ERROR_OBJECT_CONSTRUCTION_FAILED;
- metadatas_node = xmlSecFindChild(xmlnode, BAD_CAST LASSO_IDWSF2_DISCOVERY_ELEMENT_METADATAS, BAD_CAST LASSO_LASSO_HREF);
- requested_services_node = xmlSecFindChild(xmlnode, BAD_CAST LASSO_IDWSF2_DISCOVERY_ELEMENT_REQUESTED_SERVICES, BAD_CAST LASSO_LASSO_HREF);
+ metadatas_node = xmlSecFindChild(xmlnode,
+ BAD_CAST LASSO_IDWSF2_DISCOVERY_ELEMENT_METADATAS,
+ BAD_CAST LASSO_LASSO_HREF);
+ requested_services_node = xmlSecFindChild(xmlnode,
+ BAD_CAST LASSO_IDWSF2_DISCOVERY_ELEMENT_REQUESTED_SERVICES,
+ BAD_CAST LASSO_LASSO_HREF);
if (! discovery->private_data) {
discovery->private_data = g_new0(LassoIdWsf2DiscoveryPrivate, 1);
diff --git a/lasso/id-wsf-2.0/discovery.h b/lasso/id-wsf-2.0/discovery.h
index ca75194e..bdb83595 100644
--- a/lasso/id-wsf-2.0/discovery.h
+++ b/lasso/id-wsf-2.0/discovery.h
@@ -105,6 +105,7 @@ LASSO_EXPORT gint lasso_idwsf2_discovery_init_query(LassoIdWsf2Discovery *discov
LASSO_EXPORT gint lasso_idwsf2_discovery_init_metadata_query(LassoIdWsf2Discovery *discovery);
LASSO_EXPORT gint lasso_idwsf2_discovery_init_metadata_register(LassoIdWsf2Discovery *discovery);
LASSO_EXPORT gint lasso_idwsf2_discovery_init_metadata_replace(LassoIdWsf2Discovery *discovery);
+LASSO_EXPORT gint lasso_idwsf2_discovery_init_metadata_delete(LassoIdWsf2Discovery *discovery);
LASSO_EXPORT gint lasso_idwsf2_discovery_init_metadata_association_add(
LassoIdWsf2Discovery *discovery);
LASSO_EXPORT gint lasso_idwsf2_discovery_init_metadata_association_delete(
@@ -118,18 +119,20 @@ LASSO_EXPORT int lasso_idwsf2_discovery_add_service_metadata(
LASSO_EXPORT int lasso_idwsf2_discovery_add_simple_service_metadata(
LassoIdWsf2Discovery *idwsf2_discovery, const char *abstract,
const char *provider_id, GList *service_types, GList *options, const char *address,
- GList *security_mech_ids);
+ GList *security_mechanisms);
LASSO_EXPORT GList* lasso_idwsf2_discovery_get_metadatas(LassoIdWsf2Discovery *discovery);
LASSO_EXPORT gint lasso_idwsf2_discovery_add_requested_service(LassoIdWsf2Discovery *discovery,
- GList *service_types, GList *provider_ids, GList *options, GList *security_mech_ids,
+ GList *service_types, GList *provider_ids, GList *options, GList *security_mechanisms,
GList *frameworks, GList *actions, LassoIdWsf2DiscoveryQueryResultType result_type,
const char *req_id);
/* Build the request message */
LASSO_EXPORT gint lasso_idwsf2_discovery_build_request_msg(LassoIdWsf2Discovery *discovery,
- const char *security_mech_id);
+ const char *security_mechanism);
/* Handle a request */
+LASSO_EXPORT int lasso_idwsf2_discovery_process_request_msg(LassoIdWsf2Discovery *discovery,
+ const char *message);
LASSO_EXPORT LassoIdWsf2DiscoveryRequestType lasso_idwsf2_discovery_get_request_type(LassoIdWsf2Discovery *discovery);
LASSO_EXPORT gint lasso_idwsf2_discovery_validate_request(LassoIdWsf2Discovery *discovery);
LASSO_EXPORT gint lasso_idwsf2_discovery_fail_request(LassoIdWsf2Discovery *discovery,
@@ -140,6 +143,7 @@ LASSO_EXPORT gint lasso_idwsf2_discovery_process_response_msg(LassoIdWsf2Discove
const char *msg);
LASSO_EXPORT GList* lasso_idwsf2_discovery_get_endpoint_references(LassoIdWsf2Discovery *discovery);
LASSO_EXPORT GList* lasso_idwsf2_discovery_get_svcmdids(LassoIdWsf2Discovery *discovery);
+LASSO_EXPORT void lasso_idwsf2_discovery_set_svcmdids(LassoIdWsf2Discovery *discovery, GList *svcmdids);
#ifdef __cplusplus
diff --git a/lasso/id-wsf-2.0/idwsf2_helper.c b/lasso/id-wsf-2.0/idwsf2_helper.c
index c7173e1c..33326c75 100644
--- a/lasso/id-wsf-2.0/idwsf2_helper.c
+++ b/lasso/id-wsf-2.0/idwsf2_helper.c
@@ -279,7 +279,7 @@ lasso_wsa_endpoint_reference_new_for_idwsf2_service(const char *address,
* lasso_wsa_endpoint_reference_add_security_token:
* @epr: a #LassoWsAddrEndpointReference object
* @security_token: a security token as a #LassoNode object
- * @security_mechanisms:(in)(transfer none)(array zero-terminated=1): a list of security mechanism
+ * @security_mechanisms:(element-type utf8): a list of security mechanism
* for whom the token is made
*
* Add a new security context declaration for the given security mechanisms identifiers and populate
@@ -289,7 +289,7 @@ lasso_wsa_endpoint_reference_new_for_idwsf2_service(const char *address,
*/
int
lasso_wsa_endpoint_reference_add_security_token(LassoWsAddrEndpointReference *epr,
- LassoNode *security_token, const char **security_mechanisms)
+ LassoNode *security_token, GList *security_mechanisms)
{
LassoIdWsf2SecToken *sec_token = NULL;
LassoWsAddrMetadata *metadata = NULL;
@@ -298,10 +298,6 @@ lasso_wsa_endpoint_reference_add_security_token(LassoWsAddrEndpointReference *ep
lasso_bad_param(WSA_ENDPOINT_REFERENCE, epr);
lasso_bad_param(NODE, security_token);
- lasso_null_param(security_mechanisms);
- if (security_mechanisms[0] == NULL) {
- return LASSO_PARAM_ERROR_INVALID_VALUE;
- }
lasso_extract_node_or_fail(metadata, epr->Metadata, WSA_METADATA, LASSO_PARAM_ERROR_INVALID_VALUE);
@@ -310,10 +306,8 @@ lasso_wsa_endpoint_reference_add_security_token(LassoWsAddrEndpointReference *ep
lasso_assign_string(sec_token->usage, LASSO_IDWSF2_SEC_TOKEN_USAGE_SECURITY_TOKEN);
security_context = lasso_idwsf2_disco_security_context_new();
- while (security_mechanisms[0] != NULL) {
- lasso_list_add_string(security_context->SecurityMechID, security_mechanisms[0]);
- ++security_mechanisms;
- }
+ lasso_assign_list_of_strings(security_context->SecurityMechID,
+ security_mechanisms);
lasso_list_add_new_gobject(security_context->Token, sec_token);
lasso_list_add_new_gobject(metadata->any, security_context);
cleanup:
diff --git a/lasso/id-wsf-2.0/idwsf2_helper.h b/lasso/id-wsf-2.0/idwsf2_helper.h
index a9aeb38c..a2e469e2 100644
--- a/lasso/id-wsf-2.0/idwsf2_helper.h
+++ b/lasso/id-wsf-2.0/idwsf2_helper.h
@@ -59,7 +59,7 @@ LASSO_EXPORT LassoWsAddrEndpointReference* lasso_wsa_endpoint_reference_new_for_
const char *abstract);
LASSO_EXPORT int lasso_wsa_endpoint_reference_add_security_token(LassoWsAddrEndpointReference *epr,
- LassoNode *security_token, const char **security_mechanisms);
+ LassoNode *security_token, GList *security_mechanisms);
LASSO_EXPORT LassoIdWsf2Profile *lasso_wsa_endpoint_reference_get_service(
LassoWsAddrEndpointReference *epr);
diff --git a/lasso/id-wsf-2.0/profile.c b/lasso/id-wsf-2.0/profile.c
index 51d8251b..7f9ca7e8 100644
--- a/lasso/id-wsf-2.0/profile.c
+++ b/lasso/id-wsf-2.0/profile.c
@@ -422,6 +422,9 @@ lasso_idwsf2_profile_check_security_mechanism(LassoIdWsf2Profile *profile,
provider_id = lasso_soap_envelope_sb2_get_provider_id(envelope);
if (! provider_id)
goto cleanup;
+ if (! profile->parent.server)
+ goto_cleanup_with_rc(LASSO_PROFILE_ERROR_MISSING_SERVER);
+ lasso_check_good_rc(lasso_saml2_assertion_decrypt_subject(assertion, profile->parent.server));
if (! assertion || ! assertion->Subject || ! assertion->Subject->NameID
|| ! assertion->Subject->NameID->SPNameQualifier)
goto cleanup;
diff --git a/lasso/id-wsf-2.0/saml2_login.c b/lasso/id-wsf-2.0/saml2_login.c
index 1d6f4f69..dafe58a3 100644
--- a/lasso/id-wsf-2.0/saml2_login.c
+++ b/lasso/id-wsf-2.0/saml2_login.c
@@ -28,6 +28,7 @@
#include "session.h"
#include "../id-ff/login.h"
#include "../saml-2.0/saml2_helper.h"
+#include "../saml-2.0/provider.h"
#include "../xml/saml-2.0/saml2_assertion.h"
#include "../xml/ws/wsa_endpoint_reference.h"
#include "../xml/id-wsf-2.0/disco_abstract.h"
@@ -47,19 +48,87 @@
/**
+ * lasso_server_create_assertion_as_idwsf2_security_token:
+ * @server: a #LassoServer object
+ * @name_id: a #LassoSaml2NameID object
+ * @tolerance: tolerance around the normal duration which is accepted
+ * @duration: life duration for this assertion in seconds
+ * @cipher: whether to cipher the NameID
+ * @audience:(allow-none)(optional): if @cipher is true, the provider for which to encrypt the NameID
+ *
+ * Create a new assertion usable as a security token in an ID-WSF 2.0 EndpointReference. See
+ * lasso_saml2_assertion_set_basic_conditions() for detail about @tolerance and @duration.
+ *
+ * Return value:(transfer full)(allow-none): a newly allocated #LassoSaml2Assertion object, or NULL.
+ */
+LassoSaml2Assertion*
+lasso_server_create_assertion_as_idwsf2_security_token(LassoServer *server,
+ LassoSaml2NameID *name_id,
+ int tolerance,
+ int duration,
+ gboolean cipher,
+ LassoProvider *audience)
+{
+ LassoSaml2Assertion *assertion;
+ int rc;
+
+ if (! LASSO_IS_SERVER(server))
+ return NULL;
+ if (! LASSO_IS_SAML2_NAME_ID(name_id))
+ return NULL;
+ if (cipher && ! LASSO_IS_PROVIDER(audience))
+ return NULL;
+
+ assertion = (LassoSaml2Assertion*)lasso_saml2_assertion_new();
+ assertion->ID = lasso_build_unique_id(32);
+ assertion->Issuer = (LassoSaml2NameID*)lasso_saml2_name_id_new_with_string(server->parent.ProviderID);
+ assertion->Subject = (LassoSaml2Subject*)lasso_saml2_subject_new();
+ if (cipher) {
+ LassoSaml2EncryptedElement *encrypted_id =
+ lasso_provider_saml2_node_encrypt(audience, (LassoNode*)name_id);
+ if (! encrypted_id) {
+ lasso_release_gobject(assertion);
+ goto cleanup;
+ }
+ lasso_assign_gobject(assertion->Subject->EncryptedID, encrypted_id);
+ } else {
+ lasso_assign_new_gobject(assertion->Subject->NameID, name_id);
+ }
+ lasso_saml2_assertion_set_basic_conditions(assertion,
+ tolerance, duration, FALSE);
+ rc = lasso_server_saml2_assertion_setup_signature(server, assertion);
+ if (rc != 0) {
+ lasso_release_gobject(assertion);
+ }
+cleanup:
+ return assertion;
+}
+
+
+
+
+/**
* lasso_login_idwsf2_add_discovery_bootstrap_epr:
* @login: a #LassoLogin object
+ * @url: the Disco service address
+ * @abstract: the Disco service description
+ * @security_mechanisms:(allow-none)(element-type utf8): the list of supported security mechanisms
+ * @tolerance:(default -1): see lasso_saml2_assertion_set_basic_conditions().
+ * @duration:(default 0): see lasso_saml2_assertion_set_basic_conditions().
*
* Add the needed bootstrap attribute to the #LassoSaml2Assertion currently container in the
* #LassoLogin object. This function should be called after lasso_login_build_assertion() by an IdP
* also having the Discovery service role.
*
+ * The default @tolerance and @duration are respectively ten minutes and two days.
+ *
* Return value: 0 if successfull, otherwise #LASSO_PROFILE_ERROR_MISSING_ASSERTION if no assertion is present
* in the #LassoLogin object, #LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if login is not a #LassoLogin
* object.
*/
int
-lasso_login_idwsf2_add_discovery_bootstrap_epr(LassoLogin *login, const char *url, const char *abstract, const char *security_mech_id)
+lasso_login_idwsf2_add_discovery_bootstrap_epr(LassoLogin *login, const char *url,
+ const char *abstract, GList *security_mechanisms, int tolerance, int duration)
{
LassoWsAddrEndpointReference *epr = NULL;
LassoWsAddrMetadata *metadata = NULL;
@@ -71,8 +140,8 @@ lasso_login_idwsf2_add_discovery_bootstrap_epr(LassoLogin *login, const char *ur
LassoSaml2Assertion *assertion_identity_token = NULL;
LassoSaml2Assertion *assertion = NULL;
LassoServer *server = NULL;
+ LassoSaml2NameID *name_id = NULL;
int rc = 0;
- const char *security_mechanisms[] = { security_mech_id, NULL };
lasso_bad_param(LOGIN, login);
lasso_null_param(url);
@@ -97,21 +166,26 @@ lasso_login_idwsf2_add_discovery_bootstrap_epr(LassoLogin *login, const char *ur
url, LASSO_IDWSF2_DISCOVERY_HREF, server->parent.ProviderID, abstract);
/* Security/Identity token */
- assertion_identity_token = LASSO_SAML2_ASSERTION(lasso_saml2_assertion_new());
- assertion_identity_token->ID = lasso_build_unique_id(32);
- assertion_identity_token->Issuer = (LassoSaml2NameID*)lasso_saml2_name_id_new_with_string(server->parent.ProviderID);
- lasso_assign_gobject(assertion_identity_token->Subject,
- assertion->Subject);
- lasso_saml2_assertion_set_basic_conditions(assertion_identity_token,
- 5, 2*LASSO_DURATION_DAY, FALSE);
-
- /* Do we sign the assertion ? */
- if (lasso_security_mech_id_is_saml_authentication(security_mech_id) || lasso_security_mech_id_is_bearer_authentication(security_mech_id)) {
- lasso_check_good_rc(lasso_server_saml2_assertion_setup_signature(login->parent.server,
- assertion_identity_token));
+ if (duration <= 0) {
+ duration = 2 * LASSO_DURATION_DAY;
}
+ if (tolerance < 0) {
+ tolerance = 10*LASSO_DURATION_MINUTE;
+ }
+ /* If the NameID is encrypted try to get to he unencrypted one */
+ if (assertion->Subject->NameID) {
+ name_id = assertion->Subject->NameID;
+ } else if (assertion->Subject->EncryptedID &&
+ LASSO_IS_SAML2_NAME_ID(assertion->Subject->EncryptedID->original_data)) {
+ name_id = (LassoSaml2NameID*)assertion->Subject->EncryptedID->original_data;
+ }
+ goto_cleanup_if_fail_with_rc (name_id, LASSO_PROFILE_ERROR_MISSING_NAME_IDENTIFIER);
+ assertion_identity_token = lasso_server_create_assertion_as_idwsf2_security_token(server,
+ name_id, tolerance, duration, TRUE, &server->parent);
- rc = lasso_wsa_endpoint_reference_add_security_token(epr, (LassoNode*)assertion_identity_token, security_mechanisms);
+ /* Add the assertion to the EPR */
+ rc = lasso_wsa_endpoint_reference_add_security_token(epr,
+ (LassoNode*)assertion_identity_token, security_mechanisms);
goto_cleanup_if_fail(rc == 0);
/* Add the EPR to the assertion as a SAML attribute */
@@ -133,29 +207,22 @@ cleanup:
}
/**
- * lasso_login_idwsf2_get_discovery_bootstrap_epr:
- * @login: a #LassoLogin object
+ * lasso_saml2_assertion_idwsf2_get_discovery_bootstrap_epr:
+ * @assertion: a #LassoSaml2Assertion object
*
- * Extract the Discovery boostrap EPR from the attribute named #LASSO_SAML2_ATTRIBUTE_NAME_EPR.
+ * Extract the Discovery bootstrap EPR from @assertion.
*
- * Return value: a caller owned #LassoWsAddrEndpointReference object, or NULL if none can be found.
+ * Return value:(transfer none): a #LassoWsAddrEndpointReference or NULL if no bootstrap EPR is found.
*/
-LassoWsAddrEndpointReference *
-lasso_login_idwsf2_get_discovery_bootstrap_epr(LassoLogin *login)
+LassoWsAddrEndpointReference*
+lasso_saml2_assertion_idwsf2_get_discovery_bootstrap_epr(LassoSaml2Assertion *assertion)
{
- LassoProfile *profile = NULL;
- LassoSession *session = NULL;
- LassoSaml2Assertion *assertion = NULL;
LassoSaml2AttributeStatement *attribute_statement = NULL;
LassoSaml2Attribute *attribute = NULL;
LassoSaml2AttributeValue *attribute_value = NULL;
GList *i = NULL, *j = NULL, *k = NULL;
LassoWsAddrEndpointReference *rc = NULL;
- g_return_val_if_fail (LASSO_IS_LOGIN (login), NULL);
- profile = &login->parent;
- lasso_extract_node_or_fail (session, profile->session, SESSION, NULL);
- assertion = (LassoSaml2Assertion*)lasso_login_get_assertion(login);
if (! LASSO_IS_SAML2_ASSERTION (assertion)) {
return NULL;
}
@@ -198,4 +265,29 @@ lasso_login_idwsf2_get_discovery_bootstrap_epr(LassoLogin *login)
cleanup:
return rc;
+
+}
+
+/**
+ * lasso_login_idwsf2_get_discovery_bootstrap_epr:
+ * @login: a #LassoLogin object
+ *
+ * Extract the Discovery boostrap EPR from the attribute named #LASSO_SAML2_ATTRIBUTE_NAME_EPR.
+ *
+ * Return value:(transfer none): a caller owned #LassoWsAddrEndpointReference object, or NULL if none can be found.
+ */
+LassoWsAddrEndpointReference *
+lasso_login_idwsf2_get_discovery_bootstrap_epr(LassoLogin *login)
+{
+ LassoProfile *profile = NULL;
+ LassoSaml2Assertion *assertion = NULL;
+ LassoWsAddrEndpointReference *rc = NULL;
+
+ g_return_val_if_fail (LASSO_IS_LOGIN (login), NULL);
+ profile = &login->parent;
+ assertion = (LassoSaml2Assertion*)lasso_login_get_assertion(login);
+ rc = lasso_saml2_assertion_idwsf2_get_discovery_bootstrap_epr(assertion);
+ lasso_release_gobject(assertion);
+
+ return rc;
}
diff --git a/lasso/id-wsf-2.0/saml2_login.h b/lasso/id-wsf-2.0/saml2_login.h
index db4bcd51..681ac707 100644
--- a/lasso/id-wsf-2.0/saml2_login.h
+++ b/lasso/id-wsf-2.0/saml2_login.h
@@ -30,15 +30,24 @@ extern "C" {
#endif /* __cplusplus */
#include "../id-ff/login.h"
+#include "../id-ff/provider.h"
#include "../xml/saml-2.0/saml2_assertion.h"
+#include "../xml/saml-2.0/saml2_name_id.h"
#include "../xml/ws/wsa_endpoint_reference.h"
LASSO_EXPORT int lasso_login_idwsf2_add_discovery_bootstrap_epr(LassoLogin *login, const char *url,
- const char *abstract, const char *security_mech_id);
-
+ const char *abstract, GList *security_mechanisms, int tolerance, int duration);
+
LASSO_EXPORT LassoWsAddrEndpointReference *lasso_login_idwsf2_get_discovery_bootstrap_epr(
LassoLogin *login);
+LASSO_EXPORT LassoWsAddrEndpointReference*
+ lasso_saml2_assertion_idwsf2_get_discovery_bootstrap_epr(LassoSaml2Assertion *assertion);
+
+LASSO_EXPORT LassoSaml2Assertion* lasso_server_create_assertion_as_idwsf2_security_token(
+ LassoServer *server, LassoSaml2NameID *name_id, int tolerance, int duration,
+ gboolean cipher, LassoProvider *audience);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/lasso/id-wsf-2.0/soap_binding.c b/lasso/id-wsf-2.0/soap_binding.c
index e5a7f446..e4724eb7 100644
--- a/lasso/id-wsf-2.0/soap_binding.c
+++ b/lasso/id-wsf-2.0/soap_binding.c
@@ -199,6 +199,8 @@ lasso_soap_envelope_get_saml2_security_token(LassoSoapEnvelope *soap_envelope)
GList *it;
security = lasso_soap_envelope_wssec_get_security_header (soap_envelope);
+ if (! security)
+ return NULL;
lasso_foreach (it, security->any) {
if (LASSO_IS_SAML2_ASSERTION (it->data)) {
return (LassoSaml2Assertion*)g_object_ref(it->data);
diff --git a/tests/idwsf2_tests.c b/tests/idwsf2_tests.c
index 25360801..027c02bb 100644
--- a/tests/idwsf2_tests.c
+++ b/tests/idwsf2_tests.c
@@ -165,6 +165,8 @@ prepare_saml2_authn_request(LassoLogin *splogin, LassoLogin *idplogin)
static void
process_authn_request(LassoLogin *splogin, LassoLogin *idplogin)
{
+ GList node = { .data = LASSO_SECURITY_MECH_BEARER, .next = NULL };
+
check_good_rc(lasso_login_process_authn_request_msg(idplogin, strchr(splogin->parent.msg_url,'?')+1));
lasso_login_must_authenticate(idplogin);
check_false(lasso_login_must_ask_for_consent(idplogin));
@@ -177,7 +179,7 @@ process_authn_request(LassoLogin *splogin, LassoLogin *idplogin)
"FIXME: notOnOrAfter"));
check_good_rc(lasso_login_idwsf2_add_discovery_bootstrap_epr(idplogin,
"http://example.com/disco", "Discovery Service Description",
- LASSO_SECURITY_MECH_BEARER));
+ &node, -1, 0));
check_good_rc(lasso_login_build_artifact_msg(idplogin, LASSO_HTTP_METHOD_ARTIFACT_GET));
}