summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Peters <fpeters@entrouvert.com>2004-12-24 10:04:37 +0000
committerFrederic Peters <fpeters@entrouvert.com>2004-12-24 10:04:37 +0000
commita6de92e3126595f9217b65184c1029cdf6bbd3f5 (patch)
treef175833c0c2bd5068eb052475f5cdcadf6bee913
parent94cd82e6aeab19a0a799dbbfb9fdb1d4a797e576 (diff)
downloadlasso-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.txt1
-rw-r--r--docs/reference/tmpl/provider.sgml11
-rw-r--r--lasso/id-ff/login.c31
-rw-r--r--lasso/id-ff/provider.c108
-rw-r--r--lasso/id-ff/provider.h3
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);