WPS: Use WEP key index 1..4 instead of 0..3 when configuring AP
[wpasupplicant] / hostapd / ieee802_11_auth.c
index a705374..3abbc64 100644 (file)
  * license.
  *
  * See README and COPYING for more details.
+ *
+ * Access control list for IEEE 802.11 authentication can uses statically
+ * configured ACL from configuration files or an external RADIUS server.
+ * Results from external RADIUS queries are cached to allow faster
+ * authentication frame processing.
  */
 
 #include "includes.h"
@@ -47,6 +52,7 @@ struct hostapd_acl_query_data {
 };
 
 
+#ifndef CONFIG_NO_RADIUS
 static void hostapd_acl_cache_free(struct hostapd_cached_radius_acl *acl_cache)
 {
        struct hostapd_cached_radius_acl *prev;
@@ -74,8 +80,12 @@ static int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr,
                        if (now - entry->timestamp > RADIUS_ACL_TIMEOUT)
                                return -1; /* entry has expired */
                        if (entry->accepted == HOSTAPD_ACL_ACCEPT_TIMEOUT)
-                               *session_timeout = entry->session_timeout;
-                       *acct_interim_interval = entry->acct_interim_interval;
+                               if (session_timeout)
+                                       *session_timeout =
+                                               entry->session_timeout;
+                       if (acct_interim_interval)
+                               *acct_interim_interval =
+                                       entry->acct_interim_interval;
                        if (vlan_id)
                                *vlan_id = entry->vlan_id;
                        return entry->accepted;
@@ -86,6 +96,7 @@ static int hostapd_acl_cache_get(struct hostapd_data *hapd, const u8 *addr,
 
        return -1;
 }
+#endif /* CONFIG_NO_RADIUS */
 
 
 static void hostapd_acl_query_free(struct hostapd_acl_query_data *query)
@@ -97,6 +108,7 @@ static void hostapd_acl_query_free(struct hostapd_acl_query_data *query)
 }
 
 
+#ifndef CONFIG_NO_RADIUS
 static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
                                    struct hostapd_acl_query_data *query)
 {
@@ -186,23 +198,37 @@ static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
        os_free(msg);
        return -1;
 }
-
-
+#endif /* CONFIG_NO_RADIUS */
+
+
+/**
+ * hostapd_allowed_address - Check whether a specified STA can be authenticated
+ * @hapd: hostapd BSS data
+ * @addr: MAC address of the STA
+ * @msg: Authentication message
+ * @len: Length of msg in octets
+ * @session_timeout: Buffer for returning session timeout (from RADIUS)
+ * @acct_interim_interval: Buffer for returning account interval (from RADIUS)
+ * @vlan_id: Buffer for returning VLAN ID
+ * Returns: HOSTAPD_ACL_ACCEPT, HOSTAPD_ACL_REJECT, or HOSTAPD_ACL_PENDING
+ */
 int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
                            const u8 *msg, size_t len, u32 *session_timeout,
                            u32 *acct_interim_interval, int *vlan_id)
 {
-       *session_timeout = 0;
-       *acct_interim_interval = 0;
+       if (session_timeout)
+               *session_timeout = 0;
+       if (acct_interim_interval)
+               *acct_interim_interval = 0;
        if (vlan_id)
                *vlan_id = 0;
 
        if (hostapd_maclist_found(hapd->conf->accept_mac,
-                                 hapd->conf->num_accept_mac, addr))
+                                 hapd->conf->num_accept_mac, addr, vlan_id))
                return HOSTAPD_ACL_ACCEPT;
 
        if (hostapd_maclist_found(hapd->conf->deny_mac,
-                                 hapd->conf->num_deny_mac, addr))
+                                 hapd->conf->num_deny_mac, addr, vlan_id))
                return HOSTAPD_ACL_REJECT;
 
        if (hapd->conf->macaddr_acl == ACCEPT_UNLESS_DENIED)
@@ -211,6 +237,9 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
                return HOSTAPD_ACL_REJECT;
 
        if (hapd->conf->macaddr_acl == USE_EXTERNAL_RADIUS_AUTH) {
+#ifdef CONFIG_NO_RADIUS
+               return HOSTAPD_ACL_REJECT;
+#else /* CONFIG_NO_RADIUS */
                struct hostapd_acl_query_data *query;
 
                /* Check whether ACL cache has an entry for this station */
@@ -266,12 +295,14 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
                /* Queued data will be processed in hostapd_acl_recv_radius()
                 * when RADIUS server replies to the sent Access-Request. */
                return HOSTAPD_ACL_PENDING;
+#endif /* CONFIG_NO_RADIUS */
        }
 
        return HOSTAPD_ACL_REJECT;
 }
 
 
