summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/eap_tnc/eap_tnc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins/eap_tnc/eap_tnc.c')
-rw-r--r--src/libcharon/plugins/eap_tnc/eap_tnc.c85
1 files changed, 82 insertions, 3 deletions
diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc.c b/src/libcharon/plugins/eap_tnc/eap_tnc.c
index 839425d59..f9ab74258 100644
--- a/src/libcharon/plugins/eap_tnc/eap_tnc.c
+++ b/src/libcharon/plugins/eap_tnc/eap_tnc.c
@@ -22,6 +22,7 @@
#include <daemon.h>
#include <tncifimv.h>
+#include <tncif_names.h>
/**
* Maximum size of an EAP-TNC message
@@ -62,6 +63,63 @@ struct private_eap_tnc_t {
};
+/**
+ * Callback function to get recommendation from TNCCS connection
+ */
+static bool enforce_recommendation(TNC_IMV_Action_Recommendation rec,
+ TNC_IMV_Evaluation_Result eval)
+{
+ char *group;
+ identification_t *id;
+ ike_sa_t *ike_sa;
+ auth_cfg_t *auth;
+ bool no_access = FALSE;
+
+ DBG1(DBG_TNC, "final recommendation is '%N' and evaluation is '%N'",
+ TNC_IMV_Action_Recommendation_names, rec,
+ TNC_IMV_Evaluation_Result_names, eval);
+
+ switch (rec)
+ {
+ case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
+ group = "allow";
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
+ group = "isolate";
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
+ case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
+ default:
+ group = "no access";
+ no_access = TRUE;
+ break;
+ }
+
+ ike_sa = charon->bus->get_sa(charon->bus);
+ if (!ike_sa)
+ {
+ DBG1(DBG_TNC, "policy enforcement point did not find IKE_SA");
+ return FALSE;
+ }
+
+ id = ike_sa->get_other_id(ike_sa);
+ DBG0(DBG_TNC, "policy enforced on peer '%Y' is '%s'", id, group);
+
+ if (no_access)
+ {
+ return FALSE;
+ }
+ else
+ {
+ auth = ike_sa->get_auth_cfg(ike_sa, FALSE);
+ id = identification_create_from_string(group);
+ auth->add(auth, AUTH_RULE_GROUP, id);
+ DBG1(DBG_TNC, "policy enforcement point added group membership '%s'",
+ group);
+ }
+ return TRUE;
+}
+
METHOD(eap_method_t, initiate, status_t,
private_eap_tnc_t *this, eap_payload_t **out)
{
@@ -155,6 +213,18 @@ METHOD(eap_method_t, is_mutual, bool,
METHOD(eap_method_t, destroy, void,
private_eap_tnc_t *this)
{
+ chunk_t pdp_server;
+ u_int16_t pdp_port;
+ tls_t *tls;
+
+ pdp_server = this->tnccs->get_pdp_server(this->tnccs, &pdp_port);
+ if (pdp_server.len)
+ {
+ DBG2(DBG_TNC, "TODO: setup PT-TLS connection to %.*s:%u",
+ pdp_server.len, pdp_server.ptr, pdp_port);
+ }
+ tls = &this->tnccs->tls;
+ tls->destroy(tls);
this->tls_eap->destroy(this->tls_eap);
free(this);
}
@@ -180,6 +250,7 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
private_eap_tnc_t *this;
int max_msg_count;
char* protocol;
+ tnccs_t *tnccs;
tnccs_type_t type;
INIT(this,
@@ -224,9 +295,17 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
free(this);
return NULL;
}
- this->tnccs = tnc->tnccs->create_instance(tnc->tnccs, type, is_server,
- server, peer, TNC_IFT_EAP_1_1);
- this->tls_eap = tls_eap_create(EAP_TNC, &this->tnccs->tls,
+ tnccs = tnc->tnccs->create_instance(tnc->tnccs, type,
+ is_server, server, peer, TNC_IFT_EAP_1_1,
+ is_server ? enforce_recommendation : NULL);
+ if (!tnccs)
+ {
+ DBG1(DBG_TNC, "TNCCS protocol '%s' not enabled", protocol);
+ free(this);
+ return NULL;
+ }
+ this->tnccs = tnccs->get_ref(tnccs);
+ this->tls_eap = tls_eap_create(EAP_TNC, &tnccs->tls,
EAP_TNC_MAX_MESSAGE_LEN,
max_msg_count, FALSE);
if (!this->tls_eap)