summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-01-12 15:39:31 +0000
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-01-12 15:39:31 +0000
commit56bd9e24052092de2cfe9562320a9291974366c5 (patch)
tree29eb3bd66516ec4687ed8e73ecf6ac646f4b7bd1
parent21cc1bf7eeb82d4f5a0dc3e8ca7e73fc5562072d (diff)
downloadlasso-56bd9e24052092de2cfe9562320a9291974366c5.tar.gz
lasso-56bd9e24052092de2cfe9562320a9291974366c5.tar.xz
lasso-56bd9e24052092de2cfe9562320a9291974366c5.zip
Fix mitm attack using the AssertionConsumerURL property on requests
* lasso/saml-2.0/login.c: check that the URL is know before using it * lasso/saml-2.0/provider.c lasso/saml-2.0/providerprivate.h: add a function to check that an URL corresponds to a know AssertionConsumer of the given provider.
-rw-r--r--lasso/saml-2.0/login.c6
-rw-r--r--lasso/saml-2.0/provider.c54
-rw-r--r--lasso/saml-2.0/providerprivate.h2
3 files changed, 60 insertions, 2 deletions
diff --git a/lasso/saml-2.0/login.c b/lasso/saml-2.0/login.c
index 22503779..95c4a3bc 100644
--- a/lasso/saml-2.0/login.c
+++ b/lasso/saml-2.0/login.c
@@ -1358,7 +1358,11 @@ lasso_saml20_login_get_assertion_consumer_service_url(LassoLogin *login,
request = LASSO_SAMLP2_AUTHN_REQUEST(LASSO_PROFILE(login)->request);
if (request->AssertionConsumerServiceURL) {
- return g_strdup(request->AssertionConsumerServiceURL);
+ if (lasso_saml20_provider_check_assertion_consumer_service_url(remote_provider,
+ request->AssertionConsumerServiceURL,
+ request->ProtocolBinding)) {
+ return g_strdup(request->AssertionConsumerServiceURL);
+ }
}
if (request->AssertionConsumerServiceIndex != -1 || request->ProtocolBinding == NULL) {
diff --git a/lasso/saml-2.0/provider.c b/lasso/saml-2.0/provider.c
index 81e91915..5598fd60 100644
--- a/lasso/saml-2.0/provider.c
+++ b/lasso/saml-2.0/provider.c
@@ -42,6 +42,8 @@ const char *profile_names[] = {
NULL
};
+static void add_assertion_consumer_url_to_list(gchar *key, G_GNUC_UNUSED gpointer value, GList **list);
+
static void
load_descriptor(xmlNode *xmlnode, GHashTable *descriptor, LassoProvider *provider)
{
@@ -247,6 +249,58 @@ lasso_saml20_provider_get_first_http_method(LassoProvider *provider,
return method;
}
+gboolean
+lasso_saml20_provider_check_assertion_consumer_service_url(LassoProvider *provider, const gchar *url, const gchar *binding)
+{
+ GHashTable *descriptor;
+ GList *l = NULL, *r = NULL, *candidate = NULL;
+ char *name;
+ char *binding_s = NULL;
+ int lname;
+
+ descriptor = provider->private_data->SPDescriptor;
+ if (descriptor == NULL || url == NULL || binding == NULL)
+ return FALSE;
+
+ if (strcmp(binding, LASSO_SAML2_METADATA_BINDING_SOAP) == 0) {
+ binding_s = "SOAP";
+ } else if (strcmp(binding, LASSO_SAML2_METADATA_BINDING_REDIRECT) == 0) {
+ binding_s = "HTTP-Redirect";
+ } else if (strcmp(binding, LASSO_SAML2_METADATA_BINDING_POST) == 0) {
+ binding_s = "HTTP-POST";
+ } else if (strcmp(binding, LASSO_SAML2_METADATA_BINDING_ARTIFACT) == 0) {
+ binding_s = "HTTP-Artifact";
+ } else if (strcmp(binding, LASSO_SAML2_METADATA_BINDING_PAOS) == 0) {
+ binding_s = "PAOS";
+ }
+
+ if (binding_s == NULL) {
+ return FALSE;
+ }
+
+ g_hash_table_foreach(descriptor, (GHFunc)add_assertion_consumer_url_to_list, &r);
+
+ name = g_strdup_printf("AssertionConsumerService %s ", binding_s);
+ lname = strlen(name);
+ for (l = r; l; l = g_list_next(l)) {
+ char *b = l->data;
+ if (strncmp(name, b, lname) == 0) {
+ candidate = g_hash_table_lookup(descriptor, b);
+ if (candidate && candidate->data && strcmp(candidate->data, url) == 0)
+ break;
+ else
+ candidate = NULL;
+ }
+ }
+ g_free(name);
+ g_list_free(r);
+
+ if (candidate)
+ return TRUE;
+ else
+ return FALSE;
+}
+
gchar*
lasso_saml20_provider_get_assertion_consumer_service_url(const LassoProvider *provider,
int service_id)
diff --git a/lasso/saml-2.0/providerprivate.h b/lasso/saml-2.0/providerprivate.h
index ae4bc2f1..5c08fe5c 100644
--- a/lasso/saml-2.0/providerprivate.h
+++ b/lasso/saml-2.0/providerprivate.h
@@ -49,7 +49,7 @@ gchar* lasso_saml20_provider_get_assertion_consumer_service_binding(const LassoP
int service_id);
gchar* lasso_saml20_provider_get_assertion_consumer_service_url_by_binding(const LassoProvider *provider,
gchar *binding);
-
+gboolean lasso_saml20_provider_check_assertion_consumer_service_url(LassoProvider *provider, const gchar *url, const gchar *binding);
#ifdef __cplusplus
}
#endif /* __cplusplus */