diff options
| author | Benjamin Dauvergne <bdauvergne@entrouvert.com> | 2010-03-27 16:51:43 +0000 |
|---|---|---|
| committer | Benjamin Dauvergne <bdauvergne@entrouvert.com> | 2010-03-27 16:51:43 +0000 |
| commit | f5442dc84bf28314339ed3e511921980bd3545aa (patch) | |
| tree | 5d23e2a70a1d7cc99cef4cb941d1a68167e36a0f | |
| parent | 3b1b382f8cd3a5ffab9c6b0d5a80172af79ee1b9 (diff) | |
| download | lasso-f5442dc84bf28314339ed3e511921980bd3545aa.tar.gz lasso-f5442dc84bf28314339ed3e511921980bd3545aa.tar.xz lasso-f5442dc84bf28314339ed3e511921980bd3545aa.zip | |
SAML 2.0: add support for attribute, authentication and authorization authorities metadata
* server.c,serverprivate.h: add new private method
lasso_server_get_firs_providerID_by_role(server, role)w
* defederation.c: use new private method
lasso_server_get_first_providerID_by_role for find providerID
when the argument remote_providerID is null in
lasso_defederation_init_notification.
* lasso/id-ff/login.c (lasso_login_init_authn_request): use new private
method lasso_server_get_first_providerID_by_role.
* provider.h: add thre new provider role (authn,pdp,attribute) and
four new services (authn,assertionid,attribute,authz) and also
a ROLE_ANY value (-1) for catchall purpose and a ROLE_LAST for
array sizing.
* provider.h: add a LAST member to LassoMdProtocolType enum.
* providerprivate.h,provider.c:
- removes separate hashtable for descriptors depending on provider role,
use only one table named Descriptors.
- use the LAST members of enumerations to dimention static string arrays.
* provider.h: add a LAST member to the e
| -rw-r--r-- | lasso/id-ff/defederation.c | 19 | ||||
| -rw-r--r-- | lasso/id-ff/login.c | 2 | ||||
| -rw-r--r-- | lasso/id-ff/provider.c | 68 | ||||
| -rw-r--r-- | lasso/id-ff/provider.h | 27 | ||||
| -rw-r--r-- | lasso/id-ff/providerprivate.h | 4 | ||||
| -rw-r--r-- | lasso/id-ff/server.c | 33 | ||||
| -rw-r--r-- | lasso/id-ff/serverprivate.h | 1 | ||||
| -rw-r--r-- | lasso/saml-2.0/assertion_query.c | 110 | ||||
| -rw-r--r-- | lasso/saml-2.0/assertion_query.h | 1 | ||||
| -rw-r--r-- | lasso/saml-2.0/ecp.c | 2 | ||||
| -rw-r--r-- | lasso/saml-2.0/provider.c | 74 |
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, |
