@@ -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);
@@ -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);
@@ -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;
@@ -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);