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.
This commit is contained in:
parent
94cd82e6ae
commit
a6de92e312
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ struct _LassoProviderPrivate
|
|||
{
|
||||
gboolean dispose_has_run;
|
||||
GHashTable *SPDescriptor;
|
||||
char *default_assertion_consumer;
|
||||
GHashTable *IDPDescriptor;
|
||||
};
|
||||
|
||||
|
@ -62,6 +63,41 @@ char *protocol_methods[] = {"", "", "", "", "", "-http", "-soap"};
|
|||
/* public methods */
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue