From patchwork Thu Apr 19 23:35:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nils Nieuwejaar X-Patchwork-Id: 901559 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Vj5db3dC"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="KXDiHeGc"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40RwNj5Y2Pz9s4q for ; Fri, 20 Apr 2018 09:36:14 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=TQL8SR5TCM+yBXTRzixEl8i5LiyJ5Opkk7FFEdCH8HM=; b=Vj5db3dC/9N5PZUtopnRxJzTvX 06eDevKdyfnQBJsQ/MPePOjhL6O8gRALBM9DF5Aoh3wLw3IsZ8tGTK1OMGzPZC7t9p9g1gKJ6YgTz apV9vUgQ1qlfb4OIzXYvP6wRPlPsevaPq0Gdkq0oIVVZmLLa+ykwc7BZa6ZIMEW+QlusYNOFgK06c TDr184LfjvcbT32MUzdLcnKAIP4iqD8kxj939gIwyW1KXC6ml+XozaoISDVG2pohy3LkcpxPykDkY puFAByyoGXbJ1AOIfGtovdJKfWadJDn4bIcFA9dy1b1vG0jxo71k7ruYTHBV4TURjrgWpteaapiOP Yo9MuXEw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1f9J5z-0007m6-Iz; Thu, 19 Apr 2018 23:36:07 +0000 Received: from mail-pf0-x22f.google.com ([2607:f8b0:400e:c00::22f]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1f9J5v-0007lJ-8g for hostap@lists.infradead.org; Thu, 19 Apr 2018 23:36:05 +0000 Received: by mail-pf0-x22f.google.com with SMTP id l27so3372220pfk.12 for ; Thu, 19 Apr 2018 16:35:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=yB/hruYsoiZ0l7k0akgO9sJSl+9mILoSzP3MYLy+nxQ=; b=KXDiHeGcNufWqs4ViSTD/xCebBiPbuY1p1JT7epIUM/ET9iF4kyt7TfamcXIn3eoQH GNye4YEIwUL/2Dp6nrWSSUeHAennoZlQ5PX2j30yF1sNVkAp91ytacs2Xgt2/SdMlKh9 t1uMOdYnTzZGBBW4crbzv+Wu3FKvWjmi8RDcVH5t4KTe/086ro13pTd4dQELLOIkhyuI isbif2RLVEe/+O8LpqXsO0ZQH4s1AmCSfCOxXCX3c6HCySnj22+GZnhYXERCD/q7gVwY 2cFMqp9wjKzyWRsBUzhPgvieYM8XUubux5bMcltdIPmJPSDHuwJORN11fVKNlM8SVzib er1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=yB/hruYsoiZ0l7k0akgO9sJSl+9mILoSzP3MYLy+nxQ=; b=sV0iB5t+mkcadQrOxjOWlxAw77fuGVQgJTmfZJogA+2sv7ZftS6bgeuqqgkUjxd7Y5 tgF4kWbhj6i1DKyeBFB1l7dgX/ykuN640YeGrRkQ4+wCwJ4dD/IV2++fJivuXYvlFTas /s8WkUvh7GHQj3oJfEdf2Pu2DpbFMzBLWTZ2/+mlT+Da1ax+z9ZYfdpnZn8i+T0GFq7B CV4QXhW/IQk2o+OEoKO1P8P9fa5NHf+TeKhoMFxkjHuI5fFBkraI8UddMBpgxIhZ4Ga1 2OfFliBsjijRhsxonjYxc5O8gC46e3PmZwOdqs3s/GIzgKNfwk6heRp8aebAZSjApuXU 3UlQ== X-Gm-Message-State: ALQs6tBIIqW1+to9oNstgdPn60sQGVrFhMscJkIu4yTDfRtk8kU6wi52 RxfdpqmVQ+Xb8gtrRS0iD1xv4J4J X-Google-Smtp-Source: AIpwx48/Ubk4wSdK7lW7lsBYBzT5Ti0aW3+gVaTPeMD3p3QUXTMs+o9RtV8BGjd/TE2JaJNQR4sVwQ== X-Received: by 10.98.150.75 with SMTP id c72mr7490237pfe.62.1524180951984; Thu, 19 Apr 2018 16:35:51 -0700 (PDT) Received: from moose.7410.brightgate.net (c-24-130-129-211.hsd1.ca.comcast.net. [24.130.129.211]) by smtp.gmail.com with ESMTPSA id z127sm8051788pfb.72.2018.04.19.16.35.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Apr 2018 16:35:51 -0700 (PDT) From: Nils Nieuwejaar To: hostap@lists.infradead.org Subject: [PATCH] Allow remote RADIUS authentication with local VLAN management Date: Thu, 19 Apr 2018 16:35:49 -0700 Message-Id: <20180419233549.30190-1-nils.nieuwejaar@gmail.com> X-Mailer: git-send-email 2.15.1 (Apple Git-101) In-Reply-To: <20180419222127.GB1665@w1.fi> References: <20180419222127.GB1665@w1.fi> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180419_163603_338877_9DC5F054 X-CRM114-Status: GOOD ( 18.50 ) X-Spam-Score: -0.1 (/) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-0.1 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [2607:f8b0:400e:c00:0:0:0:22f listed in] [list.dnswl.org] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (nils.nieuwejaar[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Nils Nieuwejaar MIME-Version: 1.0 Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org If dynamic_vlan=0 (disabled), then vlan assignments will be managed using the local accept_mac_file ACL file, even if a RADIUS server if being used for user authentication. This allows us to manage users and devices independently. Signed-off-by: Nils Nieuwejaar --- hostapd/hostapd.conf | 2 +- src/ap/ieee802_11_auth.c | 17 +++++---- src/ap/ieee802_1x.c | 90 +++++++++++++++++++++++++----------------------- src/ap/sta_info.c | 3 -- 4 files changed, 58 insertions(+), 54 deletions(-) diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 220625651..7f13b147d 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1104,7 +1104,7 @@ own_ip_addr=127.0.0.1 # Tunnel-Medium-Type (value 6 = IEEE 802), Tunnel-Private-Group-ID (value # VLANID as a string). Optionally, the local MAC ACL list (accept_mac_file) can # be used to set static client MAC address to VLAN ID mapping. -# 0 = disabled (default) +# 0 = disabled (default); only VLAN IDs from accept_mac_file will be used # 1 = option; use default interface if RADIUS server does not include VLAN ID # 2 = required; reject authentication if RADIUS server does not include VLAN ID #dynamic_vlan=0 diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c index 5cb7fb145..b2ea12c3a 100644 --- a/src/ap/ieee802_11_auth.c +++ b/src/ap/ieee802_11_auth.c @@ -289,6 +289,9 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr, return HOSTAPD_ACL_ACCEPT; }; + if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_DISABLED) + vlan_id = NULL; + /* Check whether ACL cache has an entry for this station */ res = hostapd_acl_cache_get(hapd, addr, session_timeout, acct_interim_interval, vlan_id, psk, @@ -574,12 +577,14 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req, cache->acct_interim_interval = 0; } - notempty = &cache->vlan_id.notempty; - untagged = &cache->vlan_id.untagged; - tagged = cache->vlan_id.tagged; - *notempty = !!radius_msg_get_vlanid(msg, untagged, - MAX_NUM_TAGGED_VLAN, - tagged); + if (hapd->conf->ssid.dynamic_vlan != DYNAMIC_VLAN_DISABLED) { + notempty = &cache->vlan_id.notempty; + untagged = &cache->vlan_id.untagged; + tagged = cache->vlan_id.tagged; + *notempty = !!radius_msg_get_vlanid(msg, untagged, + MAX_NUM_TAGGED_VLAN, + tagged); + } decode_tunnel_passwords(hapd, shared_secret, shared_secret_len, msg, req, cache); diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c index 4fcccce72..ffff58d55 100644 --- a/src/ap/ieee802_1x.c +++ b/src/ap/ieee802_1x.c @@ -1683,6 +1683,49 @@ ieee802_1x_search_radius_identifier(struct hostapd_data *hapd, u8 identifier) } +#ifndef CONFIG_NO_VLAN +static int +ieee802_1x_update_vlan(struct radius_msg *msg, + struct hostapd_data *hapd, + struct sta_info *sta) +{ + struct vlan_description vlan_desc; + int *untagged, *tagged, *notempty; + + os_memset(&vlan_desc, 0, sizeof(vlan_desc)); + notempty = &vlan_desc.notempty; + untagged = &vlan_desc.untagged; + tagged = vlan_desc.tagged; + *notempty = !!radius_msg_get_vlanid(msg, untagged, MAX_NUM_TAGGED_VLAN, + tagged); + + if (vlan_desc.notempty && + !hostapd_vlan_valid(hapd->conf->vlan, &vlan_desc)) { + sta->eapol_sm->authFail = TRUE; + hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS, + HOSTAPD_LEVEL_INFO, + "Invalid VLAN %d%s received from RADIUS server", + vlan_desc.untagged, + vlan_desc.tagged[0] ? "+" : ""); + os_memset(&vlan_desc, 0, sizeof(vlan_desc)); + ap_sta_set_vlan(hapd, sta, &vlan_desc); + return -1; + } + + if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_REQUIRED && + !vlan_desc.notempty) { + sta->eapol_sm->authFail = TRUE; + hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, + HOSTAPD_LEVEL_INFO, "authentication server did " + "not include required VLAN ID in Access-Accept"); + return -1; + } + + return (ap_sta_set_vlan(hapd, sta, &vlan_desc)); +} +#endif /* CONFIG_NO_VLAN */ + + /** * ieee802_1x_receive_auth - Process RADIUS frames from Authentication Server * @msg: RADIUS response message @@ -1705,12 +1748,6 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, struct eapol_state_machine *sm; int override_eapReq = 0; struct radius_hdr *hdr = radius_msg_get_hdr(msg); - struct vlan_description vlan_desc; -#ifndef CONFIG_NO_VLAN - int *untagged, *tagged, *notempty; -#endif /* CONFIG_NO_VLAN */ - - os_memset(&vlan_desc, 0, sizeof(vlan_desc)); sm = ieee802_1x_search_radius_identifier(hapd, hdr->identifier); if (sm == NULL) { @@ -1775,56 +1812,21 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req, switch (hdr->code) { case RADIUS_CODE_ACCESS_ACCEPT: #ifndef CONFIG_NO_VLAN - if (hapd->conf->ssid.dynamic_vlan != DYNAMIC_VLAN_DISABLED) { - notempty = &vlan_desc.notempty; - untagged = &vlan_desc.untagged; - tagged = vlan_desc.tagged; - *notempty = !!radius_msg_get_vlanid(msg, untagged, - MAX_NUM_TAGGED_VLAN, - tagged); - } - - if (vlan_desc.notempty && - !hostapd_vlan_valid(hapd->conf->vlan, &vlan_desc)) { - sta->eapol_sm->authFail = TRUE; - hostapd_logger(hapd, sta->addr, - HOSTAPD_MODULE_RADIUS, - HOSTAPD_LEVEL_INFO, - "Invalid VLAN %d%s received from RADIUS server", - vlan_desc.untagged, - vlan_desc.tagged[0] ? "+" : ""); - os_memset(&vlan_desc, 0, sizeof(vlan_desc)); - ap_sta_set_vlan(hapd, sta, &vlan_desc); - break; - } - - if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_REQUIRED && - !vlan_desc.notempty) { - sta->eapol_sm->authFail = TRUE; - hostapd_logger(hapd, sta->addr, - HOSTAPD_MODULE_IEEE8021X, - HOSTAPD_LEVEL_INFO, "authentication " - "server did not include required VLAN " - "ID in Access-Accept"); - break; - } -#endif /* CONFIG_NO_VLAN */ - - if (ap_sta_set_vlan(hapd, sta, &vlan_desc) < 0) + if (hapd->conf->ssid.dynamic_vlan != DYNAMIC_VLAN_DISABLED && + ieee802_1x_update_vlan(msg, hapd, sta) < 0) break; -#ifndef CONFIG_NO_VLAN if (sta->vlan_id > 0) { hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id); } -#endif /* CONFIG_NO_VLAN */ if ((sta->flags & WLAN_STA_ASSOC) && ap_sta_bind_vlan(hapd, sta) < 0) break; +#endif /* CONFIG_NO_VLAN */ sta->session_timeout_set = !!session_timeout_set; os_get_reltime(&sta->session_timeout); diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c index cb9be2832..94833ee1e 100644 --- a/src/ap/sta_info.c +++ b/src/ap/sta_info.c @@ -893,9 +893,6 @@ int ap_sta_set_vlan(struct hostapd_data *hapd, struct sta_info *sta, struct hostapd_vlan *vlan = NULL, *wildcard_vlan = NULL; int old_vlan_id, vlan_id = 0, ret = 0; - if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_DISABLED) - vlan_desc = NULL; - /* Check if there is something to do */ if (hapd->conf->ssid.per_sta_vif && !sta->vlan_id) { /* This sta is lacking its own vif */