You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
388 lines
13 KiB
388 lines
13 KiB
From 23c3528a8461681b23c94ed441cd94c8d528bebe Mon Sep 17 00:00:00 2001 |
|
Message-Id: <23c3528a8461681b23c94ed441cd94c8d528bebe.1488376601.git.dcaratti@redhat.com> |
|
From: Sabrina Dubroca <sd@queasysnail.net> |
|
Date: Fri, 21 Oct 2016 14:45:28 +0200 |
|
Subject: [PATCH] mka: Add support for removing SAs |
|
|
|
So that the core can notify drivers that need to perform some operations |
|
when an SA is deleted. |
|
|
|
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> |
|
--- |
|
src/drivers/driver.h | 16 +++++++++ |
|
src/pae/ieee802_1x_kay.c | 81 +++++++++++++++++++++++++++++++++---------- |
|
src/pae/ieee802_1x_kay.h | 2 ++ |
|
src/pae/ieee802_1x_secy_ops.c | 41 ++++++++++++++++++++++ |
|
src/pae/ieee802_1x_secy_ops.h | 3 ++ |
|
wpa_supplicant/driver_i.h | 16 +++++++++ |
|
wpa_supplicant/wpas_kay.c | 14 ++++++++ |
|
7 files changed, 154 insertions(+), 19 deletions(-) |
|
|
|
diff --git a/src/drivers/driver.h b/src/drivers/driver.h |
|
index 54ae6b7..9a6db90 100644 |
|
--- a/src/drivers/driver.h |
|
+++ b/src/drivers/driver.h |
|
@@ -3419,6 +3419,14 @@ struct wpa_driver_ops { |
|
int (*create_receive_sa)(void *priv, struct receive_sa *sa); |
|
|
|
/** |
|
+ * delete_receive_sa - Delete secure association for receive |
|
+ * @priv: Private driver interface data from init() |
|
+ * @sa: Secure association |
|
+ * Returns: 0 on success, -1 on failure |
|
+ */ |
|
+ int (*delete_receive_sa)(void *priv, struct receive_sa *sa); |
|
+ |
|
+ /** |
|
* enable_receive_sa - enable the SA for receive |
|
* @priv: private driver interface data from init() |
|
* @sa: secure association |
|
@@ -3461,6 +3469,14 @@ struct wpa_driver_ops { |
|
int (*create_transmit_sa)(void *priv, struct transmit_sa *sa); |
|
|
|
/** |
|
+ * delete_transmit_sa - Delete secure association for transmit |
|
+ * @priv: Private driver interface data from init() |
|
+ * @sa: Secure association |
|
+ * Returns: 0 on success, -1 on failure |
|
+ */ |
|
+ int (*delete_transmit_sa)(void *priv, struct transmit_sa *sa); |
|
+ |
|
+ /** |
|
* enable_transmit_sa - enable SA for transmit |
|
* @priv: private driver interface data from init() |
|
* @sa: secure association |
|
diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c |
|
index 38a8293..e312d04 100644 |
|
--- a/src/pae/ieee802_1x_kay.c |
|
+++ b/src/pae/ieee802_1x_kay.c |
|
@@ -491,6 +491,15 @@ ieee802_1x_kay_init_receive_sc(const struct ieee802_1x_mka_sci *psci) |
|
} |
|
|
|
|
|
+static void ieee802_1x_delete_receive_sa(struct ieee802_1x_kay *kay, |
|
+ struct receive_sa *sa) |
|
+{ |
|
+ secy_disable_receive_sa(kay, sa); |
|
+ secy_delete_receive_sa(kay, sa); |
|
+ ieee802_1x_kay_deinit_receive_sa(sa); |
|
+} |
|
+ |
|
+ |
|
/** |
|
* ieee802_1x_kay_deinit_receive_sc - |
|
**/ |
|
@@ -502,10 +511,9 @@ ieee802_1x_kay_deinit_receive_sc( |
|
|
|
wpa_printf(MSG_DEBUG, "KaY: Delete receive SC"); |
|
dl_list_for_each_safe(psa, pre_sa, &psc->sa_list, struct receive_sa, |
|
- list) { |
|
- secy_disable_receive_sa(participant->kay, psa); |
|
- ieee802_1x_kay_deinit_receive_sa(psa); |
|
- } |
|
+ list) |
|
+ ieee802_1x_delete_receive_sa(participant->kay, psa); |
|
+ |
|
dl_list_del(&psc->list); |
|
os_free(psc); |
|
} |
|
@@ -2270,6 +2278,16 @@ ieee802_1x_participant_send_mkpdu( |
|
|
|
|
|
static void ieee802_1x_kay_deinit_transmit_sa(struct transmit_sa *psa); |
|
+ |
|
+static void ieee802_1x_delete_transmit_sa(struct ieee802_1x_kay *kay, |
|
+ struct transmit_sa *sa) |
|
+{ |
|
+ secy_disable_transmit_sa(kay, sa); |
|
+ secy_delete_transmit_sa(kay, sa); |
|
+ ieee802_1x_kay_deinit_transmit_sa(sa); |
|
+} |
|
+ |
|
+ |
|
/** |
|
* ieee802_1x_participant_timer - |
|
*/ |
|
@@ -2344,8 +2362,7 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx) |
|
dl_list_for_each_safe(txsa, pre_txsa, |
|
&participant->txsc->sa_list, |
|
struct transmit_sa, list) { |
|
- secy_disable_transmit_sa(kay, txsa); |
|
- ieee802_1x_kay_deinit_transmit_sa(txsa); |
|
+ ieee802_1x_delete_transmit_sa(kay, txsa); |
|
} |
|
|
|
ieee802_1x_cp_connect_authenticated(kay->cp); |
|
@@ -2487,11 +2504,8 @@ ieee802_1x_kay_deinit_transmit_sc( |
|
struct transmit_sa *psa, *tmp; |
|
|
|
wpa_printf(MSG_DEBUG, "KaY: Delete transmit SC"); |
|
- dl_list_for_each_safe(psa, tmp, &psc->sa_list, struct transmit_sa, |
|
- list) { |
|
- secy_disable_transmit_sa(participant->kay, psa); |
|
- ieee802_1x_kay_deinit_transmit_sa(psa); |
|
- } |
|
+ dl_list_for_each_safe(psa, tmp, &psc->sa_list, struct transmit_sa, list) |
|
+ ieee802_1x_delete_transmit_sa(participant->kay, psa); |
|
|
|
os_free(psc); |
|
} |
|
@@ -2569,6 +2583,32 @@ int ieee802_1x_kay_set_old_sa_attr(struct ieee802_1x_kay *kay, |
|
} |
|
|
|
|
|
+static struct transmit_sa * lookup_txsa_by_an(struct transmit_sc *txsc, u8 an) |
|
+{ |
|
+ struct transmit_sa *txsa; |
|
+ |
|
+ dl_list_for_each(txsa, &txsc->sa_list, struct transmit_sa, list) { |
|
+ if (txsa->an == an) |
|
+ return txsa; |
|
+ } |
|
+ |
|
+ return NULL; |
|
+} |
|
+ |
|
+ |
|
+static struct receive_sa * lookup_rxsa_by_an(struct receive_sc *rxsc, u8 an) |
|
+{ |
|
+ struct receive_sa *rxsa; |
|
+ |
|
+ dl_list_for_each(rxsa, &rxsc->sa_list, struct receive_sa, list) { |
|
+ if (rxsa->an == an) |
|
+ return rxsa; |
|
+ } |
|
+ |
|
+ return NULL; |
|
+} |
|
+ |
|
+ |
|
/** |
|
* ieee802_1x_kay_create_sas - |
|
*/ |
|
@@ -2603,6 +2643,9 @@ int ieee802_1x_kay_create_sas(struct ieee802_1x_kay *kay, |
|
} |
|
|
|
dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { |
|
+ while ((rxsa = lookup_rxsa_by_an(rxsc, latest_sak->an)) != NULL) |
|
+ ieee802_1x_delete_receive_sa(kay, rxsa); |
|
+ |
|
rxsa = ieee802_1x_kay_init_receive_sa(rxsc, latest_sak->an, 1, |
|
latest_sak); |
|
if (!rxsa) |
|
@@ -2611,6 +2654,10 @@ int ieee802_1x_kay_create_sas(struct ieee802_1x_kay *kay, |
|
secy_create_receive_sa(kay, rxsa); |
|
} |
|
|
|
+ while ((txsa = lookup_txsa_by_an(principal->txsc, latest_sak->an)) != |
|
+ NULL) |
|
+ ieee802_1x_delete_transmit_sa(kay, txsa); |
|
+ |
|
txsa = ieee802_1x_kay_init_transmit_sa(principal->txsc, latest_sak->an, |
|
1, latest_sak); |
|
if (!txsa) |
|
@@ -2644,20 +2691,16 @@ int ieee802_1x_kay_delete_sas(struct ieee802_1x_kay *kay, |
|
/* remove the transmit sa */ |
|
dl_list_for_each_safe(txsa, pre_txsa, &principal->txsc->sa_list, |
|
struct transmit_sa, list) { |
|
- if (is_ki_equal(&txsa->pkey->key_identifier, ki)) { |
|
- secy_disable_transmit_sa(kay, txsa); |
|
- ieee802_1x_kay_deinit_transmit_sa(txsa); |
|
- } |
|
+ if (is_ki_equal(&txsa->pkey->key_identifier, ki)) |
|
+ ieee802_1x_delete_transmit_sa(kay, txsa); |
|
} |
|
|
|
/* remove the receive sa */ |
|
dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { |
|
dl_list_for_each_safe(rxsa, pre_rxsa, &rxsc->sa_list, |
|
struct receive_sa, list) { |
|
- if (is_ki_equal(&rxsa->pkey->key_identifier, ki)) { |
|
- secy_disable_receive_sa(kay, rxsa); |
|
- ieee802_1x_kay_deinit_receive_sa(rxsa); |
|
- } |
|
+ if (is_ki_equal(&rxsa->pkey->key_identifier, ki)) |
|
+ ieee802_1x_delete_receive_sa(kay, rxsa); |
|
} |
|
} |
|
|
|
diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h |
|
index e2ba180..5233cb2 100644 |
|
--- a/src/pae/ieee802_1x_kay.h |
|
+++ b/src/pae/ieee802_1x_kay.h |
|
@@ -153,12 +153,14 @@ struct ieee802_1x_kay_ctx { |
|
enum confidentiality_offset co); |
|
int (*delete_receive_sc)(void *ctx, struct receive_sc *sc); |
|
int (*create_receive_sa)(void *ctx, struct receive_sa *sa); |
|
+ int (*delete_receive_sa)(void *ctx, struct receive_sa *sa); |
|
int (*enable_receive_sa)(void *ctx, struct receive_sa *sa); |
|
int (*disable_receive_sa)(void *ctx, struct receive_sa *sa); |
|
int (*create_transmit_sc)(void *ctx, struct transmit_sc *sc, |
|
enum confidentiality_offset co); |
|
int (*delete_transmit_sc)(void *ctx, struct transmit_sc *sc); |
|
int (*create_transmit_sa)(void *ctx, struct transmit_sa *sa); |
|
+ int (*delete_transmit_sa)(void *ctx, struct transmit_sa *sa); |
|
int (*enable_transmit_sa)(void *ctx, struct transmit_sa *sa); |
|
int (*disable_transmit_sa)(void *ctx, struct transmit_sa *sa); |
|
}; |
|
diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c |
|
index b57c670..b1a9d22 100644 |
|
--- a/src/pae/ieee802_1x_secy_ops.c |
|
+++ b/src/pae/ieee802_1x_secy_ops.c |
|
@@ -256,6 +256,26 @@ int secy_create_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa) |
|
} |
|
|
|
|
|
+int secy_delete_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa) |
|
+{ |
|
+ struct ieee802_1x_kay_ctx *ops; |
|
+ |
|
+ if (!kay || !rxsa) { |
|
+ wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__); |
|
+ return -1; |
|
+ } |
|
+ |
|
+ ops = kay->ctx; |
|
+ if (!ops || !ops->delete_receive_sa) { |
|
+ wpa_printf(MSG_ERROR, |
|
+ "KaY: secy delete_receive_sa operation not supported"); |
|
+ return -1; |
|
+ } |
|
+ |
|
+ return ops->delete_receive_sa(ops->ctx, rxsa); |
|
+} |
|
+ |
|
+ |
|
int secy_enable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa) |
|
{ |
|
struct ieee802_1x_kay_ctx *ops; |
|
@@ -363,6 +383,27 @@ int secy_create_transmit_sa(struct ieee802_1x_kay *kay, |
|
} |
|
|
|
|
|
+int secy_delete_transmit_sa(struct ieee802_1x_kay *kay, |
|
+ struct transmit_sa *txsa) |
|
+{ |
|
+ struct ieee802_1x_kay_ctx *ops; |
|
+ |
|
+ if (!kay || !txsa) { |
|
+ wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__); |
|
+ return -1; |
|
+ } |
|
+ |
|
+ ops = kay->ctx; |
|
+ if (!ops || !ops->delete_transmit_sa) { |
|
+ wpa_printf(MSG_ERROR, |
|
+ "KaY: secy delete_transmit_sa operation not supported"); |
|
+ return -1; |
|
+ } |
|
+ |
|
+ return ops->delete_transmit_sa(ops->ctx, txsa); |
|
+} |
|
+ |
|
+ |
|
int secy_enable_transmit_sa(struct ieee802_1x_kay *kay, |
|
struct transmit_sa *txsa) |
|
{ |
|
diff --git a/src/pae/ieee802_1x_secy_ops.h b/src/pae/ieee802_1x_secy_ops.h |
|
index 59f0baa..477120b 100644 |
|
--- a/src/pae/ieee802_1x_secy_ops.h |
|
+++ b/src/pae/ieee802_1x_secy_ops.h |
|
@@ -38,6 +38,7 @@ int secy_set_transmit_next_pn(struct ieee802_1x_kay *kay, |
|
int secy_create_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc); |
|
int secy_delete_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc); |
|
int secy_create_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa); |
|
+int secy_delete_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa); |
|
int secy_enable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa); |
|
int secy_disable_receive_sa(struct ieee802_1x_kay *kay, |
|
struct receive_sa *rxsa); |
|
@@ -48,6 +49,8 @@ int secy_delete_transmit_sc(struct ieee802_1x_kay *kay, |
|
struct transmit_sc *txsc); |
|
int secy_create_transmit_sa(struct ieee802_1x_kay *kay, |
|
struct transmit_sa *txsa); |
|
+int secy_delete_transmit_sa(struct ieee802_1x_kay *kay, |
|
+ struct transmit_sa *txsa); |
|
int secy_enable_transmit_sa(struct ieee802_1x_kay *kay, |
|
struct transmit_sa *txsa); |
|
int secy_disable_transmit_sa(struct ieee802_1x_kay *kay, |
|
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h |
|
index 244e386..c9bb20d 100644 |
|
--- a/wpa_supplicant/driver_i.h |
|
+++ b/wpa_supplicant/driver_i.h |
|
@@ -806,6 +806,14 @@ static inline int wpa_drv_create_receive_sa(struct wpa_supplicant *wpa_s, |
|
return wpa_s->driver->create_receive_sa(wpa_s->drv_priv, sa); |
|
} |
|
|
|
+static inline int wpa_drv_delete_receive_sa(struct wpa_supplicant *wpa_s, |
|
+ struct receive_sa *sa) |
|
+{ |
|
+ if (!wpa_s->driver->delete_receive_sa) |
|
+ return -1; |
|
+ return wpa_s->driver->delete_receive_sa(wpa_s->drv_priv, sa); |
|
+} |
|
+ |
|
static inline int wpa_drv_enable_receive_sa(struct wpa_supplicant *wpa_s, |
|
struct receive_sa *sa) |
|
{ |
|
@@ -848,6 +856,14 @@ static inline int wpa_drv_create_transmit_sa(struct wpa_supplicant *wpa_s, |
|
return wpa_s->driver->create_transmit_sa(wpa_s->drv_priv, sa); |
|
} |
|
|
|
+static inline int wpa_drv_delete_transmit_sa(struct wpa_supplicant *wpa_s, |
|
+ struct transmit_sa *sa) |
|
+{ |
|
+ if (!wpa_s->driver->delete_transmit_sa) |
|
+ return -1; |
|
+ return wpa_s->driver->delete_transmit_sa(wpa_s->drv_priv, sa); |
|
+} |
|
+ |
|
static inline int wpa_drv_enable_transmit_sa(struct wpa_supplicant *wpa_s, |
|
struct transmit_sa *sa) |
|
{ |
|
diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c |
|
index 64364f7..e032330 100644 |
|
--- a/wpa_supplicant/wpas_kay.c |
|
+++ b/wpa_supplicant/wpas_kay.c |
|
@@ -120,6 +120,12 @@ static int wpas_create_receive_sa(void *wpa_s, struct receive_sa *sa) |
|
} |
|
|
|
|
|
+static int wpas_delete_receive_sa(void *wpa_s, struct receive_sa *sa) |
|
+{ |
|
+ return wpa_drv_delete_receive_sa(wpa_s, sa); |
|
+} |
|
+ |
|
+ |
|
static int wpas_enable_receive_sa(void *wpa_s, struct receive_sa *sa) |
|
{ |
|
return wpa_drv_enable_receive_sa(wpa_s, sa); |
|
@@ -152,6 +158,12 @@ static int wpas_create_transmit_sa(void *wpa_s, struct transmit_sa *sa) |
|
} |
|
|
|
|
|
+static int wpas_delete_transmit_sa(void *wpa_s, struct transmit_sa *sa) |
|
+{ |
|
+ return wpa_drv_delete_transmit_sa(wpa_s, sa); |
|
+} |
|
+ |
|
+ |
|
static int wpas_enable_transmit_sa(void *wpa_s, struct transmit_sa *sa) |
|
{ |
|
return wpa_drv_enable_transmit_sa(wpa_s, sa); |
|
@@ -196,11 +208,13 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) |
|
kay_ctx->create_receive_sc = wpas_create_receive_sc; |
|
kay_ctx->delete_receive_sc = wpas_delete_receive_sc; |
|
kay_ctx->create_receive_sa = wpas_create_receive_sa; |
|
+ kay_ctx->delete_receive_sa = wpas_delete_receive_sa; |
|
kay_ctx->enable_receive_sa = wpas_enable_receive_sa; |
|
kay_ctx->disable_receive_sa = wpas_disable_receive_sa; |
|
kay_ctx->create_transmit_sc = wpas_create_transmit_sc; |
|
kay_ctx->delete_transmit_sc = wpas_delete_transmit_sc; |
|
kay_ctx->create_transmit_sa = wpas_create_transmit_sa; |
|
+ kay_ctx->delete_transmit_sa = wpas_delete_transmit_sa; |
|
kay_ctx->enable_transmit_sa = wpas_enable_transmit_sa; |
|
kay_ctx->disable_transmit_sa = wpas_disable_transmit_sa; |
|
|
|
-- |
|
2.7.4 |
|
|
|
|