From 9828aba16eeefc489addf28fe5ef6314f6d9194d Mon Sep 17 00:00:00 2001 From: Chaoli Zhou Date: Thu, 24 Mar 2022 14:34:18 +0800 Subject: [PATCH] Support ACL operations in wpa_supplicant AP mode Extend AP mode ACL control interface commands to work from wpa_supplicant in addition to the previously supported hostapd case. Signed-off-by: Chaoli Zhou --- wpa_supplicant/ap.c | 123 ++++++++++++++++++++++++++++++++++++ wpa_supplicant/ap.h | 13 ++++ wpa_supplicant/ctrl_iface.c | 45 +++++++++++++ 3 files changed, 181 insertions(+) diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index 0d117b4ed..a31734728 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -1610,6 +1610,129 @@ int ap_ctrl_iface_bss_tm_req(struct wpa_supplicant *wpa_s, const char *buf) #endif /* CONFIG_WNM_AP */ + +int ap_ctrl_iface_acl_add_mac(struct wpa_supplicant *wpa_s, + enum macaddr_acl acl_type, + const char *buf) +{ + struct hostapd_data *hapd; + + if (wpa_s->ap_iface) + hapd = wpa_s->ap_iface->bss[0]; + else + return -1; + + hapd->conf->macaddr_acl = acl_type; + + if (acl_type == ACCEPT_UNLESS_DENIED) + return hostapd_ctrl_iface_acl_add_mac(&hapd->conf->deny_mac, + &hapd->conf->num_deny_mac, + buf); + if (acl_type == DENY_UNLESS_ACCEPTED) + return hostapd_ctrl_iface_acl_add_mac( + &hapd->conf->accept_mac, + &hapd->conf->num_accept_mac, buf); + + return -1; +} + + +int ap_ctrl_iface_acl_del_mac(struct wpa_supplicant *wpa_s, + enum macaddr_acl acl_type, + const char *buf) +{ + struct hostapd_data *hapd; + + if (wpa_s->ap_iface) + hapd = wpa_s->ap_iface->bss[0]; + else + return -1; + + hapd->conf->macaddr_acl = acl_type; + + if (acl_type == ACCEPT_UNLESS_DENIED) + return hostapd_ctrl_iface_acl_del_mac(&hapd->conf->deny_mac, + &hapd->conf->num_deny_mac, + buf); + if (acl_type == DENY_UNLESS_ACCEPTED) + return hostapd_ctrl_iface_acl_del_mac( + &hapd->conf->accept_mac, &hapd->conf->num_accept_mac, + buf); + + return -1; +} + + +int ap_ctrl_iface_acl_show_mac(struct wpa_supplicant *wpa_s, + enum macaddr_acl acl_type, char *buf, + size_t buflen) +{ + struct hostapd_data *hapd; + + if (wpa_s->ap_iface) + hapd = wpa_s->ap_iface->bss[0]; + else + return -1; + + if (acl_type == ACCEPT_UNLESS_DENIED) + return hostapd_ctrl_iface_acl_show_mac(hapd->conf->deny_mac, + hapd->conf->num_deny_mac, + buf, buflen); + if (acl_type == DENY_UNLESS_ACCEPTED) + return hostapd_ctrl_iface_acl_show_mac( + hapd->conf->accept_mac, hapd->conf->num_accept_mac, + buf, buflen); + + return -1; +} + + +void ap_ctrl_iface_acl_clear_list(struct wpa_supplicant *wpa_s, + enum macaddr_acl acl_type) +{ + struct hostapd_data *hapd; + + if (wpa_s->ap_iface) + hapd = wpa_s->ap_iface->bss[0]; + else + return; + + hapd->conf->macaddr_acl = acl_type; + + if (acl_type == ACCEPT_UNLESS_DENIED) + hostapd_ctrl_iface_acl_clear_list(&hapd->conf->deny_mac, + &hapd->conf->num_deny_mac); + else if (acl_type == DENY_UNLESS_ACCEPTED) + hostapd_ctrl_iface_acl_clear_list(&hapd->conf->accept_mac, + &hapd->conf->num_accept_mac); +} + + +int ap_ctrl_iface_disassoc_deny_mac(struct wpa_supplicant *wpa_s) +{ + struct hostapd_data *hapd; + + if (wpa_s->ap_iface) + hapd = wpa_s->ap_iface->bss[0]; + else + return -1; + + return hostapd_disassoc_deny_mac(hapd); +} + + +int ap_ctrl_iface_disassoc_accept_mac(struct wpa_supplicant *wpa_s) +{ + struct hostapd_data *hapd; + + if (wpa_s->ap_iface) + hapd = wpa_s->ap_iface->bss[0]; + else + return -1; + + return hostapd_disassoc_accept_mac(hapd); +} + #endif /* CONFIG_CTRL_IFACE */ diff --git a/wpa_supplicant/ap.h b/wpa_supplicant/ap.h index 3e20ac1bb..c23d218fd 100644 --- a/wpa_supplicant/ap.h +++ b/wpa_supplicant/ap.h @@ -10,6 +10,8 @@ #ifndef AP_H #define AP_H +enum macaddr_acl; + int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s); @@ -42,6 +44,17 @@ int ap_ctrl_iface_disassoc_imminent(struct wpa_supplicant *wpa_s, const char *buf); int ap_ctrl_iface_ess_disassoc(struct wpa_supplicant *wpa_s, const char *buf); int ap_ctrl_iface_bss_tm_req(struct wpa_supplicant *wpa_s, const char *buf); +int ap_ctrl_iface_acl_add_mac(struct wpa_supplicant *wpa_s, + enum macaddr_acl acl_type, const char *buf); +int ap_ctrl_iface_acl_del_mac(struct wpa_supplicant *wpa_s, + enum macaddr_acl acl_type, const char *buf); +int ap_ctrl_iface_acl_show_mac(struct wpa_supplicant *wpa_s, + enum macaddr_acl acl_type, char *buf, + size_t buflen); +void ap_ctrl_iface_acl_clear_list(struct wpa_supplicant *wpa_s, + enum macaddr_acl acl_type); +int ap_ctrl_iface_disassoc_deny_mac(struct wpa_supplicant *wpa_s); +int ap_ctrl_iface_disassoc_accept_mac(struct wpa_supplicant *wpa_s); void ap_tx_status(void *ctx, const u8 *addr, const u8 *buf, size_t len, int ack); void ap_eapol_tx_status(void *ctx, const u8 *dst, diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 078a8110d..4c5407d09 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -12022,6 +12022,51 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strcmp(buf, "UPDATE_BEACON") == 0) { if (wpas_ap_update_beacon(wpa_s)) reply_len = -1; + } else if (os_strncmp(buf, "ACCEPT_ACL ", 11) == 0) { + if (os_strncmp(buf + 11, "ADD_MAC ", 8) == 0) { + if (ap_ctrl_iface_acl_add_mac(wpa_s, + DENY_UNLESS_ACCEPTED, + buf + 19)) + reply_len = -1; + } else if (os_strncmp((buf + 11), "DEL_MAC ", 8) == 0) { + if (ap_ctrl_iface_acl_del_mac(wpa_s, + DENY_UNLESS_ACCEPTED, + buf + 19) || + ap_ctrl_iface_disassoc_accept_mac(wpa_s)) + reply_len = -1; + } else if (os_strcmp(buf + 11, "SHOW") == 0) { + reply_len = ap_ctrl_iface_acl_show_mac( + wpa_s, DENY_UNLESS_ACCEPTED, + reply, reply_size); + } else if (os_strcmp(buf + 11, "CLEAR") == 0) { + ap_ctrl_iface_acl_clear_list(wpa_s, + DENY_UNLESS_ACCEPTED); + if (ap_ctrl_iface_disassoc_accept_mac(wpa_s)) + reply_len = -1; + } else { + reply_len = -1; + } + } else if (os_strncmp(buf, "DENY_ACL ", 9) == 0) { + if (os_strncmp(buf + 9, "ADD_MAC ", 8) == 0) { + if (ap_ctrl_iface_acl_add_mac(wpa_s, + ACCEPT_UNLESS_DENIED, + buf + 17) || + ap_ctrl_iface_disassoc_deny_mac(wpa_s)) + reply_len = -1; + } else if (os_strncmp(buf + 9, "DEL_MAC ", 8) == 0) { + if (ap_ctrl_iface_acl_del_mac(wpa_s, + ACCEPT_UNLESS_DENIED, + buf + 17)) + reply_len = -1; + } else if (os_strcmp(buf + 9, "SHOW") == 0) { + reply_len = ap_ctrl_iface_acl_show_mac( + wpa_s, ACCEPT_UNLESS_DENIED, reply, reply_size); + } else if (os_strcmp(buf + 9, "CLEAR") == 0) { + ap_ctrl_iface_acl_clear_list(wpa_s, + ACCEPT_UNLESS_DENIED); + } else { + reply_len = -1; + } #endif /* CONFIG_AP */ } else if (os_strcmp(buf, "SUSPEND") == 0) { wpas_notify_suspend(wpa_s->global);