summaryrefslogtreecommitdiff
path: root/src/charon/sa/tasks
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/sa/tasks')
-rw-r--r--src/charon/sa/tasks/ike_auth.c16
-rw-r--r--src/charon/sa/tasks/ike_auth_lifetime.c200
-rw-r--r--src/charon/sa/tasks/ike_auth_lifetime.h61
-rw-r--r--src/charon/sa/tasks/ike_mobike.c8
-rw-r--r--src/charon/sa/tasks/ike_p2p.c97
-rw-r--r--src/charon/sa/tasks/task.c1
-rw-r--r--src/charon/sa/tasks/task.h2
7 files changed, 325 insertions, 60 deletions
diff --git a/src/charon/sa/tasks/ike_auth.c b/src/charon/sa/tasks/ike_auth.c
index a3cd6a2bc..de88a0abe 100644
--- a/src/charon/sa/tasks/ike_auth.c
+++ b/src/charon/sa/tasks/ike_auth.c
@@ -297,6 +297,7 @@ static status_t collect_other_init_data(private_ike_auth_t *this, message_t *mes
return NEED_MORE;
}
+
/**
* Implementation of task_t.build to create AUTH payload from EAP data
*/
@@ -520,6 +521,7 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
break;
case NOT_FOUND:
/* use EAP if no AUTH payload found */
+ this->ike_sa->set_condition(this->ike_sa, COND_EAP_AUTHENTICATED, TRUE);
this->eap_auth = eap_authenticator_create(this->ike_sa);
break;
default:
@@ -546,6 +548,7 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
{
peer_cfg_t *config;
eap_type_t eap_type;
+ u_int32_t eap_vendor;
eap_payload_t *eap_payload;
status_t status;
@@ -590,10 +593,11 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
return FAILED;
}
-
+
/* initiate EAP authenitcation */
- eap_type = config->get_eap_type(config);
- status = this->eap_auth->initiate(this->eap_auth, eap_type, &eap_payload);
+ eap_type = config->get_eap_type(config, &eap_vendor);
+ status = this->eap_auth->initiate(this->eap_auth, eap_type,
+ eap_vendor, &eap_payload);
message->add_payload(message, (payload_t*)eap_payload);
if (status != NEED_MORE)
{
@@ -645,6 +649,12 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
case ADDITIONAL_IP6_ADDRESS:
/* handled in ike_mobike task */
break;
+ case AUTH_LIFETIME:
+ /* handled in ike_auth_lifetime task */
+ break;
+ case P2P_ENDPOINT:
+ /* handled in ike_p2p task */
+ break;
default:
{
if (type < 16383)
diff --git a/src/charon/sa/tasks/ike_auth_lifetime.c b/src/charon/sa/tasks/ike_auth_lifetime.c
new file mode 100644
index 000000000..9d37ec608
--- /dev/null
+++ b/src/charon/sa/tasks/ike_auth_lifetime.c
@@ -0,0 +1,200 @@
+/**
+ * @file ike_auth_lifetime.c
+ *
+ * @brief Implementation of the ike_auth_lifetime task.
+ *
+ */
+
+/*
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "ike_auth_lifetime.h"
+
+#include <daemon.h>
+#include <encoding/payloads/notify_payload.h>
+
+
+typedef struct private_ike_auth_lifetime_t private_ike_auth_lifetime_t;
+
+/**
+ * Private members of a ike_auth_lifetime_t task.
+ */
+struct private_ike_auth_lifetime_t {
+
+ /**
+ * Public methods and task_t interface.
+ */
+ ike_auth_lifetime_t public;
+
+ /**
+ * Assigned IKE_SA.
+ */
+ ike_sa_t *ike_sa;
+};
+
+/**
+ * add the AUTH_LIFETIME notify to the message
+ */
+static void add_auth_lifetime(private_ike_auth_lifetime_t *this, message_t *message)
+{
+ chunk_t chunk;
+ u_int32_t lifetime;
+
+ lifetime = this->ike_sa->get_statistic(this->ike_sa, STAT_REAUTH_TIME);
+ if (lifetime)
+ {
+ chunk = chunk_from_thing(lifetime);
+ *(u_int32_t*)chunk.ptr = htonl(lifetime);
+ message->add_notify(message, FALSE, AUTH_LIFETIME, chunk);
+ }
+}
+
+/**
+ * read notifys from message and evaluate them
+ */
+static void process_payloads(private_ike_auth_lifetime_t *this, message_t *message)
+{
+ iterator_t *iterator;
+ payload_t *payload;
+ notify_payload_t *notify;
+
+ iterator = message->get_payload_iterator(message);
+ while (iterator->iterate(iterator, (void**)&payload))
+ {
+ if (payload->get_type(payload) == NOTIFY)
+ {
+ notify = (notify_payload_t*)payload;
+ switch (notify->get_notify_type(notify))
+ {
+ case AUTH_LIFETIME:
+ {
+ chunk_t data = notify->get_notification_data(notify);
+ u_int32_t lifetime = ntohl(*(u_int32_t*)data.ptr);
+ this->ike_sa->set_auth_lifetime(this->ike_sa, lifetime);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ iterator->destroy(iterator);
+}
+
+/**
+ * Implementation of task_t.process for initiator
+ */
+static status_t build_i(private_ike_auth_lifetime_t *this, message_t *message)
+{
+ if (message->get_exchange_type(message) == INFORMATIONAL)
+ {
+ add_auth_lifetime(this, message);
+ return SUCCESS;
+ }
+ return NEED_MORE;
+}
+
+/**
+ * Implementation of task_t.process for responder
+ */
+static status_t process_r(private_ike_auth_lifetime_t *this, message_t *message)
+{
+ if (message->get_exchange_type(message) == INFORMATIONAL)
+ {
+ process_payloads(this, message);
+ return SUCCESS;
+ }
+ return NEED_MORE;
+}
+
+/**
+ * Implementation of task_t.build for responder
+ */
+static status_t build_r(private_ike_auth_lifetime_t *this, message_t *message)
+{
+ if (message->get_exchange_type(message) == IKE_AUTH &&
+ this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
+ {
+ add_auth_lifetime(this, message);
+ return SUCCESS;
+ }
+ return NEED_MORE;
+}
+
+/**
+ * Implementation of task_t.process for initiator
+ */
+static status_t process_i(private_ike_auth_lifetime_t *this, message_t *message)
+{
+ if (message->get_exchange_type(message) == IKE_AUTH &&
+ this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
+ {
+ process_payloads(this, message);
+ return SUCCESS;
+ }
+ return NEED_MORE;
+}
+
+/**
+ * Implementation of task_t.get_type
+ */
+static task_type_t get_type(private_ike_auth_lifetime_t *this)
+{
+ return IKE_AUTH_LIFETIME;
+}
+
+/**
+ * Implementation of task_t.migrate
+ */
+static void migrate(private_ike_auth_lifetime_t *this, ike_sa_t *ike_sa)
+{
+ this->ike_sa = ike_sa;
+}
+
+/**
+ * Implementation of task_t.destroy
+ */
+static void destroy(private_ike_auth_lifetime_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+ike_auth_lifetime_t *ike_auth_lifetime_create(ike_sa_t *ike_sa, bool initiator)
+{
+ private_ike_auth_lifetime_t *this = malloc_thing(private_ike_auth_lifetime_t);
+
+ this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
+ this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
+ this->public.task.destroy = (void(*)(task_t*))destroy;
+
+ if (initiator)
+ {
+ this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
+ this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
+ }
+ else
+ {
+ this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
+ this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
+ }
+
+ this->ike_sa = ike_sa;
+
+ return &this->public;
+}
+
diff --git a/src/charon/sa/tasks/ike_auth_lifetime.h b/src/charon/sa/tasks/ike_auth_lifetime.h
new file mode 100644
index 000000000..500b89d39
--- /dev/null
+++ b/src/charon/sa/tasks/ike_auth_lifetime.h
@@ -0,0 +1,61 @@
+/**
+ * @file ike_auth_lifetime.h
+ *
+ * @brief Interface ike_auth_lifetime_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef IKE_AUTH_LIFETIME_H_
+#define IKE_AUTH_LIFETIME_H_
+
+typedef struct ike_auth_lifetime_t ike_auth_lifetime_t;
+
+#include <library.h>
+#include <sa/ike_sa.h>
+#include <sa/tasks/task.h>
+
+/**
+ * @brief Task of type IKE_AUTH_LIFETIME, implements RFC4478.
+ *
+ * This task exchanges lifetimes for IKE_AUTH to force a client to
+ * reauthenticate before the responders lifetime reaches the limit.
+ *
+ * @b Constructors:
+ * - ike_auth_lifetime_create()
+ *
+ * @ingroup tasks
+ */
+struct ike_auth_lifetime_t {
+
+ /**
+ * Implements the task_t interface
+ */
+ task_t task;
+};
+
+/**
+ * @brief Create a new IKE_AUTH_LIFETIME task.
+ *
+ * @param ike_sa IKE_SA this task works for
+ * @param initiator TRUE if taks is initiated by us
+ * @return ike_auth_lifetime task to handle by the task_manager
+ */
+ike_auth_lifetime_t *ike_auth_lifetime_create(ike_sa_t *ike_sa, bool initiator);
+
+#endif /* IKE_MOBIKE_H_ */
+
diff --git a/src/charon/sa/tasks/ike_mobike.c b/src/charon/sa/tasks/ike_mobike.c
index d1fc8c695..a53c243f0 100644
--- a/src/charon/sa/tasks/ike_mobike.c
+++ b/src/charon/sa/tasks/ike_mobike.c
@@ -287,7 +287,7 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet)
static status_t build_i(private_ike_mobike_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_AUTH &&
- message->get_payload(message, SECURITY_ASSOCIATION))
+ message->get_payload(message, ID_INITIATOR))
{
message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty);
build_address_list(this, message);
@@ -317,7 +317,7 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message)
static status_t process_r(private_ike_mobike_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_AUTH &&
- message->get_payload(message, SECURITY_ASSOCIATION))
+ message->get_payload(message, ID_INITIATOR))
{
process_payloads(this, message);
}
@@ -348,7 +348,7 @@ static status_t process_r(private_ike_mobike_t *this, message_t *message)
static status_t build_r(private_ike_mobike_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_AUTH &&
- message->get_payload(message, SECURITY_ASSOCIATION))
+ this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
{
if (this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
{
@@ -378,7 +378,7 @@ static status_t build_r(private_ike_mobike_t *this, message_t *message)
static status_t process_i(private_ike_mobike_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_AUTH &&
- message->get_payload(message, SECURITY_ASSOCIATION))
+ this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
{
process_payloads(this, message);
return SUCCESS;
diff --git a/src/charon/sa/tasks/ike_p2p.c b/src/charon/sa/tasks/ike_p2p.c
index de5a2e30e..84b88e16b 100644
--- a/src/charon/sa/tasks/ike_p2p.c
+++ b/src/charon/sa/tasks/ike_p2p.c
@@ -34,7 +34,7 @@
#define P2P_SESSIONID_LEN 8
#define P2P_SESSIONKEY_LEN 16
-// FIXME: proposed values
+/* FIXME: proposed values */
#define P2P_SESSIONID_MIN_LEN 4
#define P2P_SESSIONID_MAX_LEN 16
#define P2P_SESSIONKEY_MIN_LEN 8
@@ -119,8 +119,6 @@ struct private_ike_p2p_t {
};
-// -----------------------------------------------------------------------------
-
/**
* Adds a list of endpoints as notifies to a given message
*/
@@ -146,7 +144,7 @@ static void gather_and_add_endpoints(private_ike_p2p_t *this, message_t *message
host_t *addr, *host;
u_int16_t port;
- // get the port that is used to communicate with the ms
+ /* get the port that is used to communicate with the ms */
host = this->ike_sa->get_my_host(this->ike_sa);
port = host->get_port(host);
@@ -215,7 +213,8 @@ static void process_payloads(private_ike_p2p_t *this, message_t *message)
DBG1(DBG_IKE, "received invalid P2P_ENDPOINT notify");
break;
}
- DBG2(DBG_IKE, "received P2P_ENDPOINT notify");
+ DBG1(DBG_IKE, "received %N P2P_ENDPOINT %#H", p2p_endpoint_type_names,
+ endpoint->get_type(endpoint), endpoint->get_host(endpoint));
this->remote_endpoints->insert_last(this->remote_endpoints, endpoint);
break;
@@ -253,8 +252,6 @@ static void process_payloads(private_ike_p2p_t *this, message_t *message)
iterator->destroy(iterator);
}
-// -----------------------------------------------------------------------------
-
/**
* Implementation of task_t.process for initiator
*/
@@ -296,8 +293,8 @@ static status_t build_i(private_ike_p2p_t *this, message_t *message)
if (!this->response)
{
- // only the initiator creates a session ID. the responder returns
- // the session ID that it received from the initiator
+ /* only the initiator creates a session ID. the responder returns
+ * the session ID that it received from the initiator */
if (rand->allocate_pseudo_random_bytes(rand,
P2P_SESSIONID_LEN, &this->session_id) != SUCCESS)
{
@@ -326,7 +323,7 @@ static status_t build_i(private_ike_p2p_t *this, message_t *message)
}
else
{
- // FIXME: should we make that configurable
+ /* FIXME: should we make that configurable */
message->add_notify(message, FALSE, P2P_CALLBACK, chunk_empty);
}
@@ -334,8 +331,9 @@ static status_t build_i(private_ike_p2p_t *this, message_t *message)
break;
}
+ default:
+ break;
}
-
return NEED_MORE;
}
@@ -387,11 +385,11 @@ static status_t process_r(private_ike_p2p_t *this, message_t *message)
}
DBG1(DBG_IKE, "received P2P_CONNECT");
-
break;
}
+ default:
+ break;
}
-
return NEED_MORE;
}
@@ -420,16 +418,16 @@ static status_t build_r(private_ike_p2p_t *this, message_t *message)
if (this->response)
{
- // FIXME: handle result of set_responder_data
- // as initiator, upon receiving a response from another peer,
- // update the checklist and start sending checks
+ /* FIXME: handle result of set_responder_data
+ * as initiator, upon receiving a response from another peer,
+ * update the checklist and start sending checks */
charon->connect_manager->set_responder_data(charon->connect_manager,
this->session_id, this->session_key, this->remote_endpoints);
}
else
{
- // FIXME: handle result of set_initiator_data
- // as responder, create a checklist with the initiator's data
+ /* FIXME: handle result of set_initiator_data
+ * as responder, create a checklist with the initiator's data */
charon->connect_manager->set_initiator_data(charon->connect_manager,
this->peer_id, this->ike_sa->get_my_id(this->ike_sa),
this->session_id, this->session_key, this->remote_endpoints,
@@ -440,9 +438,10 @@ static status_t build_r(private_ike_p2p_t *this, message_t *message)
return FAILED;
}
}
-
break;
}
+ default:
+ break;
}
return SUCCESS;
}
@@ -469,20 +468,19 @@ static status_t process_i(private_ike_p2p_t *this, message_t *message)
case IKE_AUTH:
{
process_payloads(this, message);
-
- //FIXME: we should update the server reflexive endpoint somehow, if mobike notices a change
-
+ /* FIXME: we should update the server reflexive endpoint somehow,
+ * if mobike notices a change */
endpoint_notify_t *reflexive;
- if (this->remote_endpoints->get_first(this->remote_endpoints, (void**)&reflexive) == SUCCESS &&
- reflexive->get_type(reflexive) == SERVER_REFLEXIVE)
- {//FIXME: should we accept this endpoint even if we did not send a request?
+ if (this->remote_endpoints->get_first(this->remote_endpoints,
+ (void**)&reflexive) == SUCCESS &&
+ reflexive->get_type(reflexive) == SERVER_REFLEXIVE)
+ { /* FIXME: should we accept this endpoint even if we did not send
+ * a request? */
host_t *endpoint = reflexive->get_host(reflexive);
- DBG2(DBG_IKE, "received server reflexive endpoint %#H", endpoint);
this->ike_sa->set_server_reflexive_host(this->ike_sa, endpoint->clone(endpoint));
}
-
- // FIXME: what if it failed? e.g. AUTH failure
+ /* FIXME: what if it failed? e.g. AUTH failure */
SIG(CHILD_UP_SUCCESS, "established mediation connection without CHILD_SA successfully");
break;
@@ -494,22 +492,23 @@ static status_t process_i(private_ike_p2p_t *this, message_t *message)
if (this->failed)
{
DBG1(DBG_IKE, "peer '%D' is not online", this->peer_id);
- // FIXME: notify the mediated connection (job?)
- // FIXME: probably delete the created checklist, at least as responder
+ /* FIXME: notify the mediated connection (job?)
+ * FIXME: probably delete the created checklist, at least as
+ * responder */
}
else
{
if (this->response)
{
- // FIXME: handle result of set_responder_data
- // as responder, we update the checklist and start sending checks
+ /* FIXME: handle result of set_responder_data.
+ * as responder, we update the checklist and start sending checks */
charon->connect_manager->set_responder_data(charon->connect_manager,
this->session_id, this->session_key, this->local_endpoints);
}
else
{
- // FIXME: handle result of set_initiator_data
- // as initiator, we create a checklist and set the initiator's data
+ /* FIXME: handle result of set_initiator_data
+ * as initiator, we create a checklist and set the initiator's data */
charon->connect_manager->set_initiator_data(charon->connect_manager,
this->ike_sa->get_my_id(this->ike_sa), this->peer_id,
this->session_id, this->session_key, this->local_endpoints,
@@ -518,12 +517,12 @@ static status_t process_i(private_ike_p2p_t *this, message_t *message)
}
break;
}
+ default:
+ break;
}
return SUCCESS;
}
-// -----------------------------------------------------------------------------
-
/**
* Implementation of task_t.process for initiator (mediation server)
*/
@@ -542,21 +541,19 @@ static status_t build_i_ms(private_ike_p2p_t *this, message_t *message)
}
else
{
- notify_payload_t *notify;
-
if (this->response)
{
message->add_notify(message, FALSE, P2P_RESPONSE, chunk_empty);
- }
-
+ }
message->add_notify(message, FALSE, P2P_SESSIONID, this->session_id);
message->add_notify(message, FALSE, P2P_SESSIONKEY, this->session_key);
add_endpoints_to_message(message, this->remote_endpoints);
}
-
break;
}
+ default:
+ break;
}
return NEED_MORE;
@@ -614,9 +611,10 @@ static status_t process_r_ms(private_ike_p2p_t *this, message_t *message)
this->invalid_syntax = TRUE;
break;
}
-
break;
}
+ default:
+ break;
}
return NEED_MORE;
@@ -679,7 +677,7 @@ static status_t build_r_ms(private_ike_p2p_t *this, message_t *message)
if (!peer_sa)
{
- // the peer is not online
+ /* the peer is not online */
message->add_notify(message, TRUE, P2P_CONNECT_FAILED, chunk_empty);
break;
}
@@ -691,6 +689,8 @@ static status_t build_r_ms(private_ike_p2p_t *this, message_t *message)
break;
}
+ default:
+ break;
}
return SUCCESS;
}
@@ -700,18 +700,9 @@ static status_t build_r_ms(private_ike_p2p_t *this, message_t *message)
*/
static status_t process_i_ms(private_ike_p2p_t *this, message_t *message)
{
- switch(message->get_exchange_type(message))
- {
- case P2P_CONNECT:
- {
- break;
- }
- }
return SUCCESS;
}
-// -----------------------------------------------------------------------------
-
/**
* Implementation of ike_p2p.connect
*/
@@ -813,7 +804,7 @@ ike_p2p_t *ike_p2p_create(ike_sa_t *ike_sa, bool initiator)
}
else
{
- // mediation server
+ /* mediation server */
if (initiator)
{
this->public.task.build = (status_t(*)(task_t*,message_t*))build_i_ms;
diff --git a/src/charon/sa/tasks/task.c b/src/charon/sa/tasks/task.c
index e9d0c4da1..cc20a8861 100644
--- a/src/charon/sa/tasks/task.c
+++ b/src/charon/sa/tasks/task.c
@@ -28,6 +28,7 @@ ENUM(task_type_names, IKE_INIT, CHILD_REKEY,
"IKE_NATD",
"IKE_MOBIKE",
"IKE_AUTHENTICATE",
+ "IKE_AUTH_LIFETIME",
"IKE_CERT",
"IKE_CONFIG",
"IKE_REKEY",
diff --git a/src/charon/sa/tasks/task.h b/src/charon/sa/tasks/task.h
index dd2bb8a83..a59207711 100644
--- a/src/charon/sa/tasks/task.h
+++ b/src/charon/sa/tasks/task.h
@@ -45,6 +45,8 @@ enum task_type_t {
IKE_MOBIKE,
/** authenticate the initiated IKE_SA */
IKE_AUTHENTICATE,
+ /** AUTH_LIFETIME negotiation, RFC4478 */
+ IKE_AUTH_LIFETIME,
/** exchange certificates and requests */
IKE_CERT,
/** Configuration payloads, virtual IP and such */