*/
#define RADIUS_SESSION_TIMEOUT 60
+/**
+ * RADIUS_SESSION_MAINTAIN - Completed session expiration timeout in seconds
+ */
+#define RADIUS_SESSION_MAINTAIN 5
+
/**
* RADIUS_MAX_SESSION - Maximum number of active sessions
*/
-#define RADIUS_MAX_SESSION 100
+#define RADIUS_MAX_SESSION 1000
/**
* RADIUS_MAX_MSG_LEN - Maximum message length for incoming RADIUS messages
*/
#define RADIUS_MAX_MSG_LEN 3000
-static struct eapol_callbacks radius_server_eapol_cb;
+static const struct eapol_callbacks radius_server_eapol_cb;
struct radius_client;
struct radius_server_data;
*/
const char *server_id;
+ /**
+ * erp - Whether EAP Re-authentication Protocol (ERP) is enabled
+ *
+ * This controls whether the authentication server derives ERP key
+ * hierarchy (rRK and rIK) from full EAP authentication and allows
+ * these keys to be used to perform ERP to derive rMSK instead of full
+ * EAP authentication to derive MSK.
+ */
+ int erp;
+
+ const char *erp_domain;
+
+ struct dl_list erp_keys; /* struct eap_server_erp_key */
+
+ unsigned int tls_session_lifetime;
+
/**
* wps - Wi-Fi Protected Setup context
*
os_memset(&tmp, 0, sizeof(tmp));
res = data->get_eap_user(data->conf_ctx, user, user_len, 0, &tmp);
- os_free(tmp.password);
+ bin_clear_free(tmp.password, tmp.password_len);
if (res != 0) {
RADIUS_DEBUG("User-Name not found from user database");
sess->accept_attr = tmp.accept_attr;
sess->macacl = tmp.macacl;
- sess->username = os_malloc(user_len * 2 + 1);
+ sess->username = os_malloc(user_len * 4 + 1);
if (sess->username == NULL) {
radius_server_session_free(data, sess);
return NULL;
}
- printf_encode(sess->username, user_len * 2 + 1, user, user_len);
+ printf_encode(sess->username, user_len * 4 + 1, user, user_len);
sess->nas_ip = os_strdup(from_addr);
if (sess->nas_ip == NULL) {
eap_conf.pwd_group = data->pwd_group;
eap_conf.server_id = (const u8 *) data->server_id;
eap_conf.server_id_len = os_strlen(data->server_id);
+ eap_conf.erp = data->erp;
+ eap_conf.tls_session_lifetime = data->tls_session_lifetime;
radius_server_testing_options(sess, &eap_conf);
sess->eap = eap_server_sm_init(sess, &radius_server_eapol_cb,
&eap_conf);
os_strlen(sess->username), 0, &tmp);
if (res || !tmp.macacl || tmp.password == NULL) {
RADIUS_DEBUG("No MAC ACL user entry");
- os_free(tmp.password);
+ bin_clear_free(tmp.password, tmp.password_len);
code = RADIUS_CODE_ACCESS_REJECT;
} else {
u8 buf[128];
(u8 *) client->shared_secret,
client->shared_secret_len,
buf, sizeof(buf));
- os_free(tmp.password);
+ bin_clear_free(tmp.password, tmp.password_len);
if (res < 0 || pw_len != (size_t) res ||
- os_memcmp(pw, buf, res) != 0) {
+ os_memcmp_const(pw, buf, res) != 0) {
RADIUS_DEBUG("Incorrect User-Password");
code = RADIUS_CODE_ACCESS_REJECT;
}
"message");
return -1;
}
-
+
eap = radius_msg_get_eap(msg);
if (eap == NULL && sess->macacl) {
reply = radius_server_macacl(data, client, sess, msg);
sess->sess_id);
eloop_cancel_timeout(radius_server_session_remove_timeout,
data, sess);
- eloop_register_timeout(10, 0,
+ eloop_register_timeout(RADIUS_SESSION_MAINTAIN, 0,
radius_server_session_remove_timeout,
data, sess);
}
if (data == NULL)
return NULL;
+ dl_list_init(&data->erp_keys);
os_get_reltime(&data->start_time);
data->conf_ctx = conf->conf_ctx;
data->eap_sim_db_priv = conf->eap_sim_db_priv;
data->ipv6 = conf->ipv6;
if (conf->pac_opaque_encr_key) {
data->pac_opaque_encr_key = os_malloc(16);
- os_memcpy(data->pac_opaque_encr_key, conf->pac_opaque_encr_key,
- 16);
+ if (data->pac_opaque_encr_key) {
+ os_memcpy(data->pac_opaque_encr_key,
+ conf->pac_opaque_encr_key, 16);
+ }
}
if (conf->eap_fast_a_id) {
data->eap_fast_a_id = os_malloc(conf->eap_fast_a_id_len);
data->eap_req_id_text_len = conf->eap_req_id_text_len;
}
}
+ data->erp = conf->erp;
+ data->erp_domain = conf->erp_domain;
+ data->tls_session_lifetime = conf->tls_session_lifetime;
if (conf->subscr_remediation_url) {
data->subscr_remediation_url =
}
+/**
+ * radius_server_erp_flush - Flush all ERP keys
+ * @data: RADIUS server context from radius_server_init()
+ */
+void radius_server_erp_flush(struct radius_server_data *data)
+{
+ struct eap_server_erp_key *erp;
+
+ if (data == NULL)
+ return;
+ while ((erp = dl_list_first(&data->erp_keys, struct eap_server_erp_key,
+ list)) != NULL) {
+ dl_list_del(&erp->list);
+ bin_clear_free(erp, sizeof(*erp));
+ }
+}
+
+
/**
* radius_server_deinit - Deinitialize RADIUS server
* @data: RADIUS server context from radius_server_init()
sqlite3_close(data->db);
#endif /* CONFIG_SQLITE */
+ radius_server_erp_flush(data);
+
os_free(data);
}
"radiusAuthServResetTime=0\n"
"radiusAuthServConfigReset=4\n",
uptime);
- if (ret < 0 || ret >= end - pos) {
+ if (os_snprintf_error(end - pos, ret)) {
*pos = '\0';
return pos - buf;
}
data->counters.malformed_acct_requests,
data->counters.acct_bad_authenticators,
data->counters.unknown_acct_types);
- if (ret < 0 || ret >= end - pos) {
+ if (os_snprintf_error(end - pos, ret)) {
*pos = '\0';
return pos - buf;
}
if (inet_ntop(AF_INET6, &cli->addr6, abuf,
sizeof(abuf)) == NULL)
abuf[0] = '\0';
- if (inet_ntop(AF_INET6, &cli->mask6, abuf,
+ if (inet_ntop(AF_INET6, &cli->mask6, mbuf,
sizeof(mbuf)) == NULL)
mbuf[0] = '\0';
}
cli->counters.malformed_acct_requests,
cli->counters.acct_bad_authenticators,
cli->counters.unknown_acct_types);
- if (ret < 0 || ret >= end - pos) {
+ if (os_snprintf_error(end - pos, ret)) {
*pos = '\0';
return pos - buf;
}
sess->remediation = user->remediation;
sess->macacl = user->macacl;
}
+
+ if (ret) {
+ RADIUS_DEBUG("%s: User-Name not found from user database",
+ __func__);
+ }
+
return ret;
}
}
-static struct eapol_callbacks radius_server_eapol_cb =
+#ifdef CONFIG_ERP
+
+static const char * radius_server_get_erp_domain(void *ctx)
+{
+ struct radius_session *sess = ctx;
+ struct radius_server_data *data = sess->server;
+
+ return data->erp_domain;
+}
+
+
+static struct eap_server_erp_key *
+radius_server_erp_get_key(void *ctx, const char *keyname)
+{
+ struct radius_session *sess = ctx;
+ struct radius_server_data *data = sess->server;
+ struct eap_server_erp_key *erp;
+
+ dl_list_for_each(erp, &data->erp_keys, struct eap_server_erp_key,
+ list) {
+ if (os_strcmp(erp->keyname_nai, keyname) == 0)
+ return erp;
+ }
+
+ return NULL;
+}
+
+
+static int radius_server_erp_add_key(void *ctx, struct eap_server_erp_key *erp)
+{
+ struct radius_session *sess = ctx;
+ struct radius_server_data *data = sess->server;
+
+ dl_list_add(&data->erp_keys, &erp->list);
+ return 0;
+}
+
+#endif /* CONFIG_ERP */
+
+
+static const struct eapol_callbacks radius_server_eapol_cb =
{
.get_eap_user = radius_server_get_eap_user,
.get_eap_req_id_text = radius_server_get_eap_req_id_text,
.log_msg = radius_server_log_msg,
+#ifdef CONFIG_ERP
+ .get_erp_send_reauth_start = NULL,
+ .get_erp_domain = radius_server_get_erp_domain,
+ .erp_get_key = radius_server_erp_get_key,
+ .erp_add_key = radius_server_erp_add_key,
+#endif /* CONFIG_ERP */
};
sess = s;
break;
}
- if (sess)
- break;
}
if (sess)
break;