aboutsummaryrefslogtreecommitdiff
path: root/src/eap_peer/eap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/eap_peer/eap.c')
-rw-r--r--src/eap_peer/eap.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index 5fd370f7..8338c47b 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -267,6 +267,7 @@ SM_STATE(EAP, INITIALIZE)
sm->reauthInit = false;
sm->erp_seq = (u32) -1;
sm->use_machine_cred = 0;
+ sm->eap_fast_mschapv2 = false;
}
@@ -1684,6 +1685,7 @@ struct wpabuf * eap_sm_buildIdentity(struct eap_sm *sm, int id, int encrypted)
struct wpabuf *resp;
const u8 *identity;
size_t identity_len;
+ struct wpabuf *privacy_identity = NULL;
if (config == NULL) {
wpa_printf(MSG_WARNING, "EAP: buildIdentity: configuration "
@@ -1706,6 +1708,33 @@ struct wpabuf * eap_sm_buildIdentity(struct eap_sm *sm, int id, int encrypted)
identity_len = config->machine_identity_len;
wpa_hexdump_ascii(MSG_DEBUG, "EAP: using machine identity",
identity, identity_len);
+ } else if (config->imsi_privacy_cert && config->identity &&
+ config->identity_len > 0) {
+ const u8 *pos = config->identity;
+ const u8 *end = config->identity + config->identity_len;
+
+ privacy_identity = wpabuf_alloc(9 + config->identity_len);
+ if (!privacy_identity)
+ return NULL;
+
+ /* Include method prefix */
+ if (*pos == '0' || *pos == '1' || *pos == '6')
+ wpabuf_put_u8(privacy_identity, *pos);
+ wpabuf_put_str(privacy_identity, "anonymous");
+
+ /* Include realm */
+ while (pos < end && *pos != '@')
+ pos++;
+ wpabuf_put_data(privacy_identity, pos, end - pos);
+
+ identity = wpabuf_head(privacy_identity);
+ identity_len = wpabuf_len(privacy_identity);
+ wpa_hexdump_ascii(MSG_DEBUG,
+ "EAP: using IMSI privacy anonymous identity",
+ identity, identity_len);
+ } else if (config->strict_conservative_peer_mode) {
+ wpa_printf(MSG_DEBUG, "EAP: never use real identity in conservative peer mode.");
+ return NULL;
} else {
identity = config->identity;
identity_len = config->identity_len;
@@ -1742,6 +1771,7 @@ struct wpabuf * eap_sm_buildIdentity(struct eap_sm *sm, int id, int encrypted)
return NULL;
wpabuf_put_data(resp, identity, identity_len);
+ wpabuf_free(privacy_identity);
return resp;
}
@@ -2157,11 +2187,25 @@ static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev,
eap_notify_status(sm, "remote TLS alert",
data->alert.description);
break;
+ case TLS_UNSAFE_RENEGOTIATION_DISABLED:
+ wpa_printf(MSG_INFO,
+ "TLS handshake failed due to the server not supporting safe renegotiation (RFC 5746); phase1 parameter allow_unsafe_renegotiation=1 can be used to work around this");
+ eap_notify_status(sm, "unsafe server renegotiation", "failure");
+ break;
}
os_free(hash_hex);
}
+ssize_t tls_certificate_callback(void* ctx, const char* alias, uint8_t** value) {
+ if (alias == NULL || ctx == NULL || value == NULL) return -1;
+ struct eap_sm *sm = (struct eap_sm*) ctx;
+ wpa_printf(MSG_INFO, "tls_certificate_callback: received sm=%p", (void*)sm);
+ if (sm->eapol_cb && sm->eapol_cb->get_certificate) {
+ return sm->eapol_cb->get_certificate(sm->eapol_ctx, alias, value);
+ }
+ return -1;
+}
/**
* eap_peer_sm_init - Allocate and initialize EAP peer state machine
@@ -2185,6 +2229,7 @@ struct eap_sm * eap_peer_sm_init(void *eapol_ctx,
struct tls_config tlsconf;
sm = os_zalloc(sizeof(*sm));
+ wpa_printf(MSG_INFO, "Init sm=%p", (void*)sm);
if (sm == NULL)
return NULL;
sm->eapol_ctx = eapol_ctx;
@@ -2205,6 +2250,7 @@ struct eap_sm * eap_peer_sm_init(void *eapol_ctx,
tlsconf.event_cb = eap_peer_sm_tls_event;
tlsconf.cb_ctx = sm;
tlsconf.cert_in_cb = conf->cert_in_cb;
+ tls_register_cert_callback(&tls_certificate_callback);
sm->ssl_ctx = tls_init(&tlsconf);
if (sm->ssl_ctx == NULL) {
wpa_printf(MSG_WARNING, "SSL: Failed to initialize TLS "
@@ -2233,6 +2279,7 @@ struct eap_sm * eap_peer_sm_init(void *eapol_ctx,
*/
void eap_peer_sm_deinit(struct eap_sm *sm)
{
+ wpa_printf(MSG_INFO, "Deinit sm=%p", (void*)sm);
if (sm == NULL)
return;
eap_deinit_prev_method(sm, "EAP deinit");
@@ -2786,6 +2833,81 @@ const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len)
}
+/**
+ * eap_get_config_strict_conservative_peer_mode - get the value of
+ * strict conservative peer mode in eap_peer_config.
+ * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
+*/
+int eap_get_config_strict_conservative_peer_mode(struct eap_sm *sm)
+{
+ struct eap_peer_config *config;
+ config = eap_get_config(sm);
+ if (config) {
+ return config->strict_conservative_peer_mode;
+ }
+
+ return 0;
+}
+
+
+static const u8 * strnchr(const u8 *str, size_t len, u8 needle) {
+ const u8 *cur = str;
+
+ if (NULL == str) return NULL;
+ if (0 >= len) return NULL;
+
+ while (cur < str + len) {
+ if (*cur == needle)
+ return cur;
+ cur++;
+ }
+ return NULL;
+}
+
+const u8 * eap_get_config_realm(struct eap_sm *sm, size_t *len) {
+ struct eap_peer_config *config = eap_get_config(sm);
+ const u8 *realm = NULL;
+ size_t realm_len = 0;
+ const u8 *identity = NULL;
+ size_t identity_len = 0;
+
+ if (!config)
+ return NULL;
+
+ /* Look for the realm of the permanent identity */
+ identity = eap_get_config_identity(sm, &identity_len);
+ realm = strnchr(identity, identity_len, '@');
+ if (NULL != realm) {
+ wpa_printf(MSG_DEBUG, "Get the realm from identity.");
+ *len = identity_len - (realm - identity);
+ return realm;
+ }
+
+ /* Look for the realm of the anonymous identity. */
+ identity = config->anonymous_identity;
+ identity_len = config->anonymous_identity_len;
+ realm = strnchr(identity, identity_len, '@');
+ if (NULL != realm) {
+ wpa_printf(MSG_DEBUG, "Get the realm from anonymous identity.");
+ *len = identity_len - (realm - identity);
+ return realm;
+ }
+
+ /* Look for the realm of the real identity. */
+ identity = config->imsi_identity;
+ identity_len = config->imsi_identity_len;
+ realm = strnchr(identity, identity_len, '@');
+ if (NULL != realm) {
+ wpa_printf(MSG_DEBUG, "Get the realm from IMSI identity.");
+ *len = identity_len - (realm - identity);
+ return realm;
+ }
+ wpa_printf(MSG_DEBUG, "No realm information in identities.");
+ *len = 0;
+ return NULL;
+}
+
+
static int eap_get_ext_password(struct eap_sm *sm,
struct eap_peer_config *config)
{
@@ -2992,6 +3114,19 @@ int eap_key_available(struct eap_sm *sm)
return sm ? sm->eapKeyAvailable : 0;
}
+/**
+ * eap_notify_permanent_id_req_denied - Notify that the AT_PERMANENT_ID_REQ
+ * is denied from eap_peer when the strict conservative mode is enabled.
+ * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
+*/
+void eap_notify_permanent_id_req_denied(struct eap_sm *sm)
+{
+ if (!sm || !sm->eapol_cb->notify_permanent_id_req_denied)
+ return;
+
+ sm->eapol_cb->notify_permanent_id_req_denied(sm->eapol_ctx);
+}
+
/**
* eap_notify_success - Notify EAP state machine about external success trigger