* [PATCH 1/3] storage: Refactor storage_tls_session_{load,sync}
@ 2022-11-17 13:56 Andrew Zaborowski
2022-11-17 13:56 ` [PATCH 2/3] eap-tls: Add session caching Andrew Zaborowski
2022-11-17 13:56 ` [PATCH 3/3] station, eapol: Set up eap-tls-common for " Andrew Zaborowski
0 siblings, 2 replies; 4+ messages in thread
From: Andrew Zaborowski @ 2022-11-17 13:56 UTC (permalink / raw)
To: iwd
Minor changes to these two methods resulting from two rewrites of them.
Actual changes are:
* storage_tls_session_sync parameter is const,
* more specific naming,
* storage_tls_session_load will return an empty l_settings instead of
NULL so eap-tls-common.c doesn't have to handle this.
storage.c makes no assumptions about the group names in the l_settings
object and keeps no reference to that object, eap-tls-common.c is going
to maintain the memory copy of the cache since this cache and the disk
copy of it are reserved for EAP methods only.
---
src/storage.c | 39 +++++++++++++++++++++++----------------
src/storage.h | 4 ++--
2 files changed, 25 insertions(+), 18 deletions(-)
diff --git a/src/storage.c b/src/storage.c
index b2c5ed48..4200030c 100644
--- a/src/storage.c
+++ b/src/storage.c
@@ -53,7 +53,7 @@
#define STORAGE_FILE_MODE (S_IRUSR | S_IWUSR)
#define KNOWN_FREQ_FILENAME ".known_network.freq"
-#define TLS_CACHE_FILENAME ".tls-session-cache"
+#define EAP_TLS_CACHE_FILENAME ".eap-tls-session-cache"
static char *storage_path = NULL;
static char *storage_hotspot_path = NULL;
@@ -702,29 +702,35 @@ void storage_known_frequencies_sync(struct l_settings *known_freqs)
l_free(known_freq_file_path);
}
-struct l_settings *storage_tls_session_cache_load(void)
+struct l_settings *storage_eap_tls_cache_load(void)
{
- _auto_(l_settings_free) struct l_settings *cache = l_settings_new();
- _auto_(l_free) char *tls_cache_file_path =
- storage_get_path("%s", TLS_CACHE_FILENAME);
+ _auto_(l_free) char *path =
+ storage_get_path("%s", EAP_TLS_CACHE_FILENAME);
+ struct l_settings *cache = l_settings_new();
- if (unlikely(!l_settings_load_from_file(cache, tls_cache_file_path)))
- return NULL;
+ if (!l_settings_load_from_file(cache, path))
+ l_debug("No session cache loaded from %s, starting with an "
+ "empty cache", path);
- return l_steal_ptr(cache);
+ return cache;
}
-void storage_tls_session_cache_sync(struct l_settings *cache)
+void storage_eap_tls_cache_sync(const struct l_settings *cache)
{
- _auto_(l_free) char *tls_cache_file_path = NULL;
+ _auto_(l_free) char *path =
+ storage_get_path("%s", EAP_TLS_CACHE_FILENAME);
+ _auto_(l_free) char *settings_data = NULL;
_auto_(l_free) char *data = NULL;
size_t len;
+ static const char comment[] =
+ "# External changes to this file are not tracked by IWD "
+ "and will be overwritten.\n\n";
+ static const size_t comment_len = L_ARRAY_SIZE(comment) - 1;
- if (!cache)
- return;
-
- tls_cache_file_path = storage_get_path("%s", TLS_CACHE_FILENAME);
- data = l_settings_to_data(cache, &len);
+ settings_data = l_settings_to_data(cache, &len);
+ data = l_malloc(comment_len + len);
+ memcpy(data, comment, comment_len);
+ memcpy(data + comment_len, settings_data, len);
/*
* Note this data contains cryptographic secrets. write_file()
@@ -732,7 +738,8 @@ void storage_tls_session_cache_sync(struct l_settings *cache)
*
* TODO: consider encrypting with system_key.
*/
- write_file(data, len, false, "%s", tls_cache_file_path);
+ write_file(data, comment_len + len, false, "%s", path);
+ explicit_bzero(settings_data, len);
explicit_bzero(data, len);
}
diff --git a/src/storage.h b/src/storage.h
index fe6ddbf5..04b50882 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -51,8 +51,8 @@ int storage_network_remove(enum security type, const char *ssid);
struct l_settings *storage_known_frequencies_load(void);
void storage_known_frequencies_sync(struct l_settings *known_freqs);
-struct l_settings *storage_tls_session_cache_load(void);
-void storage_tls_session_cache_sync(struct l_settings *cache);
+struct l_settings *storage_eap_tls_cache_load(void);
+void storage_eap_tls_cache_sync(const struct l_settings *cache);
int __storage_decrypt(struct l_settings *settings, const char *ssid,
bool *changed);
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] eap-tls: Add session caching
2022-11-17 13:56 [PATCH 1/3] storage: Refactor storage_tls_session_{load,sync} Andrew Zaborowski
@ 2022-11-17 13:56 ` Andrew Zaborowski
2022-11-17 13:56 ` [PATCH 3/3] station, eapol: Set up eap-tls-common for " Andrew Zaborowski
1 sibling, 0 replies; 4+ messages in thread
From: Andrew Zaborowski @ 2022-11-17 13:56 UTC (permalink / raw)
To: iwd
Use l_tls_set_session_cache() to enable session cache/resume in the
TLS-based EAP methods. Sessions for all 802.1x networks are stored in
one l_settings object.
eap_{get,set}_peer_id() API is added for the upper layers to set the
identifier of the authenticator (or the supplicant if we're the
authenticator, if there's ever a use case for that.)
eap-tls-common.c can't call storage_eap_tls_cache_{load,sync}()
or known_networks_watch_add() (to handle known network removals) because
it's linked into some executables that don't have storage.o,
knownnetworks.o or common.o so an upper layer (station.c) will call
eap_tls_set_session_cache_ops() and eap_tls_forget_peer() as needed.
---
src/eap-tls-common.c | 58 ++++++++++++++++++++++++++++++++++++++++++++
src/eap-tls-common.h | 7 ++++++
src/eap.c | 13 ++++++++++
src/eap.h | 3 +++
4 files changed, 81 insertions(+)
diff --git a/src/eap-tls-common.c b/src/eap-tls-common.c
index acc5b387..9a4450e9 100644
--- a/src/eap-tls-common.c
+++ b/src/eap-tls-common.c
@@ -28,7 +28,9 @@
#include <errno.h>
#include <ell/ell.h>
+#include "ell/useful.h"
#include "src/missing.h"
+#include "src/module.h"
#include "src/eap.h"
#include "src/eap-private.h"
#include "src/eap-tls-common.h"
@@ -123,6 +125,10 @@ struct eap_tls_state {
void *variant_data;
};
+static struct l_settings *eap_tls_session_cache;
+static eap_tls_session_cache_load_func_t eap_tls_session_cache_load;
+static eap_tls_session_cache_sync_func_t eap_tls_session_cache_sync;
+
static void __eap_tls_common_state_reset(struct eap_tls_state *eap_tls)
{
eap_tls->version_negotiated = EAP_TLS_VERSION_NOT_NEGOTIATED;
@@ -571,6 +577,15 @@ static int eap_tls_handle_fragmented_request(struct eap_state *eap,
return r;
}
+static void eap_tls_session_cache_update(void *user_data)
+{
+ if (L_WARN_ON(!eap_tls_session_cache_sync) ||
+ L_WARN_ON(!eap_tls_session_cache))
+ return;
+
+ eap_tls_session_cache_sync(eap_tls_session_cache);
+}
+
static bool eap_tls_tunnel_init(struct eap_state *eap)
{
struct eap_tls_state *eap_tls = eap_get_data(eap);
@@ -633,6 +648,17 @@ static bool eap_tls_tunnel_init(struct eap_state *eap)
if (eap_tls->domain_mask)
l_tls_set_domain_mask(eap_tls->tunnel, eap_tls->domain_mask);
+ if (!eap_tls_session_cache_load)
+ goto start;
+
+ if (!eap_tls_session_cache)
+ eap_tls_session_cache = eap_tls_session_cache_load();
+
+ l_tls_set_session_cache(eap_tls->tunnel, eap_tls_session_cache,
+ eap_get_peer_id(eap),
+ 24 * 3600 * L_USEC_PER_SEC, 0,
+ eap_tls_session_cache_update, NULL);
+
start:
if (!l_tls_start(eap_tls->tunnel)) {
l_error("%s: Failed to start the TLS client",
@@ -1085,3 +1111,35 @@ void eap_tls_common_tunnel_close(struct eap_state *eap)
l_tls_close(eap_tls->tunnel);
}
+
+void eap_tls_set_session_cache_ops(eap_tls_session_cache_load_func_t load,
+ eap_tls_session_cache_sync_func_t sync)
+{
+ eap_tls_session_cache_load = load;
+ eap_tls_session_cache_sync = sync;
+}
+
+void eap_tls_forget_peer(const char *peer_id)
+{
+ if (L_WARN_ON(!eap_tls_session_cache_sync))
+ return;
+
+ if (!eap_tls_session_cache)
+ eap_tls_session_cache = eap_tls_session_cache_load();
+
+ if (l_settings_remove_group(eap_tls_session_cache, peer_id))
+ eap_tls_session_cache_sync(eap_tls_session_cache);
+}
+
+static int eap_tls_common_init(void)
+{
+ return 0;
+}
+
+static void eap_tls_common_exit(void)
+{
+ l_settings_free(eap_tls_session_cache);
+ eap_tls_session_cache = NULL;
+}
+
+IWD_MODULE(eap_tls_common, eap_tls_common_init, eap_tls_common_exit);
diff --git a/src/eap-tls-common.h b/src/eap-tls-common.h
index 174770c0..25f668e2 100644
--- a/src/eap-tls-common.h
+++ b/src/eap-tls-common.h
@@ -20,6 +20,9 @@
*
*/
+typedef struct l_settings *(*eap_tls_session_cache_load_func_t)(void);
+typedef void (*eap_tls_session_cache_sync_func_t)(const struct l_settings *);
+
enum eap_tls_version {
EAP_TLS_VERSION_0 = 0x00,
EAP_TLS_VERSION_1 = 0x01,
@@ -81,3 +84,7 @@ bool eap_tls_common_tunnel_prf_get_bytes(struct eap_state *eap,
void eap_tls_common_tunnel_send(struct eap_state *eap, const uint8_t *data,
size_t data_len);
void eap_tls_common_tunnel_close(struct eap_state *eap);
+
+void eap_tls_set_session_cache_ops(eap_tls_session_cache_load_func_t load,
+ eap_tls_session_cache_sync_func_t sync);
+void eap_tls_forget_peer(const char *peer_id);
diff --git a/src/eap.c b/src/eap.c
index 6f523f2f..981b6388 100644
--- a/src/eap.c
+++ b/src/eap.c
@@ -59,6 +59,7 @@ struct eap_state {
char *identity;
char *identity_setting;
bool authenticator;
+ char *peer_id;
int last_id;
void *method_state;
@@ -154,6 +155,7 @@ void eap_free(struct eap_state *eap)
eap_free_common(eap);
l_timeout_remove(eap->complete_timeout);
+ eap_set_peer_id(eap, NULL);
l_free(eap);
}
@@ -837,6 +839,17 @@ err:
return false;
}
+void eap_set_peer_id(struct eap_state *eap, const char *id)
+{
+ l_free(eap->peer_id);
+ eap->peer_id = l_strdup(id);
+}
+
+const char *eap_get_peer_id(struct eap_state *eap)
+{
+ return eap->peer_id;
+}
+
void eap_set_data(struct eap_state *eap, void *data)
{
eap->method_state = data;
diff --git a/src/eap.h b/src/eap.h
index f1e867f5..702caf24 100644
--- a/src/eap.h
+++ b/src/eap.h
@@ -94,6 +94,9 @@ const char *eap_get_identity(struct eap_state *eap);
void eap_rx_packet(struct eap_state *eap, const uint8_t *pkt, size_t len);
+void eap_set_peer_id(struct eap_state *eap, const char *id);
+const char *eap_get_peer_id(struct eap_state *eap);
+
void __eap_set_config(struct l_settings *config);
int eap_init(void);
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] station, eapol: Set up eap-tls-common for session caching
2022-11-17 13:56 [PATCH 1/3] storage: Refactor storage_tls_session_{load,sync} Andrew Zaborowski
2022-11-17 13:56 ` [PATCH 2/3] eap-tls: Add session caching Andrew Zaborowski
@ 2022-11-17 13:56 ` Andrew Zaborowski
2022-11-17 16:22 ` Denis Kenzior
1 sibling, 1 reply; 4+ messages in thread
From: Andrew Zaborowski @ 2022-11-17 13:56 UTC (permalink / raw)
To: iwd
Use eap_set_peer_id() to set a string identifying the TLS server,
currently the hex-encoded SSID of the network, to be used as group name
and primary key in the session cache l_settings object. Provide pointers
to storage_eap_tls_cache_{load,sync} to eap-tls-common.c using
eap_tls_set_session_cache_ops(). Listen to Known Network removed
signals and call eap_tls_forget_peer() to have any session related to
the network also dropped from the cache.
---
src/eapol.c | 6 ++++++
src/station.c | 28 ++++++++++++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/src/eapol.c b/src/eapol.c
index 4a1abd28..4d4e201d 100644
--- a/src/eapol.c
+++ b/src/eapol.c
@@ -2770,6 +2770,8 @@ void eapol_register(struct eapol_sm *sm)
bool eapol_start(struct eapol_sm *sm)
{
if (sm->handshake->settings_8021x) {
+ _auto_(l_free) char *network_id = NULL;
+
sm->eap = eap_new(eapol_eap_msg_cb, eapol_eap_complete_cb, sm);
if (!sm->eap)
@@ -2785,6 +2787,10 @@ bool eapol_start(struct eapol_sm *sm)
eap_set_key_material_func(sm->eap, eapol_eap_results_cb);
eap_set_event_func(sm->eap, eapol_eap_event_cb);
+
+ network_id = l_util_hexstring(sm->handshake->ssid,
+ sm->handshake->ssid_len);
+ eap_set_peer_id(sm->eap, network_id);
}
sm->started = true;
diff --git a/src/station.c b/src/station.c
index eab16eff..4aab7828 100644
--- a/src/station.c
+++ b/src/station.c
@@ -60,6 +60,9 @@
#include "src/sysfs.h"
#include "src/band.h"
#include "src/ft.h"
+#include "src/eap.h"
+#include "src/eap-tls-common.h"
+#include "src/storage.h"
static struct l_queue *station_list;
static uint32_t netdev_watch;
@@ -69,6 +72,7 @@ static bool anqp_disabled;
static bool supports_arp_evict_nocarrier;
static bool supports_ndisc_evict_nocarrier;
static struct watchlist event_watches;
+static uint32_t known_networks_watch;
struct station {
enum station_state state;
@@ -5087,6 +5091,22 @@ static void station_netdev_watch(struct netdev *netdev,
}
}
+static void station_known_networks_changed(enum known_networks_event event,
+ const struct network_info *info,
+ void *user_data)
+{
+ _auto_(l_free) char *network_id = NULL;
+
+ if (event != KNOWN_NETWORKS_EVENT_REMOVED)
+ return;
+
+ if (info->type != SECURITY_8021X)
+ return;
+
+ network_id = l_util_hexstring(info->ssid, strlen(info->ssid));
+ eap_tls_forget_peer(network_id);
+}
+
static int station_init(void)
{
station_list = l_queue_new();
@@ -5139,6 +5159,12 @@ static int station_init(void)
watchlist_init(&event_watches, NULL);
+ eap_tls_set_session_cache_ops(storage_eap_tls_cache_load,
+ storage_eap_tls_cache_sync);
+ known_networks_watch = known_networks_watch_add(
+ station_known_networks_changed,
+ NULL, NULL);
+
return 0;
}
@@ -5154,6 +5180,8 @@ static void station_exit(void)
l_queue_destroy(station_list, NULL);
station_list = NULL;
watchlist_destroy(&event_watches);
+ known_networks_watch_remove(known_networks_watch);
+ known_networks_watch = 0;
}
IWD_MODULE(station, station_init, station_exit)
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 3/3] station, eapol: Set up eap-tls-common for session caching
2022-11-17 13:56 ` [PATCH 3/3] station, eapol: Set up eap-tls-common for " Andrew Zaborowski
@ 2022-11-17 16:22 ` Denis Kenzior
0 siblings, 0 replies; 4+ messages in thread
From: Denis Kenzior @ 2022-11-17 16:22 UTC (permalink / raw)
To: Andrew Zaborowski, iwd
Hi Andrew,
On 11/17/22 07:56, Andrew Zaborowski wrote:
> Use eap_set_peer_id() to set a string identifying the TLS server,
> currently the hex-encoded SSID of the network, to be used as group name
> and primary key in the session cache l_settings object. Provide pointers
> to storage_eap_tls_cache_{load,sync} to eap-tls-common.c using
> eap_tls_set_session_cache_ops(). Listen to Known Network removed
> signals and call eap_tls_forget_peer() to have any session related to
> the network also dropped from the cache.
> ---
> src/eapol.c | 6 ++++++
> src/station.c | 28 ++++++++++++++++++++++++++++
> 2 files changed, 34 insertions(+)
>
<snip>
> @@ -5139,6 +5159,12 @@ static int station_init(void)
>
> watchlist_init(&event_watches, NULL);
>
> + eap_tls_set_session_cache_ops(storage_eap_tls_cache_load,
> + storage_eap_tls_cache_sync);
> + known_networks_watch = known_networks_watch_add(
> + station_known_networks_changed,
> + NULL, NULL);
This requires a dependency between station and known_networks module since the
watchlist is initialized in known_networks_init. I added this in a follow on
commit. Please have a look.
> +
> return 0;
> }
>
All three applied, thanks.
Regards,
-Denis
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-11-17 16:22 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-17 13:56 [PATCH 1/3] storage: Refactor storage_tls_session_{load,sync} Andrew Zaborowski
2022-11-17 13:56 ` [PATCH 2/3] eap-tls: Add session caching Andrew Zaborowski
2022-11-17 13:56 ` [PATCH 3/3] station, eapol: Set up eap-tls-common for " Andrew Zaborowski
2022-11-17 16:22 ` Denis Kenzior
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.