diff options
| author | Frederic Peters <fpeters@entrouvert.com> | 2004-12-24 10:04:37 +0000 |
|---|---|---|
| committer | Frederic Peters <fpeters@entrouvert.com> | 2004-12-24 10:04:37 +0000 |
| commit | a6de92e3126595f9217b65184c1029cdf6bbd3f5 (patch) | |
| tree | f175833c0c2bd5068eb052475f5cdcadf6bee913 | |
| parent | 94cd82e6aeab19a0a799dbbfb9fdb1d4a797e576 (diff) | |
| download | lasso-a6de92e3126595f9217b65184c1029cdf6bbd3f5.tar.gz lasso-a6de92e3126595f9217b65184c1029cdf6bbd3f5.tar.xz lasso-a6de92e3126595f9217b65184c1029cdf6bbd3f5.zip | |
Do not store metadata in provider dumps; only store the filename. Handle
AssertionConsumerServiceID in <lib:AuthnRequest>; this allows to have more than
one AssertionConsumerServiceURL in a single service provider.
| -rw-r--r-- | docs/reference/lasso-sections.txt | 1 | ||||
| -rw-r--r-- | docs/reference/tmpl/provider.sgml | 11 | ||||
| -rw-r--r-- | lasso/id-ff/login.c | 31 | ||||
| -rw-r--r-- | lasso/id-ff/provider.c | 108 | ||||
| -rw-r--r-- | lasso/id-ff/provider.h | 3 |
5 files changed, 105 insertions, 49 deletions
diff --git a/docs/reference/lasso-sections.txt b/docs/reference/lasso-sections.txt index 54971cf8..4caee45f 100644 --- a/docs/reference/lasso-sections.txt +++ b/docs/reference/lasso-sections.txt @@ -10,6 +10,7 @@ lassoMdProtocolType lasso_provider_new lasso_provider_new_from_dump lasso_provider_accept_http_method +lasso_provider_get_assertion_consumer_service_url lasso_provider_get_base64_succint_id lasso_provider_get_first_http_method lasso_provider_get_metadata_list diff --git a/docs/reference/tmpl/provider.sgml b/docs/reference/tmpl/provider.sgml index ec78bfad..ce89373f 100644 --- a/docs/reference/tmpl/provider.sgml +++ b/docs/reference/tmpl/provider.sgml @@ -21,6 +21,7 @@ It holds all the data about a provider. @ProviderID: @role: +@metadata_filename: @public_key: @ca_cert_chain: @@ -95,6 +96,16 @@ It holds all the data about a provider. @Returns: +<!-- ##### FUNCTION lasso_provider_get_assertion_consumer_service_url ##### --> +<para> + +</para> + +@provider: +@service_id: +@Returns: + + <!-- ##### FUNCTION lasso_provider_get_base64_succint_id ##### --> <para> diff --git a/lasso/id-ff/login.c b/lasso/id-ff/login.c index 3552bdde..c68aacfc 100644 --- a/lasso/id-ff/login.c +++ b/lasso/id-ff/login.c @@ -448,6 +448,7 @@ gint lasso_login_build_artifact_msg(LassoLogin *login, lassoHttpMethod http_method) { LassoProvider *remote_provider; + LassoProfile *profile; gchar *url; xmlSecByte samlArt[42], *b64_samlArt, *relayState; xmlChar *identityProviderSuccinctID; @@ -459,23 +460,26 @@ lasso_login_build_artifact_msg(LassoLogin *login, lassoHttpMethod http_method) return critical_error(LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD); } + profile = LASSO_PROFILE(login); + /* ProtocolProfile must be BrwsArt */ if (login->protocolProfile != LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART) { return critical_error(LASSO_PROFILE_ERROR_INVALID_PROTOCOLPROFILE); } - if (LASSO_PROFILE(login)->remote_providerID == NULL) + if (profile->remote_providerID == NULL) return critical_error(LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID); /* build artifact infos */ - remote_provider = g_hash_table_lookup(LASSO_PROFILE(login)->server->providers, - LASSO_PROFILE(login)->remote_providerID); - url = lasso_provider_get_metadata_one(remote_provider, "AssertionConsumerServiceURL"); + remote_provider = g_hash_table_lookup(profile->server->providers, + profile->remote_providerID); + url = lasso_provider_get_assertion_consumer_service_url(remote_provider, + LASSO_LIB_AUTHN_REQUEST(profile->request)->AssertionConsumerServiceID); if (url == NULL) { return critical_error(LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL); } identityProviderSuccinctID = lasso_sha1( - LASSO_PROVIDER(LASSO_PROFILE(login)->server)->ProviderID); + LASSO_PROVIDER(profile->server)->ProviderID); /* Artifact Format is described in "Binding Profiles", 3.2.2.2. */ memcpy(samlArt, "\000\003", 2); /* type code */ @@ -484,25 +488,24 @@ lasso_login_build_artifact_msg(LassoLogin *login, lassoHttpMethod http_method) xmlFree(identityProviderSuccinctID); b64_samlArt = xmlSecBase64Encode(samlArt, 42, 0); - relayState = xmlURIEscapeStr( - LASSO_LIB_AUTHN_REQUEST(LASSO_PROFILE(login)->request)->RelayState, NULL); + relayState = xmlURIEscapeStr(LASSO_LIB_AUTHN_REQUEST(profile->request)->RelayState, NULL); if (http_method == LASSO_HTTP_METHOD_REDIRECT) { if (relayState == NULL) { - LASSO_PROFILE(login)->msg_url = g_strdup_printf( + profile->msg_url = g_strdup_printf( "%s?SAMLart=%s", url, b64_samlArt); } else { - LASSO_PROFILE(login)->msg_url = g_strdup_printf( + profile->msg_url = g_strdup_printf( "%s?SAMLart=%s&RelayState=%s", url, b64_samlArt, relayState); } } if (http_method == LASSO_HTTP_METHOD_POST) { - LASSO_PROFILE(login)->msg_url = g_strdup(url); - LASSO_PROFILE(login)->msg_body = g_strdup(b64_samlArt); + profile->msg_url = g_strdup(url); + profile->msg_body = g_strdup(b64_samlArt); if (relayState != NULL) { - LASSO_PROFILE(login)->msg_relayState = g_strdup(relayState); + profile->msg_relayState = g_strdup(relayState); } } login->assertionArtifact = g_strdup(b64_samlArt); @@ -645,8 +648,8 @@ lasso_login_build_authn_response_msg(LassoLogin *login) remote_provider = g_hash_table_lookup(LASSO_PROFILE(login)->server->providers, LASSO_PROFILE(login)->remote_providerID); - profile->msg_url = lasso_provider_get_metadata_one( - remote_provider, "AssertionConsumerServiceURL"); + profile->msg_url = lasso_provider_get_assertion_consumer_service_url(remote_provider, + LASSO_LIB_AUTHN_REQUEST(profile->request)->AssertionConsumerServiceID); return 0; } diff --git a/lasso/id-ff/provider.c b/lasso/id-ff/provider.c index 046cfffa..f9f48ef6 100644 --- a/lasso/id-ff/provider.c +++ b/lasso/id-ff/provider.c @@ -36,6 +36,7 @@ struct _LassoProviderPrivate { gboolean dispose_has_run; GHashTable *SPDescriptor; + char *default_assertion_consumer; GHashTable *IDPDescriptor; }; @@ -63,6 +64,41 @@ char *protocol_methods[] = {"", "", "", "", "", "-http", "-soap"}; /*****************************************************************************/ /** + * lasso_provider_get_assertion_consumer_service_url: + * @provider: a #LassoProvider + * @service_id: the AssertionConsumerServiceID, NULL for default + * + * Extracts the AssertionConsumerServiceURL from the provider metadata + * descriptor. + * + * Return value: the element value, NULL if the element was not found. This + * string must be freed by the caller. + **/ +gchar* +lasso_provider_get_assertion_consumer_service_url(LassoProvider *provider, const char *service_id) +{ + GHashTable *descriptor; + GList *l; + char *sid = (char*)service_id; + char *name; + + if (sid == NULL) + sid = provider->private_data->default_assertion_consumer; + + descriptor = provider->private_data->SPDescriptor; + if (descriptor == NULL) + return NULL; + + name = g_strdup_printf("AssertionConsumerServiceURL %s", sid); + l = g_hash_table_lookup(descriptor, name); + g_free(name); + if (l == NULL) + return NULL; + + return g_strdup(l->data); +} + +/** * lasso_provider_get_metadata_one: * @provider: a #LassoProvider * @name: the element name @@ -81,6 +117,8 @@ lasso_provider_get_metadata_one(LassoProvider *provider, const char *name) descriptor = provider->private_data->SPDescriptor; /* default to SP */ if (provider->role == LASSO_PROVIDER_ROLE_IDP) descriptor = provider->private_data->IDPDescriptor; + if (descriptor == NULL) + return NULL; l = g_hash_table_lookup(descriptor, name); if (l) @@ -274,10 +312,11 @@ lasso_provider_get_base64_succint_id(LassoProvider *provider) static LassoNodeClass *parent_class = NULL; static void -load_descriptor(xmlNode *xmlnode, GHashTable *descriptor) +load_descriptor(xmlNode *xmlnode, GHashTable *descriptor, LassoProvider *provider) { xmlNode *t; GList *elements; + char *name; t = xmlnode->children; while (t) { @@ -285,27 +324,31 @@ load_descriptor(xmlNode *xmlnode, GHashTable *descriptor) t = t->next; continue; } - /* XXX: AssertionConsumerServiceURL nodes have attributes */ - elements = g_hash_table_lookup(descriptor, t->name); + if (strcmp(t->name, "AssertionConsumerServiceURL") == 0) { + char *isDefault = xmlGetProp(t, "isDefault"); + char *id = xmlGetProp(t, "id"); + name = g_strdup_printf("%s %s", t->name, id); + if (isDefault) { + if (strcmp(isDefault, "true") == 0) + provider->private_data->default_assertion_consumer = + g_strdup(id); + xmlFree(isDefault); + } + xmlFree(id); + } else { + name = g_strdup(t->name); + } + elements = g_hash_table_lookup(descriptor, name); elements = g_list_append(elements, g_strdup(xmlNodeGetContent(t))); - g_hash_table_insert(descriptor, g_strdup(t->name), elements); + g_hash_table_insert(descriptor, name, elements); t = t->next; } } -static void -add_descriptor_childnodes(gchar *key, GList *value, xmlNode *xmlnode) -{ - while (value) { - xmlNewTextChild(xmlnode, NULL, key, value->data); - value = g_list_next(value); - } -} - static xmlNode* get_xmlNode(LassoNode *node, gboolean lasso_dump) { - xmlNode *xmlnode, *t; + xmlNode *xmlnode; LassoProvider *provider = LASSO_PROVIDER(node); char *roles[] = { "None", "SP", "IdP"}; @@ -321,19 +364,9 @@ get_xmlNode(LassoNode *node, gboolean lasso_dump) if (provider->ca_cert_chain) xmlNewTextChild(xmlnode, NULL, "CaCertChainFilePath", provider->ca_cert_chain); - if (g_hash_table_size(provider->private_data->SPDescriptor)) { - t = xmlNewTextChild(xmlnode, NULL, "SPDescriptor", NULL); - g_hash_table_foreach(provider->private_data->SPDescriptor, - (GHFunc)add_descriptor_childnodes, t); - } + if (provider->metadata_filename) + xmlNewTextChild(xmlnode, NULL, "MetadataFilePath", provider->metadata_filename); - if (g_hash_table_size(provider->private_data->IDPDescriptor)) { - t = xmlNewTextChild(xmlnode, NULL, "IDPDescriptor", NULL); - g_hash_table_foreach(provider->private_data->IDPDescriptor, - (GHFunc)add_descriptor_childnodes, t); - } - - return xmlnode; } @@ -368,10 +401,11 @@ init_from_xml(LassoNode *node, xmlNode *xmlnode) provider->public_key = xmlNodeGetContent(t); if (strcmp(t->name, "CaCertChainFilePath") == 0) provider->ca_cert_chain = xmlNodeGetContent(t); - if (strcmp(t->name, "SPDescriptor") == 0) - load_descriptor(t, provider->private_data->SPDescriptor); - if (strcmp(t->name, "IDPDescriptor") == 0) - load_descriptor(t, provider->private_data->IDPDescriptor); + if (strcmp(t->name, "MetadataFilePath") == 0) { + xmlChar *s = xmlNodeGetContent(t); + lasso_provider_load_metadata(provider, s); + xmlFree(s); + }; t = t->next; } return 0; @@ -419,12 +453,14 @@ finalize(GObject *object) static void instance_init(LassoProvider *provider) { - provider->private_data = g_new(LassoProviderPrivate, 1); - provider->private_data->dispose_has_run = FALSE; provider->role = LASSO_PROVIDER_ROLE_NONE; + provider->ProviderID = NULL; + provider->metadata_filename = NULL; provider->public_key = NULL; provider->ca_cert_chain = NULL; - provider->ProviderID = NULL; + provider->private_data = g_new(LassoProviderPrivate, 1); + provider->private_data->dispose_has_run = FALSE; + provider->private_data->default_assertion_consumer = NULL; 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( @@ -482,6 +518,8 @@ lasso_provider_load_metadata(LassoProvider *provider, const gchar *metadata) if (doc == NULL) return FALSE; + provider->metadata_filename = g_strdup(metadata); + xpathCtx = xmlXPathNewContext(doc); xmlXPathRegisterNs(xpathCtx, "md", LASSO_METADATA_HREF); xmlXPathRegisterNs(xpathCtx, "lib", LASSO_LIB_HREF); @@ -507,7 +545,7 @@ lasso_provider_load_metadata(LassoProvider *provider, const gchar *metadata) xpathObj = xmlXPathEvalExpression(xpath_idp, xpathCtx); if (xpathObj && xpathObj->nodesetval && xpathObj->nodesetval->nodeNr == 1) { load_descriptor(xpathObj->nodesetval->nodeTab[0], - provider->private_data->IDPDescriptor); + provider->private_data->IDPDescriptor, provider); if (compatibility) { /* lookup ProviderID */ node = xpathObj->nodesetval->nodeTab[0]->children; @@ -525,7 +563,7 @@ lasso_provider_load_metadata(LassoProvider *provider, const gchar *metadata) xpathObj = xmlXPathEvalExpression(xpath_sp, xpathCtx); if (xpathObj && xpathObj->nodesetval && xpathObj->nodesetval->nodeNr == 1) { load_descriptor(xpathObj->nodesetval->nodeTab[0], - provider->private_data->SPDescriptor); + provider->private_data->SPDescriptor, provider); if (compatibility) { /* lookup ProviderID */ node = xpathObj->nodesetval->nodeTab[0]->children; diff --git a/lasso/id-ff/provider.h b/lasso/id-ff/provider.h index af71aa1b..68660b71 100644 --- a/lasso/id-ff/provider.h +++ b/lasso/id-ff/provider.h @@ -77,6 +77,7 @@ struct _LassoProvider { gchar *ProviderID; LassoProviderRole role; + char *metadata_filename; gchar *public_key; gchar *ca_cert_chain; @@ -91,6 +92,8 @@ struct _LassoProviderClass { LASSO_EXPORT GType lasso_provider_get_type(void); LASSO_EXPORT LassoProvider* lasso_provider_new(LassoProviderRole role, const char *metadata, const char *public_key, const char *ca_cert_chain); +LASSO_EXPORT gchar* lasso_provider_get_assertion_consumer_service_url(LassoProvider *provider, + const char *service_id); LASSO_EXPORT gchar* lasso_provider_get_metadata_one(LassoProvider *provider, const char *name); LASSO_EXPORT GList* lasso_provider_get_metadata_list(LassoProvider *provider, const char *name); |