+#ifndef CONFIG_NO_RADIUS
 static void hostapd_acl_expire_cache(struct hostapd_data *hapd, time_t now)
 {
        struct hostapd_cached_radius_acl *prev, *entry, *tmp;
@@ -287,7 +318,9 @@ static void hostapd_acl_expire_cache(struct hostapd_data *hapd, time_t now)
                                prev->next = entry->next;
                        else
                                hapd->acl_cache = entry->next;
-
+#ifdef CONFIG_DRIVER_RADIUS_ACL
+                       hostapd_set_radius_acl_expire(hapd, entry->addr);
+#endif /* CONFIG_DRIVER_RADIUS_ACL */
                        tmp = entry;
                        entry = entry->next;
                        os_free(tmp);
@@ -328,6 +361,11 @@ static void hostapd_acl_expire_queries(struct hostapd_data *hapd, time_t now)
 }
 
 
+/**
+ * hostapd_acl_expire - ACL cache expiration callback
+ * @eloop_ctx: struct hostapd_data *
+ * @timeout_ctx: Not used
+ */
 static void hostapd_acl_expire(void *eloop_ctx, void *timeout_ctx)
 {
        struct hostapd_data *hapd = eloop_ctx;
@@ -341,11 +379,19 @@ static void hostapd_acl_expire(void *eloop_ctx, void *timeout_ctx)
 }
 
 
-/* Return 0 if RADIUS message was a reply to ACL query (and was processed here)
- * or -1 if not. */
+/**
+ * hostapd_acl_recv_radius - Process incoming RADIUS Authentication messages
+ * @msg: RADIUS response message
+ * @req: RADIUS request message
+ * @shared_secret: RADIUS shared secret
+ * @shared_secret_len: Length of shared_secret in octets
+ * @data: Context data (struct hostapd_data *)
+ * Returns: RADIUS_RX_PROCESSED if RADIUS message was a reply to ACL query (and
+ * was processed here) or RADIUS_RX_UNKNOWN if not.
+ */
 static RadiusRxResult
 hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
-                       u8 *shared_secret, size_t shared_secret_len,
+                       const u8 *shared_secret, size_t shared_secret_len,
                        void *data)
 {
        struct hostapd_data *hapd = data;
@@ -411,11 +457,18 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
        cache->next = hapd->acl_cache;
        hapd->acl_cache = cache;
 
+#ifdef CONFIG_DRIVER_RADIUS_ACL
+       hostapd_set_radius_acl_auth(hapd, query->addr, cache->accepted,
+                                   cache->session_timeout);
+#else /* CONFIG_DRIVER_RADIUS_ACL */
+#ifdef NEED_MLME
        /* Re-send original authentication frame for 802.11 processing */
        wpa_printf(MSG_DEBUG, "Re-sending authentication frame after "
                   "successful RADIUS ACL query");
        ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len,
                        WLAN_FC_STYPE_AUTH, NULL);
+#endif /* NEED_MLME */
+#endif /* CONFIG_DRIVER_RADIUS_ACL */
 
  done:
        if (prev == NULL)
@@ -427,27 +480,41 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
 
        return RADIUS_RX_PROCESSED;
 }
+#endif /* CONFIG_NO_RADIUS */
 
 
+/**
+ * hostapd_acl_init: Initialize IEEE 802.11 ACL
+ * @hapd: hostapd BSS data
+ * Returns: 0 on success, -1 on failure
+ */
 int hostapd_acl_init(struct hostapd_data *hapd)
 {
+#ifndef CONFIG_NO_RADIUS
        if (radius_client_register(hapd->radius, RADIUS_AUTH,
                                   hostapd_acl_recv_radius, hapd))
                return -1;
 
        eloop_register_timeout(10, 0, hostapd_acl_expire, hapd, NULL);
+#endif /* CONFIG_NO_RADIUS */
 
        return 0;
 }
 
 
+/**
+ * hostapd_acl_deinit - Deinitialize IEEE 802.11 ACL
+ * @hapd: hostapd BSS data
+ */
 void hostapd_acl_deinit(struct hostapd_data *hapd)
 {
        struct hostapd_acl_query_data *query, *prev;
 
+#ifndef CONFIG_NO_RADIUS
        eloop_cancel_timeout(hostapd_acl_expire, hapd, NULL);
 
        hostapd_acl_cache_free(hapd->acl_cache);
+#endif /* CONFIG_NO_RADIUS */
 
        query = hapd->acl_queries;
        while (query) {