forked from pool/strongswan
103 lines
3.0 KiB
Diff
103 lines
3.0 KiB
Diff
|
From ca1a65cc6aef2e037b529574783b7c571d1d82a9 Mon Sep 17 00:00:00 2001
|
||
|
From: Martin Willi <martin@strongswan.org>
|
||
|
Date: Wed, 3 Jun 2015 10:52:34 +0200
|
||
|
References: bsc#933591,CVE-2015-4171
|
||
|
Subject: [PATCH] ikev2: Enforce remote authentication config before proceeding
|
||
|
with own authentication
|
||
|
|
||
|
Previously the constraints in the authentication configuration of an
|
||
|
initiator were enforced only after all authentication rounds were
|
||
|
complete. This posed a problem if an initiator used EAP or PSK
|
||
|
authentication while the responder was authenticated with a certificate
|
||
|
and if a rogue server was able to authenticate itself with a valid
|
||
|
certificate issued by any CA the initiator trusted.
|
||
|
|
||
|
Because any constraints for the responder's identity (rightid) or other
|
||
|
aspects of the authentication (e.g. rightca) the initiator had were not
|
||
|
enforced until the initiator itself finished its authentication such a rogue
|
||
|
responder was able to acquire usernames and password hashes from the client.
|
||
|
And if a client supported EAP-GTC it was even possible to trick it into
|
||
|
sending plaintext passwords.
|
||
|
|
||
|
This patch enforces the configured constraints right after the responder's
|
||
|
authentication successfully finished for each round and before the initiator
|
||
|
starts with its own authentication.
|
||
|
|
||
|
Fixes CVE-2015-4171.
|
||
|
---
|
||
|
src/libcharon/sa/ikev2/tasks/ike_auth.c | 44 +++++++++++++++++++++++++++++++++
|
||
|
1 file changed, 44 insertions(+)
|
||
|
|
||
|
diff --git a/src/libcharon/sa/ikev2/tasks/ike_auth.c b/src/libcharon/sa/ikev2/tasks/ike_auth.c
|
||
|
index bf747a49edde..2554496c1916 100644
|
||
|
--- a/src/libcharon/sa/ikev2/tasks/ike_auth.c
|
||
|
+++ b/src/libcharon/sa/ikev2/tasks/ike_auth.c
|
||
|
@@ -112,6 +112,11 @@ struct private_ike_auth_t {
|
||
|
* received an INITIAL_CONTACT?
|
||
|
*/
|
||
|
bool initial_contact;
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Is EAP acceptable, did we strictly authenticate peer?
|
||
|
+ */
|
||
|
+ bool eap_acceptable;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
@@ -879,6 +884,37 @@ static void send_auth_failed_informational(private_ike_auth_t *this,
|
||
|
message->destroy(message);
|
||
|
}
|
||
|
|
||
|
+/**
|
||
|
+ * Check if strict constraint fullfillment required to continue current auth
|
||
|
+ */
|
||
|
+static bool require_strict(private_ike_auth_t *this, bool mutual_eap)
|
||
|
+{
|
||
|
+ auth_cfg_t *cfg;
|
||
|
+
|
||
|
+ if (this->eap_acceptable)
|
||
|
+ {
|
||
|
+ return FALSE;
|
||
|
+ }
|
||
|
+
|
||
|
+ cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
|
||
|
+ switch ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS))
|
||
|
+ {
|
||
|
+ case AUTH_CLASS_EAP:
|
||
|
+ if (mutual_eap && this->my_auth)
|
||
|
+ {
|
||
|
+ this->eap_acceptable = TRUE;
|
||
|
+ return !this->my_auth->is_mutual(this->my_auth);
|
||
|
+ }
|
||
|
+ return TRUE;
|
||
|
+ case AUTH_CLASS_PSK:
|
||
|
+ return TRUE;
|
||
|
+ case AUTH_CLASS_PUBKEY:
|
||
|
+ case AUTH_CLASS_ANY:
|
||
|
+ default:
|
||
|
+ return FALSE;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
METHOD(task_t, process_i, status_t,
|
||
|
private_ike_auth_t *this, message_t *message)
|
||
|
{
|
||
|
@@ -1014,6 +1050,14 @@ METHOD(task_t, process_i, status_t,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+ if (require_strict(this, mutual_eap))
|
||
|
+ {
|
||
|
+ if (!update_cfg_candidates(this, TRUE))
|
||
|
+ {
|
||
|
+ goto peer_auth_failed;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
if (this->my_auth)
|
||
|
{
|
||
|
switch (this->my_auth->process(this->my_auth, message))
|
||
|
--
|
||
|
1.9.1
|
||
|
|