summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-07-20 14:15:55 +0000
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-07-20 14:15:55 +0000
commitaebd6ed3d73da56409593b4d500748959d8c1cea (patch)
treefb21057e0234a2f459cc502fccab0ecb7e6bab0d
parent52d9fba0fa28be83571a267e30757f2699340d90 (diff)
downloadlasso-aebd6ed3d73da56409593b4d500748959d8c1cea.tar.gz
lasso-aebd6ed3d73da56409593b4d500748959d8c1cea.tar.xz
lasso-aebd6ed3d73da56409593b4d500748959d8c1cea.zip
[SAMLv2] simplify logic for handling AuthnResponse with binding HTTP-Post
The logic is now simpler: - first lasso_saml20_profile_process_any_response check the signature on the message - then lasso_saml20_login_process_response_status_and_assertion traverse all the assertions: - if the message is signed all assertion from the same issuer are automatically accepted, - if the message is not signed, or the signature validation failed, or the assertion has a different issuer than the message, we check the signature directly on the assertion. If any of the assertions fails the signature check, the result will be LASSO_PROFILE_ERROR_CANNOT_VERIFY_SIGNATURE. The public field profile->signature_status will contain only the message level signature status, each assertion signature status is not accessible. That will change when signature and key handling is reworked.
-rw-r--r--lasso/saml-2.0/login.c98
1 files changed, 38 insertions, 60 deletions
diff --git a/lasso/saml-2.0/login.c b/lasso/saml-2.0/login.c
index 4125ba27..7b6cf3c7 100644
--- a/lasso/saml-2.0/login.c
+++ b/lasso/saml-2.0/login.c
@@ -58,8 +58,7 @@
static int lasso_saml20_login_process_federation(LassoLogin *login, gboolean is_consent_obtained);
static gboolean lasso_saml20_login_must_ask_for_consent_private(LassoLogin *login);
-static gint lasso_saml20_login_process_response_status_and_assertion(LassoLogin *login,
- lasso_error_t *assertion_signature_status);
+static gint lasso_saml20_login_process_response_status_and_assertion(LassoLogin *login);
static char* lasso_saml20_login_get_assertion_consumer_service_url(LassoLogin *login,
LassoProvider *remote_provider);
static gboolean _lasso_login_must_verify_signature(LassoProfile *profile) G_GNUC_UNUSED;
@@ -1015,7 +1014,7 @@ lasso_saml20_login_process_paos_response_msg(LassoLogin *login, gchar *msg)
profile = LASSO_PROFILE(login);
rc1 = lasso_saml20_profile_process_soap_response(profile, msg);
- rc2 = lasso_saml20_login_process_response_status_and_assertion(login, NULL);
+ rc2 = lasso_saml20_login_process_response_status_and_assertion(login);
if (rc1) {
return rc1;
@@ -1037,52 +1036,32 @@ gint
lasso_saml20_login_process_authn_response_msg(LassoLogin *login, gchar *authn_response_msg)
{
LassoProfile *profile = NULL;
- int rc1, rc2, message_signature_status;
LassoSamlp2Response *samlp2_response = NULL;
LassoHttpMethod response_method = LASSO_HTTP_METHOD_NONE;
+ int rc = 0;
lasso_null_param(authn_response_msg);
/* parse the message */
profile = LASSO_PROFILE(login);
samlp2_response = (LassoSamlp2Response*)lasso_samlp2_response_new();
- rc1 = lasso_saml20_profile_process_any_response(profile,
+ rc = lasso_saml20_profile_process_any_response(profile,
(LassoSamlp2StatusResponse*)samlp2_response, &response_method,
authn_response_msg);
if (response_method != LASSO_HTTP_METHOD_POST) {
/* Only HTTP-Post binding is possible through this method */
- return LASSO_PROFILE_ERROR_UNSUPPORTED_PROFILE;
+ goto_cleanup_with_rc(LASSO_PROFILE_ERROR_UNSUPPORTED_PROFILE);
}
- message_signature_status = profile->signature_status;
- rc2 = lasso_saml20_login_process_response_status_and_assertion(login,
- NULL);
- /** The more important signature errors */
+ /* Skip signature errors, let lasso_saml20_login_process_response_status_and_assertion
+ * handle them */
+ goto_cleanup_if_fail (rc == 0 || rc == LASSO_PROFILE_ERROR_CANNOT_VERIFY_SIGNATURE);
+
+ rc = lasso_saml20_login_process_response_status_and_assertion(login);
+cleanup:
lasso_release_gobject(samlp2_response);
- if (rc1) {
- return rc1;
- }
- if (rc2) {
- return rc2;
- }
- switch (lasso_profile_get_signature_verify_hint(profile)) {
- case LASSO_PROFILE_SIGNATURE_VERIFY_HINT_FORCE:
- if (message_signature_status) {
- return message_signature_status;
- }
- case LASSO_PROFILE_SIGNATURE_VERIFY_HINT_MAYBE:
- if (response_method == LASSO_HTTP_METHOD_POST &&
- profile->signature_status) {
- return profile->signature_status;
- }
- break;
- case LASSO_PROFILE_SIGNATURE_VERIFY_HINT_IGNORE:
- break;
- default:
- g_assert(0);
- }
- return 0;
+ return rc;
}
gint
@@ -1098,7 +1077,7 @@ lasso_saml20_login_process_response_msg(LassoLogin *login, gchar *response_msg)
if (LASSO_IS_SAMLP2_ARTIFACT_RESPONSE(login->parent.response)) {
return lasso_saml20_login_process_authn_request_msg(login, NULL);
} else {
- return lasso_saml20_login_process_response_status_and_assertion(login, NULL);
+ return lasso_saml20_login_process_response_status_and_assertion(login);
}
}
@@ -1231,22 +1210,21 @@ _lasso_saml20_login_decrypt_assertion(LassoLogin *login, LassoSamlp2Response *sa
}
static gint
-lasso_saml20_login_process_response_status_and_assertion(LassoLogin *login, lasso_error_t *assertion_signature_status)
+lasso_saml20_login_process_response_status_and_assertion(LassoLogin *login)
{
LassoSamlp2StatusResponse *response;
LassoSamlp2Response *samlp2_response = NULL;
LassoProfile *profile;
char *status_value;
- int rc = 0, rc1 = 0, message_signature_status;
+ lasso_error_t rc = 0;
+ lasso_error_t assertion_signature_status = 0;
LassoProfileSignatureVerifyHint verify_hint;
- lasso_error_t _assertion_signature_status = 0;
profile = &login->parent;
lasso_extract_node_or_fail(response, profile->response, SAMLP2_STATUS_RESPONSE,
LASSO_PROFILE_ERROR_INVALID_MSG);
lasso_extract_node_or_fail(samlp2_response, response, SAMLP2_RESPONSE,
LASSO_PROFILE_ERROR_INVALID_MSG);
- message_signature_status = profile->signature_status;
if (response->Status == NULL || ! LASSO_IS_SAMLP2_STATUS(response->Status) ||
response->Status->StatusCode == NULL ||
@@ -1278,7 +1256,7 @@ lasso_saml20_login_process_response_status_and_assertion(LassoLogin *login, lass
}
/* Decrypt all EncryptedAssertions */
- rc1 = _lasso_saml20_login_decrypt_assertion(login, samlp2_response);
+ _lasso_saml20_login_decrypt_assertion(login, samlp2_response);
/* traverse all assertions */
goto_cleanup_if_fail_with_rc (samlp2_response->Assertion != NULL,
LASSO_PROFILE_ERROR_MISSING_ASSERTION);
@@ -1287,34 +1265,24 @@ lasso_saml20_login_process_response_status_and_assertion(LassoLogin *login, lass
lasso_foreach_full_begin(LassoSaml2Assertion*, assertion, it, samlp2_response->Assertion);
LassoSaml2Subject *subject = NULL;
- int rc2 = 0;
lasso_assign_gobject (login->private_data->saml2_assertion, assertion);
/* If signature has already been verified on the message, and assertion has the same
* issuer as the message, the assertion is covered. So no need to verify a second
* time */
- _assertion_signature_status = lasso_saml20_login_check_assertion_signature(login,
- assertion);
- if (message_signature_status != 0
+ if (profile->signature_status != 0
|| ! _lasso_check_assertion_issuer(assertion,
profile->remote_providerID)
|| verify_hint == LASSO_PROFILE_SIGNATURE_VERIFY_HINT_FORCE) {
- rc2 = _assertion_signature_status;
- profile->signature_status = rc2;
+ assertion_signature_status = lasso_saml20_login_check_assertion_signature(login,
+ assertion);
+ /* If signature validation fails, it is the return code for this function */
+ if (assertion_signature_status) {
+ rc = LASSO_PROFILE_ERROR_CANNOT_VERIFY_SIGNATURE;
+ }
}
- switch (verify_hint) {
- case LASSO_PROFILE_SIGNATURE_VERIFY_HINT_FORCE:
- case LASSO_PROFILE_SIGNATURE_VERIFY_HINT_MAYBE:
- goto_cleanup_if_fail_with_rc (profile->signature_status == 0,
- LASSO_LOGIN_ERROR_INVALID_ASSERTION_SIGNATURE);
- break;
- case LASSO_PROFILE_SIGNATURE_VERIFY_HINT_IGNORE:
- break;
- default:
- g_assert(0);
- }
lasso_extract_node_or_fail(subject, assertion->Subject, SAML2_SUBJECT,
LASSO_PROFILE_ERROR_MISSING_SUBJECT);
@@ -1332,11 +1300,21 @@ lasso_saml20_login_process_response_status_and_assertion(LassoLogin *login, lass
lasso_check_good_rc(lasso_saml20_profile_process_name_identifier_decryption(profile,
&subject->NameID, &subject->EncryptedID));
lasso_foreach_full_end();
-
-cleanup:
- if (assertion_signature_status) {
- *assertion_signature_status = _assertion_signature_status;
+
+ switch (verify_hint) {
+ case LASSO_PROFILE_SIGNATURE_VERIFY_HINT_FORCE:
+ case LASSO_PROFILE_SIGNATURE_VERIFY_HINT_MAYBE:
+ break;
+ case LASSO_PROFILE_SIGNATURE_VERIFY_HINT_IGNORE:
+ /* ignore signature errors */
+ if (rc == LASSO_PROFILE_ERROR_CANNOT_VERIFY_SIGNATURE) {
+ rc = 0;
+ }
+ break;
+ default:
+ g_assert(0);
}
+cleanup:
return rc;
}