ID-FF 1.2 & SAML 2.0: fix "fix bug 173" match assertion and not the response with authn request id

* lasso/id-ff/login.c:
 * lasso/saml-2.0/login.c:
   Serialize/Unserialize request_id private field in LassoLogin dumps.
   Match InResponseTo assertion attribute (ID-FF 1.2) or
   SubjectConfirmationData attribute (SAML 2.0) to original request id
   if it is present.
This commit is contained in:
Benjamin Dauvergne 2009-03-03 20:52:45 +00:00
parent 8d7c968fa8
commit 94398d7edf
2 changed files with 42 additions and 21 deletions

View File

@ -600,10 +600,29 @@ lasso_login_process_response_status_and_assertion(LassoLogin *login)
if (response->Assertion) {
LassoProfile *profile = LASSO_PROFILE(login);
LassoSamlAssertion *assertion = response->Assertion->data;
LassoLibAssertion *lib_assertion = NULL;
if (LASSO_IS_LIB_ASSERTION(assertion)) {
lib_assertion = LASSO_LIB_ASSERTION(assertion);
}
idp = g_hash_table_lookup(profile->server->providers, profile->remote_providerID);
if (idp == NULL) {
return LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND;
}
/* Validate AuthnRequest RequestID and InResponseTo */
{
char *previous_reqid = login->private_data->request_id;
if (previous_reqid) {
if (lib_assertion == NULL ||
lib_assertion->InResponseTo == NULL ||
strcmp(lib_assertion->InResponseTo, previous_reqid) != 0) {
return critical_error(LASSO_LOGIN_ERROR_ASSERTION_DOES_NOT_MATCH_REQUEST_ID);
}
}
}
/* If the status of the signature verification process is not 0, we try to verify on
* the assertion */
if (profile->signature_status != 0) {
@ -1928,17 +1947,6 @@ lasso_login_process_response_msg(LassoLogin *login, gchar *response_msg)
}
response = LASSO_SAMLP_RESPONSE(profile->response);
/* Validate RequestID and InResponseTo */
{
char *previous_reqid = login->private_data->request_id;
if (previous_reqid) {
if (response->parent.InResponseTo == NULL ||
strcmp(response->parent.InResponseTo, previous_reqid) != 0) {
return critical_error(LASSO_LOGIN_ERROR_REFER_TO_UNKNOWN_REQUEST);
}
}
}
/* In the artifact profile we cannot verify the signature on the message, we must wait the
* verification on the assertion, so for the moment the signature verification failed. */
profile->signature_status = LASSO_DS_ERROR_SIGNATURE_VERIFICATION_FAILED;
@ -2031,6 +2039,7 @@ get_xmlNode(LassoNode *node, gboolean lasso_dump)
xmlnode = parent_class->get_xmlNode(node, lasso_dump);
xmlSetProp(xmlnode, (xmlChar*)"LoginDumpVersion", (xmlChar*)"2");
xmlSetProp(xmlnode, (xmlChar*)"RequestID", (xmlChar*)LASSO_LOGIN(node)->private_data->request_id);
if (login->protocolProfile == LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART)
xmlNewTextChild(xmlnode, NULL, (xmlChar*)"ProtocolProfile", (xmlChar*)"Artifact");
@ -2052,6 +2061,9 @@ init_from_xml(LassoNode *node, xmlNode *xmlnode)
rc = parent_class->init_from_xml(node, xmlnode);
if (rc) return rc;
lasso_assign_new_string(LASSO_LOGIN(node)->private_data->request_id, (char*)xmlGetProp(xmlnode,
(xmlChar*)"RequestID"));
t = xmlnode->children;
while (t) {
if (t->type != XML_ELEMENT_NODE) {

View File

@ -754,9 +754,14 @@ lasso_saml20_login_build_assertion(LassoLogin *login,
LassoProvider *provider = NULL;
LassoSaml2EncryptedElement *encrypted_element = NULL;
LassoSamlp2Response *response = NULL;
LassoSamlp2RequestAbstract *request_abstract = NULL;
provider = g_hash_table_lookup(profile->server->providers, profile->remote_providerID);
if (profile->request && LASSO_IS_SAMLP2_REQUEST_ABSTRACT(profile->request)) {
request_abstract = LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request);
}
if (profile->identity && strcmp(login->nameIDPolicy,
LASSO_SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT) != 0) {
char *name_id_sp_name_qualifier;
@ -800,6 +805,10 @@ lasso_saml20_login_build_assertion(LassoLogin *login,
notBefore);
assertion->Subject->SubjectConfirmation->SubjectConfirmationData->NotOnOrAfter = g_strdup(
notOnOrAfter);
if (request_abstract) {
lasso_assign_string(assertion->Subject->SubjectConfirmation->SubjectConfirmationData->InResponseTo,
request_abstract->ID);
}
if (name_id_policy && (strcmp(name_id_policy->Format,
LASSO_SAML2_NAME_IDENTIFIER_FORMAT_EMAIL) == 0 ||
@ -1190,16 +1199,6 @@ lasso_saml20_login_process_response_status_and_assertion(LassoLogin *login)
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
response = LASSO_SAMLP2_STATUS_RESPONSE(LASSO_PROFILE(login)->response);
/* Try to validate the InResponseTo attribute */
{
char *previous_reqid = login->private_data->request_id;
if (previous_reqid) {
char *in_response_to = response->InResponseTo;
if (in_response_to == NULL || strcmp(previous_reqid, in_response_to) != 0) {
return LASSO_LOGIN_ERROR_REFER_TO_UNKNOWN_REQUEST;
}
}
}
if (response->Status == NULL || ! LASSO_IS_SAMLP2_STATUS(response->Status) ||
response->Status->StatusCode == NULL ||
@ -1271,6 +1270,16 @@ lasso_saml20_login_process_response_status_and_assertion(LassoLogin *login)
return LASSO_PROFILE_ERROR_MISSING_SUBJECT;
}
/* Verify some SubjectConfirmationData InResponseTo */
if (login->private_data->request_id && (
assertion->Subject->SubjectConfirmation == NULL ||
assertion->Subject->SubjectConfirmation->SubjectConfirmationData == NULL ||
assertion->Subject->SubjectConfirmation->SubjectConfirmationData->InResponseTo == NULL ||
strcmp(assertion->Subject->SubjectConfirmation->SubjectConfirmationData->InResponseTo, login->private_data->request_id) != 0)) {
return LASSO_LOGIN_ERROR_ASSERTION_DOES_NOT_MATCH_REQUEST_ID;
}
if (assertion->Subject->NameID != NULL) {
id_node = g_object_ref(assertion->Subject->NameID);
if (id_node != NULL) {