| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- From: Felix Fietkau <[email protected]>
- Date: Thu, 16 Mar 2023 11:35:50 +0100
- Subject: [PATCH] hostapd: add experimental radius server
- This can be used to run a standalone EAP server that can be used from
- other APs. It uses json as user database format and can automatically
- handle reload.
- --- a/hostapd/Makefile
- +++ b/hostapd/Makefile
- @@ -63,6 +63,10 @@ endif
- OBJS += main.o
- OBJS += config_file.o
-
- +ifdef CONFIG_RADIUS_SERVER
- +OBJS += radius.o
- +endif
- +
- OBJS += ../src/ap/hostapd.o
- OBJS += ../src/ap/wpa_auth_glue.o
- OBJS += ../src/ap/drv_callbacks.o
- --- a/hostapd/main.c
- +++ b/hostapd/main.c
- @@ -40,6 +40,7 @@ struct hapd_global {
-
- static struct hapd_global global;
-
- +extern int radius_main(int argc, char **argv);
-
- #ifndef CONFIG_NO_HOSTAPD_LOGGER
- static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
- @@ -838,6 +839,11 @@ int main(int argc, char *argv[])
- if (os_program_init())
- return -1;
-
- +#ifdef RADIUS_SERVER
- + if (strstr(argv[0], "radius"))
- + return radius_main(argc, argv);
- +#endif
- +
- os_memset(&interfaces, 0, sizeof(interfaces));
- interfaces.reload_config = hostapd_reload_config;
- interfaces.config_read_cb = hostapd_config_read;
- --- a/src/radius/radius_server.c
- +++ b/src/radius/radius_server.c
- @@ -63,6 +63,12 @@ struct radius_server_counters {
- u32 unknown_acct_types;
- };
-
- +struct radius_accept_attr {
- + u8 type;
- + u16 len;
- + void *data;
- +};
- +
- /**
- * struct radius_session - Internal RADIUS server data for a session
- */
- @@ -89,7 +95,7 @@ struct radius_session {
- unsigned int macacl:1;
- unsigned int t_c_filtering:1;
-
- - struct hostapd_radius_attr *accept_attr;
- + struct radius_accept_attr *accept_attr;
-
- u32 t_c_timestamp; /* Last read T&C timestamp from user DB */
- };
- @@ -373,6 +379,7 @@ static void radius_server_session_free(s
- radius_msg_free(sess->last_reply);
- os_free(sess->username);
- os_free(sess->nas_ip);
- + os_free(sess->accept_attr);
- os_free(sess);
- data->num_sess--;
- }
- @@ -533,6 +540,36 @@ radius_server_erp_find_key(struct radius
- }
- #endif /* CONFIG_ERP */
-
- +static struct radius_accept_attr *
- +radius_server_copy_attr(const struct hostapd_radius_attr *data)
- +{
- + const struct hostapd_radius_attr *attr;
- + struct radius_accept_attr *attr_new;
- + size_t data_size = 0;
- + void *data_buf;
- + int n_attr = 1;
- +
- + for (attr = data; attr; attr = attr->next) {
- + n_attr++;
- + data_size += wpabuf_len(attr->val);
- + }
- +
- + attr_new = os_zalloc(n_attr * sizeof(*attr) + data_size);
- + if (!attr_new)
- + return NULL;
- +
- + data_buf = &attr_new[n_attr];
- + for (n_attr = 0, attr = data; attr; attr = attr->next) {
- + struct radius_accept_attr *cur = &attr_new[n_attr++];
- +
- + cur->type = attr->type;
- + cur->len = wpabuf_len(attr->val);
- + cur->data = memcpy(data_buf, wpabuf_head(attr->val), cur->len);
- + data_buf += cur->len;
- + }
- +
- + return attr_new;
- +}
-
- static struct radius_session *
- radius_server_get_new_session(struct radius_server_data *data,
- @@ -586,7 +623,7 @@ radius_server_get_new_session(struct rad
- eap_user_free(tmp);
- return NULL;
- }
- - sess->accept_attr = tmp->accept_attr;
- + sess->accept_attr = radius_server_copy_attr(tmp->accept_attr);
- sess->macacl = tmp->macacl;
- eap_user_free(tmp);
-
- @@ -923,11 +960,10 @@ radius_server_encapsulate_eap(struct rad
- }
-
- if (code == RADIUS_CODE_ACCESS_ACCEPT) {
- - struct hostapd_radius_attr *attr;
- - for (attr = sess->accept_attr; attr; attr = attr->next) {
- - if (!radius_msg_add_attr(msg, attr->type,
- - wpabuf_head(attr->val),
- - wpabuf_len(attr->val))) {
- + struct radius_accept_attr *attr;
- + for (attr = sess->accept_attr; attr->data; attr++) {
- + if (!radius_msg_add_attr(msg, attr->type, attr->data,
- + attr->len)) {
- wpa_printf(MSG_ERROR, "Could not add RADIUS attribute");
- radius_msg_free(msg);
- return NULL;
- @@ -1023,11 +1059,10 @@ radius_server_macacl(struct radius_serve
- }
-
- if (code == RADIUS_CODE_ACCESS_ACCEPT) {
- - struct hostapd_radius_attr *attr;
- - for (attr = sess->accept_attr; attr; attr = attr->next) {
- - if (!radius_msg_add_attr(msg, attr->type,
- - wpabuf_head(attr->val),
- - wpabuf_len(attr->val))) {
- + struct radius_accept_attr *attr;
- + for (attr = sess->accept_attr; attr->data; attr++) {
- + if (!radius_msg_add_attr(msg, attr->type, attr->data,
- + attr->len)) {
- wpa_printf(MSG_ERROR, "Could not add RADIUS attribute");
- radius_msg_free(msg);
- return NULL;
- @@ -2335,7 +2370,7 @@ static int radius_server_get_eap_user(vo
- ret = data->get_eap_user(data->conf_ctx, identity, identity_len,
- phase2, user);
- if (ret == 0 && user) {
- - sess->accept_attr = user->accept_attr;
- + sess->accept_attr = radius_server_copy_attr(user->accept_attr);
- sess->macacl = user->macacl;
- sess->t_c_timestamp = user->t_c_timestamp;
- }
|