summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lasso/id-ff/defederation.c19
-rw-r--r--lasso/id-ff/login.c2
-rw-r--r--lasso/id-ff/provider.c68
-rw-r--r--lasso/id-ff/provider.h27
-rw-r--r--lasso/id-ff/providerprivate.h4
-rw-r--r--lasso/id-ff/server.c33
-rw-r--r--lasso/id-ff/serverprivate.h1
-rw-r--r--lasso/saml-2.0/assertion_query.c110
-rw-r--r--lasso/saml-2.0/assertion_query.h1
-rw-r--r--lasso/saml-2.0/ecp.c2
-rw-r--r--lasso/saml-2.0/provider.c74
11 files changed, 247 insertions, 94 deletions
diff --git a/lasso/id-ff/defederation.c b/lasso/id-ff/defederation.c
index 05d7e961..9877deb7 100644
--- a/lasso/id-ff/defederation.c
+++ b/lasso/id-ff/defederation.c
@@ -171,6 +171,7 @@ lasso_defederation_init_notification(LassoDefederation *defederation, gchar *rem
LassoFederation *federation;
LassoSamlNameIdentifier *nameIdentifier;
LassoNode *nameIdentifier_n;
+ gint rc = 0;
g_return_val_if_fail(LASSO_IS_DEFEDERATION(defederation),
LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
@@ -183,10 +184,19 @@ lasso_defederation_init_notification(LassoDefederation *defederation, gchar *rem
if (remote_providerID != NULL) {
lasso_assign_string(profile->remote_providerID, remote_providerID);
} else {
- lasso_assign_new_string(profile->remote_providerID, lasso_server_get_first_providerID(profile->server));
- if (profile->remote_providerID == NULL) {
- return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
+ LassoProvider *my_provider;
+ LassoProviderRole role = LASSO_PROVIDER_ROLE_IDP;
+
+ lasso_extract_node_or_fail(my_provider, profile->server, PROVIDER,
+ LASSO_PROFILE_ERROR_MISSING_SERVER);
+ if (my_provider->role == LASSO_PROVIDER_ROLE_IDP) {
+ role = LASSO_PROVIDER_ROLE_SP;
}
+ lasso_assign_new_string(profile->remote_providerID,
+ lasso_server_get_first_providerID_by_role(profile->server, role));
+ }
+ if (profile->remote_providerID == NULL) {
+ return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
}
remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
@@ -276,7 +286,8 @@ lasso_defederation_init_notification(LassoDefederation *defederation, gchar *rem
/* Save notification method */
profile->http_request_method = http_method;
- return 0;
+cleanup:
+ return rc;
}
/**
diff --git a/lasso/id-ff/login.c b/lasso/id-ff/login.c
index 43f665b1..8940b46b 100644
--- a/lasso/id-ff/login.c
+++ b/lasso/id-ff/login.c
@@ -1381,7 +1381,7 @@ lasso_login_init_authn_request(LassoLogin *login, const gchar *remote_providerID
if (remote_providerID != NULL) {
lasso_assign_string(profile->remote_providerID, remote_providerID);
} else {
- lasso_assign_new_string(profile->remote_providerID, lasso_server_get_first_providerID(profile->server));
+ lasso_assign_new_string(profile->remote_providerID, lasso_server_get_first_providerID_by_role(profile->server, LASSO_PROVIDER_ROLE_IDP));
if (profile->remote_providerID == NULL) {
return critical_error(LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID);
}
diff --git a/lasso/id-ff/provider.c b/lasso/id-ff/provider.c
index a52fe2eb..0dcd9d5e 100644
--- a/lasso/id-ff/provider.c
+++ b/lasso/id-ff/provider.c
@@ -47,22 +47,28 @@
#include "../utils.h"
#include "../debug.h"
-static char *protocol_uris[] = {
+static char *protocol_uris[LASSO_MD_PROTOCOL_TYPE_LAST] = {
"http://projectliberty.org/profiles/fedterm",
"http://projectliberty.org/profiles/nim",
"http://projectliberty.org/profiles/rni",
"http://projectliberty.org/profiles/slo",
NULL /* none for single sign on */
};
-static char *protocol_md_nodename[] = {
+static char *protocol_md_nodename[LASSO_MD_PROTOCOL_TYPE_LAST] = {
"FederationTerminationNotificationProtocolProfile",
"NameIdentifierMappingProtocolProfile",
"RegisterNameIdentifierProtocolProfile",
"SingleLogoutProtocolProfile",
"SingleSignOnProtocolProfile"
};
-static char *protocol_roles[] = { NULL, "sp", "idp"};
-char *protocol_methods[] = {"", "", "", "", "", "-http", "-soap"};
+static char *protocol_roles[LASSO_PROVIDER_ROLE_LAST] = {
+ NULL, "sp", "idp",
+ "authn-authority", "pdp", "attribute-authority"
+};
+char *protocol_methods[LASSO_HTTP_METHOD_LAST] = {
+ "", "", "", "",
+ "", "-http", "-soap"
+};
static gboolean lasso_provider_load_metadata_from_doc(LassoProvider *provider, xmlDoc *doc);
/*****************************************************************************/
@@ -92,7 +98,7 @@ lasso_provider_get_assertion_consumer_service_url(const LassoProvider *provider,
if (sid == NULL)
sid = provider->private_data->default_assertion_consumer;
- descriptor = provider->private_data->SPDescriptor;
+ descriptor = provider->private_data->Descriptors;
if (descriptor == NULL)
return NULL;
@@ -122,12 +128,10 @@ lasso_provider_get_metadata_one(const LassoProvider *provider, const char *name)
GHashTable *descriptor;
g_return_val_if_fail(LASSO_IS_PROVIDER(provider), NULL);
- descriptor = provider->private_data->SPDescriptor; /* default to SP */
- if (provider->role == LASSO_PROVIDER_ROLE_IDP)
- descriptor = provider->private_data->IDPDescriptor;
+
+ descriptor = provider->private_data->Descriptors; /* default to SP */
if (descriptor == NULL)
return NULL;
-
l = g_hash_table_lookup(descriptor, name);
if (l)
return g_strdup(l->data);
@@ -152,10 +156,8 @@ lasso_provider_get_metadata_list(const LassoProvider *provider, const char *name
{
GHashTable *descriptor;
- g_return_val_if_fail(LASSO_IS_PROVIDER(provider), NULL);
- descriptor = provider->private_data->SPDescriptor; /* default to SP */
- if (provider->role == LASSO_PROVIDER_ROLE_IDP)
- descriptor = provider->private_data->IDPDescriptor;
+ g_return_val_if_fail(LASSO_IS_PROVIDER(provider), NULL);
+ descriptor = provider->private_data->Descriptors;
return g_hash_table_lookup(descriptor, name);
}
@@ -459,7 +461,7 @@ get_xmlNode(LassoNode *node, gboolean lasso_dump)
{
xmlNode *xmlnode;
LassoProvider *provider = LASSO_PROVIDER(node);
- char *roles[] = { "None", "SP", "IdP"};
+ char *roles[LASSO_PROVIDER_ROLE_LAST] = { "None", "SP", "IdP", "AuthnAuthority", "PDP", "AttributeAuthority"};
char *encryption_mode[] = { "None", "NameId", "Assertion", "Both" };
xmlnode = parent_class->get_xmlNode(node, lasso_dump);
@@ -482,7 +484,9 @@ static int
init_from_xml(LassoNode *node, xmlNode *xmlnode)
{
LassoProvider *provider = LASSO_PROVIDER(node);
+ char *roles[LASSO_PROVIDER_ROLE_LAST] = { "None", "SP", "IdP", "AuthnAuthority", "PDP", "AttributeAuthority"};
xmlChar *s;
+ int i;
parent_class->init_from_xml(node, xmlnode);
@@ -492,10 +496,14 @@ init_from_xml(LassoNode *node, xmlNode *xmlnode)
/* Load provider role */
s = xmlGetProp(xmlnode, (xmlChar*)"ProviderRole");
- if (s != NULL && strcmp((char*)s, "SP") == 0) {
- provider->role = LASSO_PROVIDER_ROLE_SP;
- } else if (s != NULL && strcmp((char*)s, "IdP") == 0) {
- provider->role = LASSO_PROVIDER_ROLE_IDP;
+ provider->role = LASSO_PROVIDER_ROLE_NONE;
+ i = LASSO_PROVIDER_ROLE_NONE;
+ while (i < LASSO_PROVIDER_ROLE_LAST) {
+ if (strcmp((char*)s, roles[i]) == 0) {
+ provider->role = i;
+ break;
+ }
+ i++;
}
if (s != NULL) {
xmlFree(s);
@@ -553,19 +561,12 @@ dispose(GObject *object)
}
provider->private_data->dispose_has_run = TRUE;
- if (provider->private_data->IDPDescriptor) {
- g_hash_table_foreach(provider->private_data->IDPDescriptor,
+ if (provider->private_data->Descriptors) {
+ g_hash_table_foreach(provider->private_data->Descriptors,
(GHFunc)free_list_strings, NULL);
- g_hash_table_destroy(provider->private_data->IDPDescriptor);
+ g_hash_table_destroy(provider->private_data->Descriptors);
}
- provider->private_data->IDPDescriptor = NULL;
-
- if (provider->private_data->SPDescriptor) {
- g_hash_table_foreach(provider->private_data->SPDescriptor,
- (GHFunc)free_list_strings, NULL);
- g_hash_table_destroy(provider->private_data->SPDescriptor);
- }
- provider->private_data->SPDescriptor = NULL;
+ provider->private_data->Descriptors = NULL;
if (provider->private_data->organization) {
xmlFreeNode(provider->private_data->organization);
@@ -649,10 +650,9 @@ instance_init(LassoProvider *provider)
provider->private_data->encryption_sym_key_type = LASSO_ENCRYPTION_SYM_KEY_TYPE_AES_128;
/* no value_destroy_func since it shouldn't destroy the GList on insert */
- provider->private_data->IDPDescriptor = g_hash_table_new_full(
- g_str_hash, g_str_equal, g_free, NULL);
- provider->private_data->SPDescriptor = g_hash_table_new_full(
+ provider->private_data->Descriptors = g_hash_table_new_full(
g_str_hash, g_str_equal, g_free, NULL);
+ provider->private_data->attributes = NULL;
}
static void
@@ -834,7 +834,7 @@ lasso_provider_load_metadata_from_doc(LassoProvider *provider, xmlDoc *doc)
xpathObj = xmlXPathEvalExpression((xmlChar*)xpath_idp, xpathCtx);
if (xpathObj && xpathObj->nodesetval && xpathObj->nodesetval->nodeNr == 1) {
load_descriptor(xpathObj->nodesetval->nodeTab[0],
- provider->private_data->IDPDescriptor, provider);
+ provider->private_data->Descriptors, provider);
if (provider->private_data->conformance < LASSO_PROTOCOL_LIBERTY_1_2) {
/* lookup ProviderID */
node = xpathObj->nodesetval->nodeTab[0]->children;
@@ -854,7 +854,7 @@ lasso_provider_load_metadata_from_doc(LassoProvider *provider, xmlDoc *doc)
xpathObj = xmlXPathEvalExpression((xmlChar*)xpath_sp, xpathCtx);
if (xpathObj && xpathObj->nodesetval && xpathObj->nodesetval->nodeNr == 1) {
load_descriptor(xpathObj->nodesetval->nodeTab[0],
- provider->private_data->SPDescriptor, provider);
+ provider->private_data->Descriptors, provider);
if (provider->private_data->conformance < LASSO_PROTOCOL_LIBERTY_1_2) {
/* lookup ProviderID */
node = xpathObj->nodesetval->nodeTab[0]->children;
diff --git a/lasso/id-ff/provider.h b/lasso/id-ff/provider.h
index 7cc8c9ed..be30426f 100644
--- a/lasso/id-ff/provider.h
+++ b/lasso/id-ff/provider.h
@@ -98,7 +98,11 @@ typedef enum {
LASSO_MD_PROTOCOL_TYPE_SINGLE_SIGN_ON,
LASSO_MD_PROTOCOL_TYPE_ARTIFACT_RESOLUTION,
LASSO_MD_PROTOCOL_TYPE_MANAGE_NAME_ID,
- LASSO_MD_PROTOCOL_TYPE_ASSERTION_ID_REQUEST
+ LASSO_MD_PROTOCOL_TYPE_ASSERTION_ID_REQUEST,
+ LASSO_MD_PROTOCOL_TYPE_AUTHN_QUERY,
+ LASSO_MD_PROTOCOL_TYPE_AUTHZ,
+ LASSO_MD_PROTOCOL_TYPE_ATTRIBUTE,
+ LASSO_MD_PROTOCOL_TYPE_LAST
} LassoMdProtocolType;
@@ -108,14 +112,27 @@ typedef enum {
* @LASSO_PROVIDER_ROLE_SP: service provider.
* @LASSO_PROVIDER_ROLE_IDP: identity provider.
* @LASSO_PROVIDER_ROLE_BOTH: service&identity provider.
+ * @LASSO_PROVIDER_ROLE_AUTHN_AUTHORITY: an authentification authority, i.e. an endpoint able to
+ * return previously returned assertion,
+ * @LASSO_PROVIDER_ROLE_AUTHZ_AUTHORITY: an authorization authority, i.e. an endpoint able to return
+ * assertion providing authorization about a principal acessing a resource,
+ * @LASSO_PROVIDER_ROLE_ATTRIBUTE_AUTHORITY: an attribute authority, i.e. an endpoint able to return
+ * attributes aboute a principal,
+ * @LASSO_PROVIDER_ROLE_LAST: all value in the enumeration are garanteed to be < to
+ * @LASSO_PROVIDER_ROLE_LAST.
*
- * Provider Role.
+ * #LassoProviderRole is an enumeration allowing to precise the roles handled by a provider.
**/
typedef enum {
+ LASSO_PROVIDER_ROLE_ANY = -1,
LASSO_PROVIDER_ROLE_NONE = 0,
- LASSO_PROVIDER_ROLE_SP,
- LASSO_PROVIDER_ROLE_IDP,
- LASSO_PROVIDER_ROLE_BOTH
+ LASSO_PROVIDER_ROLE_IDP = 1,
+ LASSO_PROVIDER_ROLE_SP = 2,
+ LASSO_PROVIDER_ROLE_BOTH = 3,
+ LASSO_PROVIDER_ROLE_AUTHN_AUTHORITY = 4,
+ LASSO_PROVIDER_ROLE_AUTHZ_AUTHORITY = 8,
+ LASSO_PROVIDER_ROLE_ATTRIBUTE_AUTHORITY = 16,
+ LASSO_PROVIDER_ROLE_LAST = 17
} LassoProviderRole;
diff --git a/lasso/id-ff/providerprivate.h b/lasso/id-ff/providerprivate.h
index 1d4ae3d3..2382cf69 100644
--- a/lasso/id-ff/providerprivate.h
+++ b/lasso/id-ff/providerprivate.h
@@ -47,9 +47,9 @@ struct _LassoProviderPrivate
gboolean dispose_has_run;
LassoProtocolConformance conformance;
- GHashTable *SPDescriptor;
+ GHashTable *Descriptors;
+ GList *attributes; /* of LassoSaml2Attribute */
char *default_assertion_consumer;
- GHashTable *IDPDescriptor;
xmlNode *organization;
char *affiliation_owner_id;
diff --git a/lasso/id-ff/server.c b/lasso/id-ff/server.c
index 0694b2ea..2b6b5701 100644
--- a/lasso/id-ff/server.c
+++ b/lasso/id-ff/server.c
@@ -326,6 +326,39 @@ get_first_providerID(gchar *key, G_GNUC_UNUSED gpointer value, char **providerID
return TRUE;
}
+static gboolean
+get_first_providerID_by_role(G_GNUC_UNUSED gchar *key, gpointer value, LassoProviderRole role) {
+ LassoProvider *provider = (LassoProvider*)value;
+ if (provider->role == role || role == LASSO_PROVIDER_ROLE_ANY) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * lasso_server_get_first_providerID_by_role
+ * @server: a #LassoServer
+ * @role: the #LassoProviderRole of the researched provider
+ *
+ * Looks up and returns the provider ID of known provider with the given role.
+ *
+ * Return value: the provider ID, NULL if there are no providers. This string
+ * must be freed by the caller.
+ */
+gchar *
+lasso_server_get_first_providerID_by_role(const LassoServer *server, LassoProviderRole role)
+{
+ LassoProvider *a_provider;
+ a_provider = LASSO_PROVIDER(g_hash_table_find(server->providers,
+ (GHRFunc) get_first_providerID_by_role,
+ (gpointer)role));
+ if (a_provider) {
+ return g_strdup(a_provider->ProviderID);
+ } else {
+ return NULL;
+ }
+}
+
/**
* lasso_server_get_first_providerID:
* @server: a #LassoServer
diff --git a/lasso/id-ff/serverprivate.h b/lasso/id-ff/serverprivate.h
index b22247ac..8375fc2e 100644
--- a/lasso/id-ff/serverprivate.h
+++ b/lasso/id-ff/serverprivate.h
@@ -37,6 +37,7 @@ struct _LassoServerPrivate
};
gchar* lasso_server_get_first_providerID(LassoServer *server);
+gchar* lasso_server_get_first_providerID_by_role(const LassoServer *server, LassoProviderRole role);
gchar* lasso_server_get_providerID_from_hash(LassoServer *server, gchar *b64_hash);
xmlSecKey* lasso_server_get_private_key(LassoServer *server);
xmlSecKey* lasso_server_get_encryption_private_key(LassoServer *server);
diff --git a/lasso/saml-2.0/assertion_query.c b/lasso/saml-2.0/assertion_query.c
index 9e9c7254..de7ae6bc 100644
--- a/lasso/saml-2.0/assertion_query.c
+++ b/lasso/saml-2.0/assertion_query.c
@@ -22,6 +22,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "../id-ff/session.h"
#include "../xml/private.h"
#include "assertion_query.h"
#include "providerprivate.h"
@@ -31,6 +32,7 @@
#include "../id-ff/identityprivate.h"
#include "../id-ff/serverprivate.h"
#include "../xml/xml_enc.h"
+#include "../xml/saml-2.0/saml2_assertion.h"
#include "../xml/saml-2.0/samlp2_assertion_id_request.h"
#include "../xml/saml-2.0/samlp2_authn_query.h"
#include "../xml/saml-2.0/samlp2_attribute_query.h"
@@ -53,12 +55,15 @@ struct _LassoAssertionQueryPrivate
/**
* lasso_assertion_query_init_request:
* @assertion_query: a #LassoAssertionQuery
- * @remote_provider_id: the providerID of the remote provider.
+ * @remote_provider_id: (allow-none): the providerID of the remote provider.
* @http_method: if set, then it get the protocol profile in metadata
* corresponding of this HTTP request method.
* @query_request_type: the type of request.
*
* Initializes a new Assertion Query Request.
+ * For the AssertionID request type, the remote_provider_id is mandatory, for all other kind of
+ * request it is optional if we can find a provider supporting the associated role, i.e.
+ * IDP; authentication, attribute and authorization authority.
*
* Return value: 0 on success; or a negative value otherwise.
**/
@@ -72,10 +77,13 @@ lasso_assertion_query_init_request(LassoAssertionQuery *assertion_query,
LassoProvider *remote_provider;
LassoFederation *federation;
LassoSamlp2RequestAbstract *request;
+ gint ret = 0;
+ g_return_val_if_fail(http_method == LASSO_HTTP_METHOD_ANY ||
+ http_method == LASSO_HTTP_METHOD_SOAP,
+ LASSO_PARAM_ERROR_INVALID_VALUE);
g_return_val_if_fail(LASSO_IS_ASSERTION_QUERY(assertion_query),
LASSO_PARAM_ERROR_INVALID_VALUE);
- g_return_val_if_fail(remote_provider_id != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
profile = LASSO_PROFILE(assertion_query);
@@ -85,15 +93,37 @@ lasso_assertion_query_init_request(LassoAssertionQuery *assertion_query,
}
/* set the remote provider id */
- profile->remote_providerID = g_strdup(remote_provider_id);
+ profile->remote_providerID = NULL;
+ if (remote_provider_id) {
+ profile->remote_providerID = g_strdup(remote_provider_id);
+ } else {
+ LassoProviderRole role = LASSO_PROVIDER_ROLE_NONE;
+ switch (query_request_type) {
+ case LASSO_ASSERTION_QUERY_REQUEST_TYPE_AUTHN:
+ role = LASSO_PROVIDER_ROLE_AUTHN_AUTHORITY;
+ break;
+ case LASSO_ASSERTION_QUERY_REQUEST_TYPE_ATTRIBUTE:
+ role = LASSO_PROVIDER_ROLE_ATTRIBUTE_AUTHORITY;
+ break;
+ case LASSO_ASSERTION_QUERY_REQUEST_TYPE_AUTHZ_DECISION:
+ role = LASSO_PROVIDER_ROLE_PDP;
+ break;
+ /* other request types should not happen or should not go there */
+ default:
+ return critical_error(LASSO_PARAM_ERROR_INVALID_VALUE);
+ }
+ profile->remote_providerID =
+ lasso_server_get_first_providerID_by_role(profile->server,
+ role);
+ }
+ g_return_val_if_fail(profile->remote_providerID != NULL,
+ LASSO_PARAM_ERROR_INVALID_VALUE);
remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
if (LASSO_IS_PROVIDER(remote_provider) == FALSE) {
return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
}
- /* XXX: check HTTP method is supported */
-
assertion_query->private_data->query_request_type = query_request_type;
switch (query_request_type) {
case LASSO_ASSERTION_QUERY_REQUEST_TYPE_ASSERTION_ID:
@@ -113,23 +143,38 @@ lasso_assertion_query_init_request(LassoAssertionQuery *assertion_query,
}
if (query_request_type != LASSO_ASSERTION_QUERY_REQUEST_TYPE_ASSERTION_ID) {
+ LassoSaml2NameID *nameID = NULL;
/* fill <Subject> */
LassoSamlp2SubjectQueryAbstract *subject_query;
/* Get federation */
- federation = g_hash_table_lookup(profile->identity->federations,
- profile->remote_providerID);
- if (LASSO_IS_FEDERATION(federation) == FALSE) {
- return critical_error(LASSO_PROFILE_ERROR_FEDERATION_NOT_FOUND);
- } /* XXX: should support looking up transient id */
-
+ if (profile->session) {
+ GList *assertions;
+ LassoSaml2Assertion *assertion = NULL;
+
+ assertions = lasso_session_get_assertions(profile->session,
+ (gchar*)profile->remote_providerID);
+ /* multiple assertions, take the first */
+ if (assertions && LASSO_IS_SAML2_ASSERTION(assertions->data)) {
+ assertion = (LassoSaml2Assertion*)assertions->data;
+ }
+ if (assertion && assertion->Subject) {
+ nameID = assertion->Subject->NameID;
+ }
+ }
+ if (nameID == NULL) {
+ federation = g_hash_table_lookup(profile->identity->federations,
+ profile->remote_providerID);
+ if (LASSO_IS_FEDERATION(federation) == FALSE) {
+ return critical_error(LASSO_PROFILE_ERROR_FEDERATION_NOT_FOUND);
+ } /* XXX: should support looking up transient id */
+ nameID = LASSO_SAML2_NAME_ID(lasso_profile_get_nameIdentifier(profile));
+ }
subject_query = LASSO_SAMLP2_SUBJECT_QUERY_ABSTRACT(profile->request);
subject_query->Subject = LASSO_SAML2_SUBJECT(lasso_saml2_subject_new());
- subject_query->Subject->NameID =LASSO_SAML2_NAME_ID(
- lasso_profile_get_nameIdentifier(profile));
-
+ subject_query->Subject->NameID = g_object_ref(nameID);
}
-
+ /* Setup usual request attributes */
request = LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request);
request->ID = lasso_build_unique_id(32);
request->Version = g_strdup("2.0");
@@ -137,9 +182,18 @@ lasso_assertion_query_init_request(LassoAssertionQuery *assertion_query,
LASSO_PROVIDER(profile->server)->ProviderID));
request->IssueInstant = lasso_get_current_time();
+ request->sign_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
+ if (profile->server->certificate) {
+ request->sign_type = LASSO_SIGNATURE_TYPE_WITHX509;
+ } else {
+ request->sign_type = LASSO_SIGNATURE_TYPE_SIMPLE;
+ }
+ request->private_key_file = g_strdup(profile->server->private_key);
+ request->certificate_file = g_strdup(profile->server->certificate);
+
profile->http_request_method = http_method;
- return 0;
+ return ret;
}
@@ -167,17 +221,23 @@ lasso_assertion_query_build_request_msg(LassoAssertionQuery *assertion_query)
if (LASSO_IS_PROVIDER(remote_provider) == FALSE) {
return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
}
-
if (profile->http_request_method == LASSO_HTTP_METHOD_SOAP) {
- if (assertion_query->private_data->query_request_type == \
- LASSO_ASSERTION_QUERY_REQUEST_TYPE_ASSERTION_ID) {
- profile->msg_url = lasso_provider_get_metadata_one(remote_provider,
- "AssertionIDRequestService SOAP");
- } else {
- profile->msg_url = lasso_provider_get_metadata_one(remote_provider,
- "AttributeService SOAP");
+ LassoAssertionQueryRequestType type;
+ /* XXX: support only SOAP */
+ static const gchar *servicepoints[LASSO_ASSERTION_QUERY_REQUEST_TYPE_LAST] = {
+ "AssertionIDRequestService SOAP",
+ "AuthnQueryService SOAP",
+ "AuthzService SOAP",
+ "AttributeService SOAP"
+ };
+ type = assertion_query->private_data->query_request_type;
+ if (type <= LASSO_ASSERTION_QUERY_REQUEST_TYPE_ASSERTION_ID ||
+ type >= LASSO_ASSERTION_QUERY_REQUEST_TYPE_AUTHZ_DECISION) {
+ return LASSO_PARAM_ERROR_INVALID_VALUE;
}
- /* XXX set private key so message is signed */
+ profile->msg_url = lasso_provider_get_metadata_one(remote_provider,
+ servicepoints[type]);
+ lasso_saml20_profile_setup_request_signing(profile);
profile->msg_body = lasso_node_export_to_soap(profile->request);
return 0;
}
diff --git a/lasso/saml-2.0/assertion_query.h b/lasso/saml-2.0/assertion_query.h
index 777b3a42..8d8c6644 100644
--- a/lasso/saml-2.0/assertion_query.h
+++ b/lasso/saml-2.0/assertion_query.h
@@ -70,6 +70,7 @@ typedef enum {
LASSO_ASSERTION_QUERY_REQUEST_TYPE_AUTHN,
LASSO_ASSERTION_QUERY_REQUEST_TYPE_ATTRIBUTE,
LASSO_ASSERTION_QUERY_REQUEST_TYPE_AUTHZ_DECISION,
+ LASSO_ASSERTION_QUERY_REQUEST_TYPE_LAST
} LassoAssertionQueryRequestType;
struct _LassoAssertionQuery {
diff --git a/lasso/saml-2.0/ecp.c b/lasso/saml-2.0/ecp.c
index 5d08d7c8..b2667d24 100644
--- a/lasso/saml-2.0/ecp.c
+++ b/lasso/saml-2.0/ecp.c
@@ -179,7 +179,7 @@ lasso_ecp_process_authn_request_msg(LassoEcp *ecp, const char *authn_request_msg
xmlOutputBufferClose(buf);
lasso_release_doc(doc);
- profile->remote_providerID = lasso_server_get_first_providerID(profile->server);
+ profile->remote_providerID = lasso_server_get_first_providerID_by_role(profile->server, LASSO_PROVIDER_ROLE_IDP);
if (profile->remote_providerID == NULL) {
return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
}
diff --git a/lasso/saml-2.0/provider.c b/lasso/saml-2.0/provider.c
index 704b3880..5e7f1082 100644
--- a/lasso/saml-2.0/provider.c
+++ b/lasso/saml-2.0/provider.c
@@ -29,17 +29,23 @@
#include "../id-ff/providerprivate.h"
#include "../utils.h"
#include "./provider.h"
+#include "../xml/saml-2.0/saml2_attribute.h"
-const char *profile_names[] = {
+const char *profile_names[LASSO_MD_PROTOCOL_TYPE_LAST] = {
"", /* No fedterm in SAML 2.0 */
- "NameIDMappingService",
+ "NameIDMappingService", /*IDPSSODescriptor*/
"", /* No rni in SAML 2.0 */
- "SingleLogoutService",
- "SingleSignOnService",
- "ArtifactResolutionService",
- "ManageNameIDService",
- "AssertionIDRequestService",
- NULL
+ "SingleLogoutService", /*SSODescriptor*/
+ "SingleSignOnService", /*IDPSSODescriptor*/
+ "ArtifactResolutionService", /*SSODescriptor*/
+ "ManageNameIDService", /*SSODescriptor*/
+ "AssertionIDRequestService", /* IDPSSODescriptor,
+ AuthnAuhtorityDescriptor,
+ PDPDescriptor,
+ AttributeAuthorityDescriptor */
+ "AuthnQueryService", /*AuthnAuthorityDescriptor*/
+ "AuthzService", /*PDPDescriptor*/
+ "AttributeService" /*AttributeAuthorityDescriptor*/
};
static void add_assertion_consumer_url_to_list(gchar *key, G_GNUC_UNUSED gpointer value, GList **list);
@@ -77,6 +83,15 @@ load_descriptor(xmlNode *xmlnode, GHashTable *descriptor, LassoProvider *provide
t = t->next;
continue;
}
+ if (strcmp((char*)t->name, "Attribute") == 0) {
+ LassoSaml2Attribute *attribute;
+ attribute = LASSO_SAML2_ATTRIBUTE(lasso_node_new_from_xmlNode(t));
+ if (attribute) {
+ provider->private_data->attributes =
+ g_list_append(provider->private_data->attributes, attribute);
+ }
+ continue;
+ }
binding = (char*)xmlGetProp(t, (xmlChar*)"Binding");
if (binding) {
/* Endpoint type */
@@ -114,7 +129,8 @@ load_descriptor(xmlNode *xmlnode, GHashTable *descriptor, LassoProvider *provide
name = g_strdup_printf("%s %s %s", t->name, binding_s, index);
xmlFree(index);
xmlFree(is_default);
- } else {
+ }
+ else {
name = g_strdup_printf("%s %s", t->name, binding_s);
}
xmlFree(binding);
@@ -192,18 +208,39 @@ lasso_saml20_provider_load_metadata(LassoProvider *provider, xmlNode *root_node)
if (strcmp((char*)descriptor_node->name, "IDPSSODescriptor") == 0) {
load_descriptor(descriptor_node,
- provider->private_data->IDPDescriptor, provider);
+ provider->private_data->Descriptors, provider);
provider->role = LASSO_PROVIDER_ROLE_IDP;
continue;
}
if (strcmp((char*)descriptor_node->name, "SPSSODescriptor") == 0) {
load_descriptor(descriptor_node,
- provider->private_data->SPDescriptor, provider);
+ provider->private_data->Descriptors, provider);
provider->role = LASSO_PROVIDER_ROLE_SP;
continue;
}
+ if (strcmp((char*)descriptor_node->name, "AttributeAuthorityDescriptor") == 0) {
+ load_descriptor(descriptor_node,
+ provider->private_data->Descriptors, provider);
+ provider->role = LASSO_PROVIDER_ROLE_ATTRIBUTE_AUTHORITY;
+ continue;
+ }
+
+ if (strcmp((char*)descriptor_node->name, "PDPDescriptor") == 0) {
+ load_descriptor(descriptor_node,
+ provider->private_data->Descriptors, provider);
+ provider->role = LASSO_PROVIDER_ROLE_PDP;
+ continue;
+ }
+
+ if (strcmp((char*)descriptor_node->name, "AuthnAuthorityDescriptor") == 0) {
+ load_descriptor(descriptor_node,
+ provider->private_data->Descriptors, provider);
+ provider->role = LASSO_PROVIDER_ROLE_AUTHN_AUTHORITY;
+ continue;
+ }
+
if (strcmp((char*)descriptor_node->name, "Organization") == 0) {
provider->private_data->organization = xmlCopyNode(
descriptor_node, 1);
@@ -228,12 +265,6 @@ lasso_saml20_provider_get_first_http_method(LassoProvider *provider,
LassoHttpMethod method_bindings[] = {
LASSO_HTTP_METHOD_SOAP, LASSO_HTTP_METHOD_REDIRECT, LASSO_HTTP_METHOD_POST
};
-
- if (remote_provider->role == LASSO_PROVIDER_ROLE_SP)
- provider->role = LASSO_PROVIDER_ROLE_IDP;
- if (remote_provider->role == LASSO_PROVIDER_ROLE_IDP)
- provider->role = LASSO_PROVIDER_ROLE_SP;
-
for (i=0; possible_bindings[i] && method == LASSO_HTTP_METHOD_NONE; i++) {
char *s;
const GList *l1, *l2;
@@ -320,7 +351,7 @@ lasso_saml20_provider_get_assertion_consumer_service_url(const LassoProvider *pr
sid = g_strdup_printf("%d", service_id);
}
- descriptor = provider->private_data->SPDescriptor;
+ descriptor = provider->private_data->Descriptors;
if (descriptor == NULL)
return NULL;
@@ -357,7 +388,7 @@ lasso_saml20_provider_get_assertion_consumer_service_url_by_binding(const LassoP
char *binding_s = NULL;
int lname;
- descriptor = provider->private_data->SPDescriptor;
+ descriptor = provider->private_data->Descriptors;
if (descriptor == NULL)
return NULL;
@@ -420,7 +451,7 @@ lasso_saml20_provider_get_assertion_consumer_service_binding(const LassoProvider
sid = g_strdup_printf("%d", service_id);
}
- descriptor = provider->private_data->SPDescriptor;
+ descriptor = provider->private_data->Descriptors;
if (descriptor == NULL)
return NULL;
@@ -443,9 +474,8 @@ lasso_saml20_provider_accept_http_method(LassoProvider *provider, const LassoPro
LassoMdProtocolType protocol_type, LassoHttpMethod http_method,
gboolean initiate_profile)
{
- LassoProviderRole initiating_role;
char *protocol_profile;
- char *http_methods[] = {
+ const static char *http_methods[] = {
NULL,
NULL,
NULL,