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:
parent
8d7c968fa8
commit
94398d7edf
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue