implemented RFC4478 (repeated authentication)
changed %V printf handler to take a time delta, %#V now takes two arguments
This commit is contained in:
parent
7b36b734a4
commit
ee61471113
|
@ -188,13 +188,13 @@ static peer_cfg_t *process_peer_cfg_row(private_sqlite_backend_t *this,
|
||||||
sqlite3_column_int(stmt, 5), /* auth_method */
|
sqlite3_column_int(stmt, 5), /* auth_method */
|
||||||
sqlite3_column_int(stmt, 6), /* eap_type */
|
sqlite3_column_int(stmt, 6), /* eap_type */
|
||||||
sqlite3_column_int(stmt, 7), /* keyingtries */
|
sqlite3_column_int(stmt, 7), /* keyingtries */
|
||||||
sqlite3_column_int(stmt, 8), /* lifetime */
|
sqlite3_column_int(stmt, 8), /* rekey_time */
|
||||||
sqlite3_column_int(stmt, 9), /* rekeytime */
|
sqlite3_column_int(stmt, 9), /* reauth_time */
|
||||||
sqlite3_column_int(stmt, 10), /* jitter */
|
sqlite3_column_int(stmt, 10), /* jitter_time */
|
||||||
sqlite3_column_int(stmt, 13), /* reauth */
|
sqlite3_column_int(stmt, 11), /* over_time */
|
||||||
sqlite3_column_int(stmt, 14), /* mobike */
|
sqlite3_column_int(stmt, 14), /* mobike */
|
||||||
sqlite3_column_int(stmt, 11), /* dpd_delay */
|
sqlite3_column_int(stmt, 12), /* dpd_delay */
|
||||||
sqlite3_column_int(stmt, 12), /* dpd_action */
|
sqlite3_column_int(stmt, 13), /* dpd_action */
|
||||||
local_vip, remote_vip, FALSE, NULL, NULL);
|
local_vip, remote_vip, FALSE, NULL, NULL);
|
||||||
add_children(this, peer_cfg, sqlite3_column_int(stmt, 0));
|
add_children(this, peer_cfg, sqlite3_column_int(stmt, 0));
|
||||||
return peer_cfg;
|
return peer_cfg;
|
||||||
|
@ -225,8 +225,9 @@ static peer_cfg_t *get_peer_cfg(private_sqlite_backend_t *this,
|
||||||
|
|
||||||
if (sqlite3_prepare_v2(this->db,
|
if (sqlite3_prepare_v2(this->db,
|
||||||
"SELECT peer_configs.oid, name, local_id, remote_id, cert_policy, "
|
"SELECT peer_configs.oid, name, local_id, remote_id, cert_policy, "
|
||||||
"auth_method, eap_type, keyingtries, lifetime, rekeytime, jitter, "
|
"auth_method, eap_type, keyingtries, "
|
||||||
"dpd_delay, dpd_action, reauth, mobike, local_vip, remote_vip, "
|
"rekey_time, reauth_time, jitter_time, over_time, "
|
||||||
|
"dpd_delay, dpd_action, mobike, local_vip, remote_vip, "
|
||||||
"local, remote, certreq "
|
"local, remote, certreq "
|
||||||
"FROM peer_configs, ike_configs "
|
"FROM peer_configs, ike_configs "
|
||||||
"ON peer_configs.ike_cfg = ike_configs.oid "
|
"ON peer_configs.ike_cfg = ike_configs.oid "
|
||||||
|
|
|
@ -131,31 +131,30 @@ struct private_peer_cfg_t {
|
||||||
*/
|
*/
|
||||||
u_int32_t keyingtries;
|
u_int32_t keyingtries;
|
||||||
|
|
||||||
/**
|
|
||||||
* user reauthentication instead of rekeying
|
|
||||||
*/
|
|
||||||
bool use_reauth;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enable support for MOBIKE
|
* enable support for MOBIKE
|
||||||
*/
|
*/
|
||||||
bool use_mobike;
|
bool use_mobike;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Time before an SA gets invalid
|
* Time before starting rekeying
|
||||||
*/
|
*/
|
||||||
u_int32_t lifetime;
|
u_int32_t rekey_time;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Time before an SA gets rekeyed
|
* Time before starting reauthentication
|
||||||
*/
|
*/
|
||||||
u_int32_t rekeytime;
|
u_int32_t reauth_time;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Time, which specifies the range of a random value
|
* Time, which specifies the range of a random value substracted from above.
|
||||||
* substracted from lifetime.
|
|
||||||
*/
|
*/
|
||||||
u_int32_t jitter;
|
u_int32_t jitter_time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delay before deleting a rekeying/reauthenticating SA
|
||||||
|
*/
|
||||||
|
u_int32_t over_time;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* What to do with an SA when other peer seams to be dead?
|
* What to do with an SA when other peer seams to be dead?
|
||||||
|
@ -353,29 +352,45 @@ static u_int32_t get_keyingtries(private_peer_cfg_t *this)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of peer_cfg_t.get_soft_lifetime
|
* Implementation of peer_cfg_t.get_rekey_time.
|
||||||
*/
|
*/
|
||||||
static u_int32_t get_lifetime(private_peer_cfg_t *this, bool rekey)
|
static u_int32_t get_rekey_time(private_peer_cfg_t *this)
|
||||||
{
|
{
|
||||||
if (rekey)
|
if (this->rekey_time == 0)
|
||||||
{
|
{
|
||||||
if (this->jitter == 0)
|
return 0;
|
||||||
{
|
|
||||||
return this->rekeytime;
|
|
||||||
}
|
|
||||||
return this->rekeytime - (random() % this->jitter);
|
|
||||||
}
|
}
|
||||||
return this->lifetime;
|
if (this->jitter_time == 0)
|
||||||
|
{
|
||||||
|
return this->rekey_time;
|
||||||
|
}
|
||||||
|
return this->rekey_time - (random() % this->jitter_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of peer_cfg_t.use_reauth.
|
* Implementation of peer_cfg_t.get_reauth_time.
|
||||||
*/
|
*/
|
||||||
static bool use_reauth(private_peer_cfg_t *this)
|
static u_int32_t get_reauth_time(private_peer_cfg_t *this)
|
||||||
{
|
{
|
||||||
return this->use_reauth;
|
if (this->reauth_time == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (this->jitter_time == 0)
|
||||||
|
{
|
||||||
|
return this->reauth_time;
|
||||||
|
}
|
||||||
|
return this->reauth_time - (random() % this->jitter_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of peer_cfg_t.get_over_time.
|
||||||
|
*/
|
||||||
|
static u_int32_t get_over_time(private_peer_cfg_t *this)
|
||||||
|
{
|
||||||
|
return this->over_time;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of peer_cfg_t.use_mobike.
|
* Implementation of peer_cfg_t.use_mobike.
|
||||||
*/
|
*/
|
||||||
|
@ -503,9 +518,9 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
|
||||||
identification_t *my_ca, identification_t *other_ca,
|
identification_t *my_ca, identification_t *other_ca,
|
||||||
linked_list_t *groups, cert_policy_t cert_policy,
|
linked_list_t *groups, cert_policy_t cert_policy,
|
||||||
auth_method_t auth_method, eap_type_t eap_type,
|
auth_method_t auth_method, eap_type_t eap_type,
|
||||||
u_int32_t keyingtries, u_int32_t lifetime,
|
u_int32_t keyingtries, u_int32_t rekey_time,
|
||||||
u_int32_t rekeytime, u_int32_t jitter,
|
u_int32_t reauth_time, u_int32_t jitter_time,
|
||||||
bool reauth, bool mobike,
|
u_int32_t over_time, bool mobike,
|
||||||
u_int32_t dpd_delay, dpd_action_t dpd_action,
|
u_int32_t dpd_delay, dpd_action_t dpd_action,
|
||||||
host_t *my_virtual_ip, host_t *other_virtual_ip,
|
host_t *my_virtual_ip, host_t *other_virtual_ip,
|
||||||
bool p2p_mediation, peer_cfg_t *p2p_mediated_by,
|
bool p2p_mediation, peer_cfg_t *p2p_mediated_by,
|
||||||
|
@ -529,8 +544,9 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
|
||||||
this->public.get_auth_method = (auth_method_t (*) (peer_cfg_t *))get_auth_method;
|
this->public.get_auth_method = (auth_method_t (*) (peer_cfg_t *))get_auth_method;
|
||||||
this->public.get_eap_type = (eap_type_t (*) (peer_cfg_t *))get_eap_type;
|
this->public.get_eap_type = (eap_type_t (*) (peer_cfg_t *))get_eap_type;
|
||||||
this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries;
|
this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries;
|
||||||
this->public.get_lifetime = (u_int32_t (*) (peer_cfg_t *, bool rekey))get_lifetime;
|
this->public.get_rekey_time = (u_int32_t(*)(peer_cfg_t*))get_rekey_time;
|
||||||
this->public.use_reauth = (bool (*) (peer_cfg_t *))use_reauth;
|
this->public.get_reauth_time = (u_int32_t(*)(peer_cfg_t*))get_reauth_time;
|
||||||
|
this->public.get_over_time = (u_int32_t(*)(peer_cfg_t*))get_over_time;
|
||||||
this->public.use_mobike = (bool (*) (peer_cfg_t *))use_mobike;
|
this->public.use_mobike = (bool (*) (peer_cfg_t *))use_mobike;
|
||||||
this->public.get_dpd_delay = (u_int32_t (*) (peer_cfg_t *))get_dpd_delay;
|
this->public.get_dpd_delay = (u_int32_t (*) (peer_cfg_t *))get_dpd_delay;
|
||||||
this->public.get_dpd_action = (dpd_action_t (*) (peer_cfg_t *))get_dpd_action;
|
this->public.get_dpd_action = (dpd_action_t (*) (peer_cfg_t *))get_dpd_action;
|
||||||
|
@ -559,10 +575,18 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
|
||||||
this->auth_method = auth_method;
|
this->auth_method = auth_method;
|
||||||
this->eap_type = eap_type;
|
this->eap_type = eap_type;
|
||||||
this->keyingtries = keyingtries;
|
this->keyingtries = keyingtries;
|
||||||
this->lifetime = lifetime;
|
this->rekey_time = rekey_time;
|
||||||
this->rekeytime = rekeytime;
|
this->reauth_time = reauth_time;
|
||||||
this->jitter = jitter;
|
if (rekey_time && jitter_time > rekey_time)
|
||||||
this->use_reauth = reauth;
|
{
|
||||||
|
jitter_time = rekey_time;
|
||||||
|
}
|
||||||
|
if (reauth_time && jitter_time > reauth_time)
|
||||||
|
{
|
||||||
|
jitter_time = reauth_time;
|
||||||
|
}
|
||||||
|
this->jitter_time = jitter_time;
|
||||||
|
this->over_time = over_time;
|
||||||
this->use_mobike = mobike;
|
this->use_mobike = mobike;
|
||||||
this->dpd_delay = dpd_delay;
|
this->dpd_delay = dpd_delay;
|
||||||
this->dpd_action = dpd_action;
|
this->dpd_action = dpd_action;
|
||||||
|
|
|
@ -244,27 +244,28 @@ struct peer_cfg_t {
|
||||||
u_int32_t (*get_keyingtries) (peer_cfg_t *this);
|
u_int32_t (*get_keyingtries) (peer_cfg_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the lifetime of a IKE_SA.
|
* @brief Get a time to start rekeying (is randomized with jitter).
|
||||||
*
|
*
|
||||||
* If "rekey" is set to TRUE, a lifetime is returned before the first
|
* @param this calling object
|
||||||
* rekeying should be started. If it is FALSE, the actual lifetime is
|
* @return time in s when to start rekeying, 0 disables rekeying
|
||||||
* returned when the IKE_SA must be deleted.
|
|
||||||
* The rekey time automatically contains a jitter to avoid simlutaneous
|
|
||||||
* rekeying.
|
|
||||||
*
|
|
||||||
* @param this child_config
|
|
||||||
* @param rekey TRUE to get rekey time
|
|
||||||
* @return lifetime in seconds
|
|
||||||
*/
|
*/
|
||||||
u_int32_t (*get_lifetime) (peer_cfg_t *this, bool rekey);
|
u_int32_t (*get_rekey_time)(peer_cfg_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Should a full reauthentication be done instead of rekeying?
|
* @brief Get a time to start reauthentication (is randomized with jitter).
|
||||||
*
|
*
|
||||||
* @param this calling object
|
* @param this calling object
|
||||||
* @return TRUE to use full reauthentication
|
* @return time in s when to start reauthentication, 0 disables it
|
||||||
*/
|
*/
|
||||||
bool (*use_reauth) (peer_cfg_t *this);
|
u_int32_t (*get_reauth_time)(peer_cfg_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the timeout of a rekeying/reauthenticating SA.
|
||||||
|
*
|
||||||
|
* @param thsi calling object
|
||||||
|
* @return timeout in s
|
||||||
|
*/
|
||||||
|
u_int32_t (*get_over_time)(peer_cfg_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Use MOBIKE (RFC4555) if peer supports it?
|
* @brief Use MOBIKE (RFC4555) if peer supports it?
|
||||||
|
@ -393,9 +394,10 @@ struct peer_cfg_t {
|
||||||
* @param auth_method auth method to use to authenticate us
|
* @param auth_method auth method to use to authenticate us
|
||||||
* @param eap_type EAP type to use for peer authentication
|
* @param eap_type EAP type to use for peer authentication
|
||||||
* @param keyingtries how many keying tries should be done before giving up
|
* @param keyingtries how many keying tries should be done before giving up
|
||||||
* @param lifetime lifetime before deleting an SA
|
* @param rekey_time timeout before starting rekeying
|
||||||
* @param rekeytime lifetime before rekeying an SA
|
* @param reauth_time timeout before starting reauthentication
|
||||||
* @param jitter range of random to substract from rekeytime
|
* @param jitter_time timerange to randomly substract from rekey/reauth time
|
||||||
|
* @param over_time maximum overtime before closing a rekeying/reauth SA
|
||||||
* @param reauth sould be done reauthentication instead of rekeying?
|
* @param reauth sould be done reauthentication instead of rekeying?
|
||||||
* @param mobike use MOBIKE (RFC4555) if peer supports it
|
* @param mobike use MOBIKE (RFC4555) if peer supports it
|
||||||
* @param dpd_delay after how many seconds of inactivity to check DPD
|
* @param dpd_delay after how many seconds of inactivity to check DPD
|
||||||
|
@ -414,9 +416,9 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ikev_version, ike_cfg_t *ike_cfg,
|
||||||
identification_t *my_ca, identification_t *other_ca,
|
identification_t *my_ca, identification_t *other_ca,
|
||||||
linked_list_t *groups, cert_policy_t cert_policy,
|
linked_list_t *groups, cert_policy_t cert_policy,
|
||||||
auth_method_t auth_method, eap_type_t eap_type,
|
auth_method_t auth_method, eap_type_t eap_type,
|
||||||
u_int32_t keyingtries, u_int32_t lifetime,
|
u_int32_t keyingtries, u_int32_t rekey_time,
|
||||||
u_int32_t rekeytime, u_int32_t jitter,
|
u_int32_t reauth_time, u_int32_t jitter_time,
|
||||||
bool reauth, bool mobike,
|
u_int32_t over_time, bool mobike,
|
||||||
u_int32_t dpd_delay, dpd_action_t dpd_action,
|
u_int32_t dpd_delay, dpd_action_t dpd_action,
|
||||||
host_t *my_virtual_ip, host_t *other_virtual_ip,
|
host_t *my_virtual_ip, host_t *other_virtual_ip,
|
||||||
bool p2p_mediation, peer_cfg_t *p2p_mediated_by,
|
bool p2p_mediation, peer_cfg_t *p2p_mediated_by,
|
||||||
|
|
|
@ -611,15 +611,25 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out)
|
||||||
ike_cfg->add_proposal(ike_cfg, proposal);
|
ike_cfg->add_proposal(ike_cfg, proposal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u_int32_t rekey = 0, reauth = 0, over, jitter;
|
||||||
|
|
||||||
|
jitter = msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100;
|
||||||
|
over = msg->add_conn.rekey.margin;
|
||||||
|
if (msg->add_conn.rekey.reauth)
|
||||||
|
{
|
||||||
|
reauth = msg->add_conn.rekey.ike_lifetime - over;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rekey = msg->add_conn.rekey.ike_lifetime - over;
|
||||||
|
}
|
||||||
|
|
||||||
peer_cfg = peer_cfg_create(msg->add_conn.name, msg->add_conn.ikev2 ? 2 : 1,
|
peer_cfg = peer_cfg_create(msg->add_conn.name, msg->add_conn.ikev2 ? 2 : 1,
|
||||||
ike_cfg, my_id, other_id, my_ca, other_ca, other_groups,
|
ike_cfg, my_id, other_id, my_ca, other_ca, other_groups,
|
||||||
msg->add_conn.me.sendcert,
|
msg->add_conn.me.sendcert,
|
||||||
msg->add_conn.auth_method, msg->add_conn.eap_type,
|
msg->add_conn.auth_method, msg->add_conn.eap_type,
|
||||||
msg->add_conn.rekey.tries, msg->add_conn.rekey.ike_lifetime,
|
msg->add_conn.rekey.tries, rekey, reauth, jitter, over,
|
||||||
msg->add_conn.rekey.ike_lifetime - msg->add_conn.rekey.margin,
|
msg->add_conn.mobike,
|
||||||
msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100,
|
|
||||||
msg->add_conn.rekey.reauth, msg->add_conn.mobike,
|
|
||||||
msg->add_conn.dpd.delay, msg->add_conn.dpd.action, my_vip, other_vip,
|
msg->add_conn.dpd.delay, msg->add_conn.dpd.action, my_vip, other_vip,
|
||||||
msg->add_conn.p2p.mediation, mediated_by_cfg, peer_id);
|
msg->add_conn.p2p.mediation, mediated_by_cfg, peer_id);
|
||||||
}
|
}
|
||||||
|
@ -1102,9 +1112,8 @@ static void stroke_del_ca(stroke_msg_t *msg, FILE *out)
|
||||||
*/
|
*/
|
||||||
static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
|
static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
|
||||||
{
|
{
|
||||||
peer_cfg_t *cfg = ike_sa->get_peer_cfg(ike_sa);
|
|
||||||
ike_sa_id_t *id = ike_sa->get_id(ike_sa);
|
ike_sa_id_t *id = ike_sa->get_id(ike_sa);
|
||||||
u_int32_t next, now = time(NULL);
|
u_int32_t rekey, reauth;
|
||||||
|
|
||||||
fprintf(out, "%12s[%d]: %N, %H[%D]...%H[%D]\n",
|
fprintf(out, "%12s[%d]: %N, %H[%D]...%H[%D]\n",
|
||||||
ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
|
ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
|
||||||
|
@ -1114,21 +1123,26 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
|
||||||
|
|
||||||
if (all)
|
if (all)
|
||||||
{
|
{
|
||||||
fprintf(out, "%12s[%d]: IKE SPIs: %.16llx_i%s %.16llx_r%s, ",
|
fprintf(out, "%12s[%d]: IKE SPIs: %.16llx_i%s %.16llx_r%s",
|
||||||
ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
|
ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
|
||||||
id->get_initiator_spi(id), id->is_initiator(id) ? "*" : "",
|
id->get_initiator_spi(id), id->is_initiator(id) ? "*" : "",
|
||||||
id->get_responder_spi(id), id->is_initiator(id) ? "" : "*");
|
id->get_responder_spi(id), id->is_initiator(id) ? "" : "*");
|
||||||
|
|
||||||
ike_sa->get_stats(ike_sa, &next);
|
rekey = ike_sa->get_statistic(ike_sa, STAT_REKEY_TIME);
|
||||||
if (next)
|
reauth = ike_sa->get_statistic(ike_sa, STAT_REAUTH_TIME);
|
||||||
|
if (rekey)
|
||||||
{
|
{
|
||||||
fprintf(out, "%s in %V\n", cfg->use_reauth(cfg) ?
|
fprintf(out, ", rekeying in %V", &rekey);
|
||||||
"reauthentication" : "rekeying", &now, &next);
|
|
||||||
}
|
}
|
||||||
else
|
if (reauth)
|
||||||
{
|
{
|
||||||
fprintf(out, "rekeying disabled\n");
|
fprintf(out, ", reauthentication in %V", &reauth);
|
||||||
}
|
}
|
||||||
|
if (!rekey && !reauth)
|
||||||
|
{
|
||||||
|
fprintf(out, ", rekeying disabled");
|
||||||
|
}
|
||||||
|
fprintf(out, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1186,7 +1200,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
|
||||||
|
|
||||||
if (rekey)
|
if (rekey)
|
||||||
{
|
{
|
||||||
fprintf(out, "in %V", &now, &rekey);
|
fprintf(out, "in %#V", &now, &rekey);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,13 +57,9 @@ ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, UNEXPECTED_NAT_DETECTED, AUTH
|
||||||
"INVALID_SELECTORS",
|
"INVALID_SELECTORS",
|
||||||
"UNACCEPTABLE_ADDRESSES",
|
"UNACCEPTABLE_ADDRESSES",
|
||||||
"UNEXPECTED_NAT_DETECTED");
|
"UNEXPECTED_NAT_DETECTED");
|
||||||
#ifdef P2P
|
|
||||||
ENUM_NEXT(notify_type_names, P2P_CONNECT_FAILED, P2P_CONNECT_FAILED, UNEXPECTED_NAT_DETECTED,
|
ENUM_NEXT(notify_type_names, P2P_CONNECT_FAILED, P2P_CONNECT_FAILED, UNEXPECTED_NAT_DETECTED,
|
||||||
"P2P_CONNECT_FAILED");
|
"P2P_CONNECT_FAILED");
|
||||||
ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, P2P_CONNECT_FAILED,
|
ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, P2P_CONNECT_FAILED,
|
||||||
#else
|
|
||||||
ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NAT_DETECTED,
|
|
||||||
#endif /* P2P */
|
|
||||||
"INITIAL_CONTACT",
|
"INITIAL_CONTACT",
|
||||||
"SET_WINDOW_SIZE",
|
"SET_WINDOW_SIZE",
|
||||||
"ADDITIONAL_TS_POSSIBLE",
|
"ADDITIONAL_TS_POSSIBLE",
|
||||||
|
@ -86,7 +82,6 @@ ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NAT_DETE
|
||||||
"AUTH_LIFETIME");
|
"AUTH_LIFETIME");
|
||||||
ENUM_NEXT(notify_type_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, AUTH_LIFETIME,
|
ENUM_NEXT(notify_type_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, AUTH_LIFETIME,
|
||||||
"EAP_ONLY_AUTHENTICATION");
|
"EAP_ONLY_AUTHENTICATION");
|
||||||
#ifdef P2P
|
|
||||||
ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION,
|
ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION,
|
||||||
"USE_BEET_MODE");
|
"USE_BEET_MODE");
|
||||||
ENUM_NEXT(notify_type_names, P2P_MEDIATION, P2P_RESPONSE, USE_BEET_MODE,
|
ENUM_NEXT(notify_type_names, P2P_MEDIATION, P2P_RESPONSE, USE_BEET_MODE,
|
||||||
|
@ -97,9 +92,6 @@ ENUM_NEXT(notify_type_names, P2P_MEDIATION, P2P_RESPONSE, USE_BEET_MODE,
|
||||||
"P2P_SESSIONKEY",
|
"P2P_SESSIONKEY",
|
||||||
"P2P_RESPONSE");
|
"P2P_RESPONSE");
|
||||||
ENUM_END(notify_type_names, P2P_RESPONSE);
|
ENUM_END(notify_type_names, P2P_RESPONSE);
|
||||||
#else
|
|
||||||
ENUM_END(notify_type_names, EAP_ONLY_AUTHENTICATION);
|
|
||||||
#endif /* P2P */
|
|
||||||
|
|
||||||
|
|
||||||
ENUM_BEGIN(notify_type_short_names, UNSUPPORTED_CRITICAL_PAYLOAD, UNSUPPORTED_CRITICAL_PAYLOAD,
|
ENUM_BEGIN(notify_type_short_names, UNSUPPORTED_CRITICAL_PAYLOAD, UNSUPPORTED_CRITICAL_PAYLOAD,
|
||||||
|
@ -128,13 +120,9 @@ ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, UNEXPECTED_NAT_DETECTED
|
||||||
"INVAL_SEL",
|
"INVAL_SEL",
|
||||||
"UNACCEPT_ADDR",
|
"UNACCEPT_ADDR",
|
||||||
"UNEXPECT_NAT");
|
"UNEXPECT_NAT");
|
||||||
#ifdef P2P
|
|
||||||
ENUM_NEXT(notify_type_short_names, P2P_CONNECT_FAILED, P2P_CONNECT_FAILED, UNEXPECTED_NAT_DETECTED,
|
ENUM_NEXT(notify_type_short_names, P2P_CONNECT_FAILED, P2P_CONNECT_FAILED, UNEXPECTED_NAT_DETECTED,
|
||||||
"P2P_CONN_FAIL");
|
"P2P_CONN_FAIL");
|
||||||
ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, AUTH_LIFETIME, P2P_CONNECT_FAILED,
|
ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, AUTH_LIFETIME, P2P_CONNECT_FAILED,
|
||||||
#else
|
|
||||||
ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NAT_DETECTED,
|
|
||||||
#endif /* P2P */
|
|
||||||
"INIT_CONTACT",
|
"INIT_CONTACT",
|
||||||
"SET_WINSIZE",
|
"SET_WINSIZE",
|
||||||
"ADD_TS_POSS",
|
"ADD_TS_POSS",
|
||||||
|
@ -157,7 +145,6 @@ ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NA
|
||||||
"AUTH_LFT");
|
"AUTH_LFT");
|
||||||
ENUM_NEXT(notify_type_short_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, AUTH_LIFETIME,
|
ENUM_NEXT(notify_type_short_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, AUTH_LIFETIME,
|
||||||
"EAP_ONLY");
|
"EAP_ONLY");
|
||||||
#ifdef P2P
|
|
||||||
ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION,
|
ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION,
|
||||||
"BEET_MODE");
|
"BEET_MODE");
|
||||||
ENUM_NEXT(notify_type_short_names, P2P_MEDIATION, P2P_RESPONSE, USE_BEET_MODE,
|
ENUM_NEXT(notify_type_short_names, P2P_MEDIATION, P2P_RESPONSE, USE_BEET_MODE,
|
||||||
|
@ -168,9 +155,6 @@ ENUM_NEXT(notify_type_short_names, P2P_MEDIATION, P2P_RESPONSE, USE_BEET_MODE,
|
||||||
"P2P_SKEY",
|
"P2P_SKEY",
|
||||||
"P2P_R");
|
"P2P_R");
|
||||||
ENUM_END(notify_type_short_names, P2P_RESPONSE);
|
ENUM_END(notify_type_short_names, P2P_RESPONSE);
|
||||||
#else
|
|
||||||
ENUM_END(notify_type_short_names, EAP_ONLY_AUTHENTICATION);
|
|
||||||
#endif /* P2P */
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct private_notify_payload_t private_notify_payload_t;
|
typedef struct private_notify_payload_t private_notify_payload_t;
|
||||||
|
@ -342,7 +326,15 @@ static status_t verify(private_notify_payload_t *this)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// FIXME: check size of P2P-NAT-T payloads
|
case AUTH_LIFETIME:
|
||||||
|
{
|
||||||
|
if (this->notification_data.len != 4)
|
||||||
|
{
|
||||||
|
bad_length = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* FIXME: check size of P2P-NAT-T payloads */
|
||||||
default:
|
default:
|
||||||
/* TODO: verify */
|
/* TODO: verify */
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -68,10 +68,9 @@ enum notify_type_t {
|
||||||
INVALID_SELECTORS = 39,
|
INVALID_SELECTORS = 39,
|
||||||
UNACCEPTABLE_ADDRESSES = 40,
|
UNACCEPTABLE_ADDRESSES = 40,
|
||||||
UNEXPECTED_NAT_DETECTED = 41,
|
UNEXPECTED_NAT_DETECTED = 41,
|
||||||
#ifdef P2P
|
|
||||||
/* P2P-NAT-T, private use */
|
/* P2P-NAT-T, private use */
|
||||||
P2P_CONNECT_FAILED = 8192,
|
P2P_CONNECT_FAILED = 8192,
|
||||||
#endif /* P2P */
|
|
||||||
/* notify status messages */
|
/* notify status messages */
|
||||||
INITIAL_CONTACT = 16384,
|
INITIAL_CONTACT = 16384,
|
||||||
SET_WINDOW_SIZE = 16385,
|
SET_WINDOW_SIZE = 16385,
|
||||||
|
@ -99,7 +98,6 @@ enum notify_type_t {
|
||||||
EAP_ONLY_AUTHENTICATION = 40960,
|
EAP_ONLY_AUTHENTICATION = 40960,
|
||||||
/* BEET mode, not even a draft yet. private use */
|
/* BEET mode, not even a draft yet. private use */
|
||||||
USE_BEET_MODE = 40961,
|
USE_BEET_MODE = 40961,
|
||||||
#ifdef P2P
|
|
||||||
/* P2P-NAT-T, private use */
|
/* P2P-NAT-T, private use */
|
||||||
P2P_MEDIATION = 40962,
|
P2P_MEDIATION = 40962,
|
||||||
P2P_ENDPOINT = 40963,
|
P2P_ENDPOINT = 40963,
|
||||||
|
@ -107,7 +105,6 @@ enum notify_type_t {
|
||||||
P2P_SESSIONID = 40965,
|
P2P_SESSIONID = 40965,
|
||||||
P2P_SESSIONKEY = 40966,
|
P2P_SESSIONKEY = 40966,
|
||||||
P2P_RESPONSE = 40967
|
P2P_RESPONSE = 40967
|
||||||
#endif /* P2P */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -248,6 +248,8 @@ struct private_ike_sa_t {
|
||||||
u_int32_t established;
|
u_int32_t established;
|
||||||
/** when IKE_SA gets rekeyed */
|
/** when IKE_SA gets rekeyed */
|
||||||
u_int32_t rekey;
|
u_int32_t rekey;
|
||||||
|
/** when IKE_SA gets reauthenticated */
|
||||||
|
u_int32_t reauth;
|
||||||
/** when IKE_SA gets deleted */
|
/** when IKE_SA gets deleted */
|
||||||
u_int32_t delete;
|
u_int32_t delete;
|
||||||
} time;
|
} time;
|
||||||
|
@ -307,16 +309,31 @@ static char *get_name(private_ike_sa_t *this)
|
||||||
return "(unnamed)";
|
return "(unnamed)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of ike_sa_t.get_stats.
|
* Implementation of ike_sa_t.get_statistic.
|
||||||
*/
|
*/
|
||||||
static void get_stats(private_ike_sa_t *this, u_int32_t *next_rekeying)
|
static u_int32_t get_statistic(private_ike_sa_t *this, statistic_t kind)
|
||||||
{
|
{
|
||||||
if (next_rekeying)
|
time_t now = time(NULL);
|
||||||
|
|
||||||
|
switch (kind)
|
||||||
{
|
{
|
||||||
*next_rekeying = this->time.rekey;
|
case STAT_REKEY_TIME:
|
||||||
|
if (this->time.rekey > now)
|
||||||
|
{
|
||||||
|
return this->time.rekey - now;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case STAT_REAUTH_TIME:
|
||||||
|
if (this->time.reauth > now)
|
||||||
|
{
|
||||||
|
return this->time.reauth - now;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -493,10 +510,6 @@ static void set_condition(private_ike_sa_t *this, ike_condition_t condition,
|
||||||
this->conditions |= condition;
|
this->conditions |= condition;
|
||||||
switch (condition)
|
switch (condition)
|
||||||
{
|
{
|
||||||
case COND_STALE:
|
|
||||||
DBG1(DBG_IKE, "no route to %H, setting IKE_SA to stale",
|
|
||||||
this->other_host);
|
|
||||||
break;
|
|
||||||
case COND_NAT_HERE:
|
case COND_NAT_HERE:
|
||||||
DBG1(DBG_IKE, "local host is behind NAT, sending keep alives");
|
DBG1(DBG_IKE, "local host is behind NAT, sending keep alives");
|
||||||
this->conditions |= COND_NAT_ANY;
|
this->conditions |= COND_NAT_ANY;
|
||||||
|
@ -519,9 +532,6 @@ static void set_condition(private_ike_sa_t *this, ike_condition_t condition,
|
||||||
this->conditions &= ~condition;
|
this->conditions &= ~condition;
|
||||||
switch (condition)
|
switch (condition)
|
||||||
{
|
{
|
||||||
case COND_STALE:
|
|
||||||
DBG1(DBG_IKE, "new route to %H found", this->other_host);
|
|
||||||
break;
|
|
||||||
case COND_NAT_HERE:
|
case COND_NAT_HERE:
|
||||||
case COND_NAT_FAKE:
|
case COND_NAT_FAKE:
|
||||||
case COND_NAT_THERE:
|
case COND_NAT_THERE:
|
||||||
|
@ -610,36 +620,58 @@ static void set_state(private_ike_sa_t *this, ike_sa_state_t state)
|
||||||
if (this->state == IKE_CONNECTING)
|
if (this->state == IKE_CONNECTING)
|
||||||
{
|
{
|
||||||
job_t *job;
|
job_t *job;
|
||||||
u_int32_t now = time(NULL);
|
u_int32_t t;
|
||||||
u_int32_t soft, hard;
|
|
||||||
bool reauth;
|
|
||||||
|
|
||||||
this->time.established = now;
|
/* calculate rekey, reauth and lifetime */
|
||||||
/* start DPD checks */
|
this->time.established = time(NULL);
|
||||||
send_dpd(this);
|
|
||||||
|
|
||||||
/* schedule rekeying/reauthentication */
|
/* schedule rekeying if we have a time which is smaller than
|
||||||
soft = this->peer_cfg->get_lifetime(this->peer_cfg, TRUE);
|
* an already scheduled rekeying */
|
||||||
hard = this->peer_cfg->get_lifetime(this->peer_cfg, FALSE);
|
t = this->peer_cfg->get_rekey_time(this->peer_cfg);
|
||||||
reauth = this->peer_cfg->use_reauth(this->peer_cfg);
|
if (t && (this->time.rekey == 0 ||
|
||||||
DBG1(DBG_IKE, "scheduling %s in %ds, maximum lifetime %ds",
|
(this->time.rekey > t + this->time.established)))
|
||||||
reauth ? "reauthentication": "rekeying", soft, hard);
|
|
||||||
|
|
||||||
if (soft)
|
|
||||||
{
|
{
|
||||||
this->time.rekey = now + soft;
|
this->time.rekey = t + this->time.established;
|
||||||
job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, reauth);
|
job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, FALSE);
|
||||||
charon->scheduler->schedule_job(charon->scheduler, job,
|
charon->scheduler->schedule_job(charon->scheduler,
|
||||||
soft * 1000);
|
job, t * 1000);
|
||||||
|
DBG1(DBG_IKE, "scheduling rekeying in %ds", t);
|
||||||
}
|
}
|
||||||
|
t = this->peer_cfg->get_reauth_time(this->peer_cfg);
|
||||||
if (hard)
|
if (t && (this->time.reauth == 0 ||
|
||||||
|
(this->time.reauth > t + this->time.established)))
|
||||||
{
|
{
|
||||||
this->time.delete = now + hard;
|
this->time.reauth = t + this->time.established;
|
||||||
|
job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE);
|
||||||
|
charon->scheduler->schedule_job(charon->scheduler,
|
||||||
|
job, t * 1000);
|
||||||
|
DBG1(DBG_IKE, "scheduling reauthentication in %ds", t);
|
||||||
|
}
|
||||||
|
t = this->peer_cfg->get_over_time(this->peer_cfg);
|
||||||
|
if (this->time.rekey || this->time.reauth)
|
||||||
|
{
|
||||||
|
if (this->time.reauth == 0)
|
||||||
|
{
|
||||||
|
this->time.delete = this->time.rekey;
|
||||||
|
}
|
||||||
|
else if (this->time.rekey == 0)
|
||||||
|
{
|
||||||
|
this->time.delete = this->time.reauth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->time.delete = min(this->time.rekey, this->time.reauth);
|
||||||
|
}
|
||||||
|
this->time.delete += t;
|
||||||
|
t = this->time.delete - this->time.established;
|
||||||
job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE);
|
job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE);
|
||||||
charon->scheduler->schedule_job(charon->scheduler, job,
|
charon->scheduler->schedule_job(charon->scheduler, job,
|
||||||
hard * 1000);
|
t * 1000);
|
||||||
|
DBG1(DBG_IKE, "maximum IKE_SA lifetime %ds", t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* start DPD checks */
|
||||||
|
send_dpd(this);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1902,13 +1934,58 @@ static status_t rekey(private_ike_sa_t *this)
|
||||||
static status_t reestablish(private_ike_sa_t *this)
|
static status_t reestablish(private_ike_sa_t *this)
|
||||||
{
|
{
|
||||||
task_t *task;
|
task_t *task;
|
||||||
|
|
||||||
|
/* we can't reauthenticate as responder when we use EAP or virtual IPs.
|
||||||
|
* If the peer does not support RFC4478, there is no way to keep the
|
||||||
|
* IKE_SA up. */
|
||||||
|
if (!this->ike_sa_id->is_initiator(this->ike_sa_id))
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "initiator did not reauthenticate as requested");
|
||||||
|
if (this->other_virtual_ip != NULL ||
|
||||||
|
has_condition(this, COND_EAP_AUTHENTICATED))
|
||||||
|
{
|
||||||
|
time_t now = time(NULL);
|
||||||
|
|
||||||
|
DBG1(DBG_IKE, "IKE_SA will timeout in %#V", &now, &this->time.delete);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "reauthenticating actively");
|
||||||
|
}
|
||||||
|
}
|
||||||
task = (task_t*)ike_reauth_create(&this->public);
|
task = (task_t*)ike_reauth_create(&this->public);
|
||||||
this->task_manager->queue_task(this->task_manager, task);
|
this->task_manager->queue_task(this->task_manager, task);
|
||||||
|
|
||||||
return this->task_manager->initiate(this->task_manager);
|
return this->task_manager->initiate(this->task_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of ike_sa_t.set_auth_lifetime.
|
||||||
|
*/
|
||||||
|
static void set_auth_lifetime(private_ike_sa_t *this, u_int32_t lifetime)
|
||||||
|
{
|
||||||
|
job_t *job;
|
||||||
|
u_int32_t reduction = this->peer_cfg->get_over_time(this->peer_cfg);
|
||||||
|
|
||||||
|
this->time.reauth = time(NULL) + lifetime - reduction;
|
||||||
|
job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE);
|
||||||
|
|
||||||
|
if (lifetime < reduction)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, starting reauthentication",
|
||||||
|
lifetime);
|
||||||
|
charon->processor->queue_job(charon->processor, job);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, scheduling reauthentication"
|
||||||
|
" in %ds", lifetime, lifetime - reduction);
|
||||||
|
charon->scheduler->schedule_job(charon->scheduler, job,
|
||||||
|
(lifetime - reduction) * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of ike_sa_t.roam.
|
* Implementation of ike_sa_t.roam.
|
||||||
*/
|
*/
|
||||||
|
@ -1935,7 +2012,6 @@ static status_t roam(private_ike_sa_t *this, bool address)
|
||||||
me = charon->kernel_interface->get_source_addr(charon->kernel_interface,
|
me = charon->kernel_interface->get_source_addr(charon->kernel_interface,
|
||||||
other);
|
other);
|
||||||
|
|
||||||
set_condition(this, COND_STALE, FALSE);
|
|
||||||
if (me)
|
if (me)
|
||||||
{
|
{
|
||||||
if (me->ip_equals(me, this->my_host) &&
|
if (me->ip_equals(me, this->my_host) &&
|
||||||
|
@ -2009,6 +2085,24 @@ static status_t inherit(private_ike_sa_t *this, private_ike_sa_t *other)
|
||||||
/* move pending tasks to the new IKE_SA */
|
/* move pending tasks to the new IKE_SA */
|
||||||
this->task_manager->adopt_tasks(this->task_manager, other->task_manager);
|
this->task_manager->adopt_tasks(this->task_manager, other->task_manager);
|
||||||
|
|
||||||
|
/* reauthentication timeout survives a rekeying */
|
||||||
|
if (other->time.reauth)
|
||||||
|
{
|
||||||
|
time_t reauth, delete, now = time(NULL);
|
||||||
|
|
||||||
|
this->time.reauth = other->time.reauth;
|
||||||
|
reauth = this->time.reauth - now;
|
||||||
|
delete = reauth + this->peer_cfg->get_over_time(this->peer_cfg);
|
||||||
|
this->time.delete = this->time.reauth + delete;
|
||||||
|
DBG1(DBG_IKE, "rescheduling reauthentication in %ds after rekeying, "
|
||||||
|
"lifetime reduced to %ds", reauth, delete);
|
||||||
|
charon->scheduler->schedule_job(charon->scheduler,
|
||||||
|
(job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE),
|
||||||
|
reauth * 1000);
|
||||||
|
charon->scheduler->schedule_job(charon->scheduler,
|
||||||
|
(job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE),
|
||||||
|
delete * 1000);
|
||||||
|
}
|
||||||
/* we have to initate here, there may be new tasks to handle */
|
/* we have to initate here, there may be new tasks to handle */
|
||||||
return this->task_manager->initiate(this->task_manager);
|
return this->task_manager->initiate(this->task_manager);
|
||||||
}
|
}
|
||||||
|
@ -2209,8 +2303,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
||||||
/* Public functions */
|
/* Public functions */
|
||||||
this->public.get_state = (ike_sa_state_t (*)(ike_sa_t*)) get_state;
|
this->public.get_state = (ike_sa_state_t (*)(ike_sa_t*)) get_state;
|
||||||
this->public.set_state = (void (*)(ike_sa_t*,ike_sa_state_t)) set_state;
|
this->public.set_state = (void (*)(ike_sa_t*,ike_sa_state_t)) set_state;
|
||||||
this->public.get_stats = (void (*)(ike_sa_t*,u_int32_t*))get_stats;
|
|
||||||
this->public.get_name = (char* (*)(ike_sa_t*))get_name;
|
this->public.get_name = (char* (*)(ike_sa_t*))get_name;
|
||||||
|
this->public.get_statistic = (u_int32_t(*)(ike_sa_t*, statistic_t kind))get_statistic;
|
||||||
this->public.process_message = (status_t (*)(ike_sa_t*, message_t*)) process_message;
|
this->public.process_message = (status_t (*)(ike_sa_t*, message_t*)) process_message;
|
||||||
this->public.initiate = (status_t (*)(ike_sa_t*,child_cfg_t*)) initiate;
|
this->public.initiate = (status_t (*)(ike_sa_t*,child_cfg_t*)) initiate;
|
||||||
this->public.route = (status_t (*)(ike_sa_t*,child_cfg_t*)) route;
|
this->public.route = (status_t (*)(ike_sa_t*,child_cfg_t*)) route;
|
||||||
|
@ -2258,6 +2352,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
||||||
this->public.destroy_child_sa = (status_t (*)(ike_sa_t*,protocol_id_t,u_int32_t))destroy_child_sa;
|
this->public.destroy_child_sa = (status_t (*)(ike_sa_t*,protocol_id_t,u_int32_t))destroy_child_sa;
|
||||||
this->public.rekey = (status_t (*)(ike_sa_t*))rekey;
|
this->public.rekey = (status_t (*)(ike_sa_t*))rekey;
|
||||||
this->public.reestablish = (status_t (*)(ike_sa_t*))reestablish;
|
this->public.reestablish = (status_t (*)(ike_sa_t*))reestablish;
|
||||||
|
this->public.set_auth_lifetime = (void(*)(ike_sa_t*, u_int32_t lifetime))set_auth_lifetime;
|
||||||
this->public.roam = (status_t(*)(ike_sa_t*,bool))roam;
|
this->public.roam = (status_t(*)(ike_sa_t*,bool))roam;
|
||||||
this->public.inherit = (status_t (*)(ike_sa_t*,ike_sa_t*))inherit;
|
this->public.inherit = (status_t (*)(ike_sa_t*,ike_sa_t*))inherit;
|
||||||
this->public.generate_message = (status_t (*)(ike_sa_t*,message_t*,packet_t**))generate_message;
|
this->public.generate_message = (status_t (*)(ike_sa_t*,message_t*,packet_t**))generate_message;
|
||||||
|
@ -2298,6 +2393,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
||||||
this->time.inbound = this->time.outbound = time(NULL);
|
this->time.inbound = this->time.outbound = time(NULL);
|
||||||
this->time.established = 0;
|
this->time.established = 0;
|
||||||
this->time.rekey = 0;
|
this->time.rekey = 0;
|
||||||
|
this->time.reauth = 0;
|
||||||
this->time.delete = 0;
|
this->time.delete = 0;
|
||||||
this->ike_cfg = NULL;
|
this->ike_cfg = NULL;
|
||||||
this->peer_cfg = NULL;
|
this->peer_cfg = NULL;
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
typedef enum ike_extension_t ike_extension_t;
|
typedef enum ike_extension_t ike_extension_t;
|
||||||
typedef enum ike_condition_t ike_condition_t;
|
typedef enum ike_condition_t ike_condition_t;
|
||||||
typedef enum ike_sa_state_t ike_sa_state_t;
|
typedef enum ike_sa_state_t ike_sa_state_t;
|
||||||
|
typedef enum statistic_t statistic_t;
|
||||||
typedef struct ike_sa_t ike_sa_t;
|
typedef struct ike_sa_t ike_sa_t;
|
||||||
|
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
|
@ -115,9 +116,25 @@ enum ike_condition_t {
|
||||||
COND_NAT_FAKE = (1<<3),
|
COND_NAT_FAKE = (1<<3),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* peer is currently not reachable (due missing route, ...)
|
* peer has ben authenticated using EAP
|
||||||
*/
|
*/
|
||||||
COND_STALE = (1<<4),
|
COND_EAP_AUTHENTICATED = (1<<4),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information and statistics to query from an SA
|
||||||
|
*/
|
||||||
|
enum statistic_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Relative time for scheduled rekeying
|
||||||
|
*/
|
||||||
|
STAT_REKEY_TIME,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Relative time for scheduled reauthentication
|
||||||
|
*/
|
||||||
|
STAT_REAUTH_TIME,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -233,13 +250,6 @@ struct ike_sa_t {
|
||||||
*/
|
*/
|
||||||
ike_sa_state_t (*get_state) (ike_sa_t *this);
|
ike_sa_state_t (*get_state) (ike_sa_t *this);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get some statistics about this IKE_SA.
|
|
||||||
*
|
|
||||||
* @param next_rekeying when the next rekeying is scheduled
|
|
||||||
*/
|
|
||||||
void (*get_stats)(ike_sa_t *this, u_int32_t *next_rekeying);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the state of the IKE_SA.
|
* @brief Set the state of the IKE_SA.
|
||||||
*
|
*
|
||||||
|
@ -256,6 +266,15 @@ struct ike_sa_t {
|
||||||
*/
|
*/
|
||||||
char* (*get_name) (ike_sa_t *this);
|
char* (*get_name) (ike_sa_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get statistic values from the IKE_SA.
|
||||||
|
*
|
||||||
|
* @param this calling object
|
||||||
|
* @param kind kind of requested value
|
||||||
|
* @return value as integer
|
||||||
|
*/
|
||||||
|
u_int32_t (*get_statistic)(ike_sa_t *this, statistic_t kind);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the own host address.
|
* @brief Get the own host address.
|
||||||
*
|
*
|
||||||
|
@ -845,6 +864,14 @@ struct ike_sa_t {
|
||||||
*/
|
*/
|
||||||
status_t (*reestablish) (ike_sa_t *this);
|
status_t (*reestablish) (ike_sa_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the lifetime limit received from a AUTH_LIFETIME notify.
|
||||||
|
*
|
||||||
|
* @param this calling object
|
||||||
|
* @param lifetime lifetime in seconds
|
||||||
|
*/
|
||||||
|
void (*set_auth_lifetime)(ike_sa_t *this, u_int32_t lifetime);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the virtual IP to use for this IKE_SA and its children.
|
* @brief Set the virtual IP to use for this IKE_SA and its children.
|
||||||
*
|
*
|
||||||
|
|
|
@ -777,6 +777,13 @@ static status_t process_request(private_task_manager_t *this,
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
case AUTH_LIFETIME:
|
||||||
|
{ /* hackish: a separate task would be overkill here */
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,6 +297,23 @@ static status_t collect_other_init_data(private_ike_auth_t *this, message_t *mes
|
||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add the AUTH_LIFETIME notify to the message
|
||||||
|
*/
|
||||||
|
static void add_auth_lifetime(private_ike_auth_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of task_t.build to create AUTH payload from EAP data
|
* Implementation of task_t.build to create AUTH payload from EAP data
|
||||||
*/
|
*/
|
||||||
|
@ -326,6 +343,7 @@ static status_t build_auth_eap(private_ike_auth_t *this, message_t *message)
|
||||||
this->ike_sa->get_my_host(this->ike_sa),
|
this->ike_sa->get_my_host(this->ike_sa),
|
||||||
this->ike_sa->get_other_host(this->ike_sa),
|
this->ike_sa->get_other_host(this->ike_sa),
|
||||||
this->ike_sa->get_other_id(this->ike_sa));
|
this->ike_sa->get_other_id(this->ike_sa));
|
||||||
|
add_auth_lifetime(this, message);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
|
@ -520,6 +538,7 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
|
||||||
break;
|
break;
|
||||||
case NOT_FOUND:
|
case NOT_FOUND:
|
||||||
/* use EAP if no AUTH payload 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);
|
this->eap_auth = eap_authenticator_create(this->ike_sa);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -581,6 +600,7 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
|
||||||
this->ike_sa->get_my_host(this->ike_sa),
|
this->ike_sa->get_my_host(this->ike_sa),
|
||||||
this->ike_sa->get_other_host(this->ike_sa),
|
this->ike_sa->get_other_host(this->ike_sa),
|
||||||
this->ike_sa->get_other_id(this->ike_sa));
|
this->ike_sa->get_other_id(this->ike_sa));
|
||||||
|
add_auth_lifetime(this, message);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -645,6 +665,13 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
|
||||||
case ADDITIONAL_IP6_ADDRESS:
|
case ADDITIONAL_IP6_ADDRESS:
|
||||||
/* handled in ike_mobike task */
|
/* handled in ike_mobike task */
|
||||||
break;
|
break;
|
||||||
|
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:
|
default:
|
||||||
{
|
{
|
||||||
if (type < 16383)
|
if (type < 16383)
|
||||||
|
|
|
@ -544,7 +544,7 @@ static void list(const private_x509ac_t *this, FILE *out, bool utc)
|
||||||
fprintf(out, " validity: not before %#T, ", &this->notBefore, utc);
|
fprintf(out, " validity: not before %#T, ", &this->notBefore, utc);
|
||||||
if (now < this->notBefore)
|
if (now < this->notBefore)
|
||||||
{
|
{
|
||||||
fprintf(out, "not valid yet (valid in %V)\n", &now, &this->notBefore);
|
fprintf(out, "not valid yet (valid in %#V)\n", &now, &this->notBefore);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -554,14 +554,14 @@ static void list(const private_x509ac_t *this, FILE *out, bool utc)
|
||||||
fprintf(out, " not after %#T, ", &this->notAfter, utc);
|
fprintf(out, " not after %#T, ", &this->notAfter, utc);
|
||||||
if (now > this->notAfter)
|
if (now > this->notAfter)
|
||||||
{
|
{
|
||||||
fprintf(out, "expired (%V ago)\n", &now, &this->notAfter);
|
fprintf(out, "expired (%#V ago)\n", &now, &this->notAfter);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(out, "ok");
|
fprintf(out, "ok");
|
||||||
if (now > this->notAfter - ACERT_WARNING_INTERVAL * 60 * 60 * 24)
|
if (now > this->notAfter - ACERT_WARNING_INTERVAL * 60 * 60 * 24)
|
||||||
{
|
{
|
||||||
fprintf(out, " (expires in %V)", &now, &this->notAfter);
|
fprintf(out, " (expires in %#V)", &now, &this->notAfter);
|
||||||
}
|
}
|
||||||
fprintf(out, " \n");
|
fprintf(out, " \n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,11 +279,11 @@ static void list_certinfos(private_ca_info_t *this, FILE *out, bool utc)
|
||||||
fprintf(out, "%#T, until %#T, ", &thisUpdate, utc, &nextUpdate, utc);
|
fprintf(out, "%#T, until %#T, ", &thisUpdate, utc, &nextUpdate, utc);
|
||||||
if (now > nextUpdate)
|
if (now > nextUpdate)
|
||||||
{
|
{
|
||||||
fprintf(out, "expired (%V ago)\n", &now, &nextUpdate);
|
fprintf(out, "expired (%#V ago)\n", &now, &nextUpdate);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(out, "ok (expires in %V)\n", &now, &nextUpdate);
|
fprintf(out, "ok (expires in %#V)\n", &now, &nextUpdate);
|
||||||
}
|
}
|
||||||
fprintf(out, " serial: %#B, %N\n", &serial,
|
fprintf(out, " serial: %#B, %N\n", &serial,
|
||||||
cert_status_names, certinfo->get_status(certinfo));
|
cert_status_names, certinfo->get_status(certinfo));
|
||||||
|
|
|
@ -463,11 +463,11 @@ static void list(private_crl_t *this, FILE* out, bool utc)
|
||||||
}
|
}
|
||||||
else if (now > this->nextUpdate)
|
else if (now > this->nextUpdate)
|
||||||
{
|
{
|
||||||
fprintf(out, "expired (%V ago)\n", &now, &this->nextUpdate);
|
fprintf(out, "expired (%#V ago)\n", &now, &this->nextUpdate);
|
||||||
}
|
}
|
||||||
else if (now > this->nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24)
|
else if (now > this->nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24)
|
||||||
{
|
{
|
||||||
fprintf(out, "ok (expires in %V)\n", &now, &this->nextUpdate);
|
fprintf(out, "ok (expires in %#V)\n", &now, &this->nextUpdate);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1182,7 +1182,7 @@ static void list(private_x509_t *this, FILE *out, bool utc)
|
||||||
fprintf(out, " validity: not before %#T, ", &this->notBefore, utc);
|
fprintf(out, " validity: not before %#T, ", &this->notBefore, utc);
|
||||||
if (now < this->notBefore)
|
if (now < this->notBefore)
|
||||||
{
|
{
|
||||||
fprintf(out, "not valid yet (valid in %V)\n", &now, &this->notBefore);
|
fprintf(out, "not valid yet (valid in %#V)\n", &now, &this->notBefore);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1192,14 +1192,14 @@ static void list(private_x509_t *this, FILE *out, bool utc)
|
||||||
fprintf(out, " not after %#T, ", &this->notAfter, utc);
|
fprintf(out, " not after %#T, ", &this->notAfter, utc);
|
||||||
if (now > this->notAfter)
|
if (now > this->notAfter)
|
||||||
{
|
{
|
||||||
fprintf(out, "expired (%V ago)\n", &now, &this->notAfter);
|
fprintf(out, "expired (%#V ago)\n", &now, &this->notAfter);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(out, "ok");
|
fprintf(out, "ok");
|
||||||
if (now > this->notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24)
|
if (now > this->notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24)
|
||||||
{
|
{
|
||||||
fprintf(out, " (expires in %V)", &now, &this->notAfter);
|
fprintf(out, " (expires in %#V)", &now, &this->notAfter);
|
||||||
}
|
}
|
||||||
fprintf(out, " \n");
|
fprintf(out, " \n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,11 +150,20 @@ static int print_time(FILE *stream, const struct printf_info *info,
|
||||||
static int print_time_delta(FILE *stream, const struct printf_info *info,
|
static int print_time_delta(FILE *stream, const struct printf_info *info,
|
||||||
const void *const *args)
|
const void *const *args)
|
||||||
{
|
{
|
||||||
time_t *start = *((time_t**)(args[0]));
|
|
||||||
time_t *end = *((time_t**)(args[1]));
|
|
||||||
u_int delta = abs(*end - *start);
|
|
||||||
|
|
||||||
char* unit = "second";
|
char* unit = "second";
|
||||||
|
time_t *arg1, *arg2;
|
||||||
|
time_t delta;
|
||||||
|
|
||||||
|
arg1 = *((time_t**)(args[0]));
|
||||||
|
if (info->alt)
|
||||||
|
{
|
||||||
|
arg2 = *((time_t**)(args[1]));
|
||||||
|
delta = abs(*arg1 - *arg2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delta = *arg1;
|
||||||
|
}
|
||||||
|
|
||||||
if (delta > 2 * 60 * 60 * 24)
|
if (delta > 2 * 60 * 60 * 24)
|
||||||
{
|
{
|
||||||
|
@ -180,5 +189,5 @@ static int print_time_delta(FILE *stream, const struct printf_info *info,
|
||||||
static void __attribute__ ((constructor))print_register()
|
static void __attribute__ ((constructor))print_register()
|
||||||
{
|
{
|
||||||
register_printf_function(PRINTF_TIME, print_time, arginfo_ptr_alt_ptr_int);
|
register_printf_function(PRINTF_TIME, print_time, arginfo_ptr_alt_ptr_int);
|
||||||
register_printf_function(PRINTF_TIME_DELTA, print_time_delta, arginfo_ptr_ptr);
|
register_printf_function(PRINTF_TIME_DELTA, print_time_delta, arginfo_ptr_alt_ptr_ptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,3 +116,26 @@ int arginfo_ptr_alt_ptr_int(const struct printf_info *info, size_t n, int *argty
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* special arginfo handler respecting alt flag
|
||||||
|
*/
|
||||||
|
int arginfo_ptr_alt_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes)
|
||||||
|
{
|
||||||
|
if (info->alt)
|
||||||
|
{
|
||||||
|
if (n > 1)
|
||||||
|
{
|
||||||
|
argtypes[0] = PA_POINTER;
|
||||||
|
argtypes[1] = PA_POINTER;
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n > 0)
|
||||||
|
{
|
||||||
|
argtypes[0] = PA_POINTER;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
#define PRINTF_TRAFFIC_SELECTOR 'R'
|
#define PRINTF_TRAFFIC_SELECTOR 'R'
|
||||||
/** 1 argument: time_t *time; with #-modifier 2 arguments: time_t *time, bool utc */
|
/** 1 argument: time_t *time; with #-modifier 2 arguments: time_t *time, bool utc */
|
||||||
#define PRINTF_TIME 'T'
|
#define PRINTF_TIME 'T'
|
||||||
/** 2 arguments: time_t *begin, time_t *end */
|
/** 1 argument: time_t *delta; with #-modifier 2 arguments: time_t *begin, time_t *end */
|
||||||
#define PRINTF_TIME_DELTA 'V'
|
#define PRINTF_TIME_DELTA 'V'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,6 +55,7 @@ int arginfo_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes);
|
||||||
int arginfo_ptr_int(const struct printf_info *info, size_t n, int *argtypes);
|
int arginfo_ptr_int(const struct printf_info *info, size_t n, int *argtypes);
|
||||||
int arginfo_int_int(const struct printf_info *info, size_t n, int *argtypes);
|
int arginfo_int_int(const struct printf_info *info, size_t n, int *argtypes);
|
||||||
int arginfo_ptr_alt_ptr_int(const struct printf_info *info, size_t n, int *argtypes);
|
int arginfo_ptr_alt_ptr_int(const struct printf_info *info, size_t n, int *argtypes);
|
||||||
|
int arginfo_ptr_alt_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes);
|
||||||
int arginfo_int_alt_int_int(const struct printf_info *info, size_t n, int *argtypes);
|
int arginfo_int_alt_int_int(const struct printf_info *info, size_t n, int *argtypes);
|
||||||
|
|
||||||
#endif /* PRINTF_HOOK_H_ */
|
#endif /* PRINTF_HOOK_H_ */
|
||||||
|
|
Loading…
Reference in New Issue