diff options
| author | Benjamin Dauvergne <bdauvergne@entrouvert.com> | 2010-01-12 15:39:31 +0000 |
|---|---|---|
| committer | Benjamin Dauvergne <bdauvergne@entrouvert.com> | 2010-01-12 15:39:31 +0000 |
| commit | 56bd9e24052092de2cfe9562320a9291974366c5 (patch) | |
| tree | 29eb3bd66516ec4687ed8e73ecf6ac646f4b7bd1 | |
| parent | 21cc1bf7eeb82d4f5a0dc3e8ca7e73fc5562072d (diff) | |
| download | lasso-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.c | 6 | ||||
| -rw-r--r-- | lasso/saml-2.0/provider.c | 54 | ||||
| -rw-r--r-- | lasso/saml-2.0/providerprivate.h | 2 |
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 */ |
