From patchwork Fri Dec 3 11:18:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Magnus Malm X-Patchwork-Id: 1563173 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=WBjtjir1; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=d/ixM4n9; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=none (no SPF record) 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=) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4J59NF31fzz9sR4 for ; Fri, 3 Dec 2021 22:20:13 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=2DE43seD6JDGXEjV8BrrxpGcHz2+nhWzc8ybHKHVvVo=; b=WBjtjir1FzVYVf RszS+VqW8OtA+4JpOMQJR3/QunpnwLlg4h4ch1aoIvZbvoYH1UetxqY8nQBLfWZREtBjOUi0fPc85 EYjw9AbsyAokTHaYKJFE89LnPHefGt7Hm5P/NyjXYwMiJHKFfrUOpytDj+AB+3SFudPP1LnHx9k0C EF6htsSIqomJOLe8ChkQFp1oYfaMHnNjsRNCj+0W5sY5NN9PB+97YlIuTrIS9kyEYr0HmD55yW00r Ig1E0GNEtOMKx4L0qX9k25vtzgowV7w594OquDKrA9Fi73y9KvlCictGwuRzNpPtl5xvBOhDzo4G0 gZe7+GJVc/8hJCWQiSJA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mt6ah-00FKFl-P1; Fri, 03 Dec 2021 11:18:59 +0000 Received: from mail-lf1-x12c.google.com ([2a00:1450:4864:20::12c]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mt6aW-00FKE1-7a for hostap@lists.infradead.org; Fri, 03 Dec 2021 11:18:49 +0000 Received: by mail-lf1-x12c.google.com with SMTP id u3so5748184lfl.2 for ; Fri, 03 Dec 2021 03:18:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=LoJ0CiQJQp9pDw/20fa+gYmZ5EmSQswkWNkSWD98gv4=; b=d/ixM4n9qydwEkEjbk2gWariYcXo4XWAz5AxxgVAVsL/nUQfMv0WG/DUlj8p0uuIU1 cdnyFoyEHlOLJ555TStxDGAKFxZ5f6zFekYB0gLFQM5GEXTysXhFJNeL1qcv706OeUaX UXp3UtFXF8cQMAkUK8fXMoi8Nc5jgeoiYR9IBxHuLcuIR4pmtV6sMM++IevWxdGnCi/E 7pmVXPV10gGPSK6JnPA6YKLis6cKqndA6Rff7izl+rwin21ASJsAHKsK2P+8ilxkpzI7 h1AQIgoHjKRTX+c9mbtMgH4ZTh8p7OV6hgMIyHGPE9olUpAgMQsLRYP2rTIqP5JjDT7e x49A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LoJ0CiQJQp9pDw/20fa+gYmZ5EmSQswkWNkSWD98gv4=; b=EKj1swW88bnAENj2yHx5uLce95EN8EiB4aRtcdrEzZJd3KY27hbnnmzprNQTKvLsAs mjySUrIRoD58Yw6EF69ipynuzCcG60gco96scTiJOvpiBKjAhr4kSnIL3kHHCOW/KC3b PXsII4RnpDDPRDnyVmchnGLGxaHkr0IFU1ByCq1/Wri7ks2D7lVDor2tQU2JKUHWvSSa SHX1pDaLBYl7hL07b82w6jB3C4smW6Z62SRAqxf9yLQ6cBNA9IlTOXnoT3ryYQuH57Fe HtIPGUtsIAwn3/sjvRO4dar5DVleibLLm2mtFfGf0OOmRYO6myZLNTrrAxbsNHoWylnF hYbw== X-Gm-Message-State: AOAM532wA/h7MfhgLc6FgPUxJ2CVRWWPRv3aIy98PiwxJ7Rgui3geaXd WpU4OayUGRPEnGLSWoEvGeUd3o09Nxc= X-Google-Smtp-Source: ABdhPJzOCBXxOigdBnjbIrmbh4eHBgaaoo4RSaYgxzfMaEP9XqW2Zdghw7o/0GzKRPjMm4lFCxf2KQ== X-Received: by 2002:ac2:5d67:: with SMTP id h7mr17411693lft.493.1638530325292; Fri, 03 Dec 2021 03:18:45 -0800 (PST) Received: from starbase.westermo.com (c-80f6235c.03-274-6f72655.bbcust.telenor.se. [92.35.246.128]) by smtp.googlemail.com with ESMTPSA id k11sm331656lfo.111.2021.12.03.03.18.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Dec 2021 03:18:44 -0800 (PST) From: Magnus Malm To: hostap@lists.infradead.org Cc: Magnus Malm Subject: [PATCH 1/1] Add FQDN support for auth and acct server addresses Date: Fri, 3 Dec 2021 12:18:41 +0100 Message-Id: <20211203111841.3631616-2-magnusmalm@gmail.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211203111841.3631616-1-magnusmalm@gmail.com> References: <20211203111841.3631616-1-magnusmalm@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211203_031848_299940_4BEF83F4 X-CRM114-Status: GOOD ( 27.17 ) X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: This patch adds support to configure Fully Qualified Domain Names (FQDN) for authentication and accounting server addresses. Signed-off-by: Magnus Malm --- hostapd/config_file.c | 31 ++++++++++++++- src/radius/radius_client.c | 13 ++++++- src/radius/radius_client.h | 3 ++ src/utils/ip_addr.c | 77 +++++++++++++++++++++++++ [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2a00:1450:4864:20:0:0:0:12c listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [magnusmalm[at]gmail.com] -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 -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org This patch adds support to configure Fully Qualified Domain Names (FQDN) for authentication and accounting server addresses. Signed-off-by: Magnus Malm --- hostapd/config_file.c | 31 ++++++++++++++- src/radius/radius_client.c | 13 ++++++- src/radius/radius_client.h | 3 ++ src/utils/ip_addr.c | 77 ++++++++++++++++++++++++++++++++++++++ src/utils/ip_addr.h | 1 + 5 files changed, 123 insertions(+), 2 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index daf3f37ad..2e4aef0b5 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -24,6 +24,7 @@ #include "ap/wpa_auth.h" #include "ap/ap_config.h" #include "config_file.h" +#include "ip_addr.h" #ifndef CONFIG_NO_VLAN @@ -627,6 +628,21 @@ static int hostapd_config_read_eap_user(const char *fname, #ifndef CONFIG_NO_RADIUS + +static int radius_parse_fqdn(const char *fqdn, + struct hostapd_radius_server *nserv) +{ + size_t len = strnlen(fqdn, NI_MAXHOST); + + if (len < 1) + return -1; + + strncpy(nserv->fqdn_addr, fqdn, len); + nserv->fqdn_addr[len + 1] = '\0'; + + return 1; +} + static int hostapd_config_read_radius_addr(struct hostapd_radius_server **server, int *num_server, const char *val, int def_port, @@ -648,7 +664,20 @@ hostapd_config_read_radius_addr(struct hostapd_radius_server **server, os_memset(nserv, 0, sizeof(*nserv)); nserv->port = def_port; ret = hostapd_parse_ip_addr(val, &nserv->addr); - nserv->index = server_index++; + + /* RADIUS address is not a valid IP address, see if it's a FQDN */ + if (ret) { + if ((radius_parse_fqdn(val, nserv) < 0)) { + wpa_printf(MSG_ERROR, "FQDN %s parse failed", val); + return -1; + } else { + nserv->resolved = resolve_fqdn(nserv->fqdn_addr, &nserv->addr); + if (!nserv->resolved) + wpa_printf(MSG_INFO, "FQDN %s resolve failed", nserv->fqdn_addr); + } + ret = 0; + } + nserv->index = server_index++; return ret; } diff --git a/src/radius/radius_client.c b/src/radius/radius_client.c index ee9e46d2a..47f2aa96a 100644 --- a/src/radius/radius_client.c +++ b/src/radius/radius_client.c @@ -1136,7 +1136,18 @@ radius_change_server(struct radius_client_data *radius, radius_client_timer, radius, NULL); } - switch (nserv->addr.af) { + /* If FQDN is confiured but it was not resolved when the config file was + * read at startup, try again. */ + if ((os_strncmp("", nserv->fqdn_addr, sizeof(nserv->fqdn_addr)) != 0) && + !nserv->resolved) { + nserv->resolved = resolve_fqdn(nserv->fqdn_addr, &nserv->addr); + if (!nserv->resolved) { + wpa_printf(MSG_ERROR, "FQDN %s failed to be resolved", nserv->fqdn_addr); + return -1; + } + } + + switch (nserv->addr.af) { case AF_INET: os_memset(&serv, 0, sizeof(serv)); serv.sin_family = AF_INET; diff --git a/src/radius/radius_client.h b/src/radius/radius_client.h index 687cd81ae..989209ef3 100644 --- a/src/radius/radius_client.h +++ b/src/radius/radius_client.h @@ -9,6 +9,7 @@ #ifndef RADIUS_CLIENT_H #define RADIUS_CLIENT_H +#include #include "ip_addr.h" struct radius_msg; @@ -29,6 +30,8 @@ struct hostapd_radius_server { * addr - radiusAuthServerAddress or radiusAccServerAddress */ struct hostapd_ip_addr addr; + char fqdn_addr[NI_MAXHOST]; + int resolved; /** * port - radiusAuthClientServerPortNumber or radiusAccClientServerPortNumber diff --git a/src/utils/ip_addr.c b/src/utils/ip_addr.c index 92a359039..96a7b3b29 100644 --- a/src/utils/ip_addr.c +++ b/src/utils/ip_addr.c @@ -6,11 +6,88 @@ * See README for more details. */ +#include +#include + #include "includes.h" #include "common.h" #include "ip_addr.h" +/** + * Do a DNS lookup on fqdn_addr and, if successful, set addr accordingly. If + * resolve fails, return 0, otherwise 1. + */ +int resolve_fqdn(const char *fqdn_addr, struct hostapd_ip_addr *addr) +{ + struct addrinfo *servinfo = NULL; + struct addrinfo hints; + struct addrinfo *next = NULL; + int sfd = 0; + int rc = 0; + + /* Ensure we do not get old DNS entries from getaddrinfo() */ + res_init(); + + os_memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; /* IPv4 or IPv6*/ + hints.ai_socktype = SOCK_DGRAM; /* DGRAM sockets only */ + hints.ai_protocol = IPPROTO_UDP; /* UDP only */ + hints.ai_flags = AI_NUMERICSERV; /* No service name lookup */ + + rc = getaddrinfo(fqdn_addr, NULL, &hints, &servinfo); + if (rc != 0 || !servinfo) { + freeaddrinfo(servinfo); + return 0; + } + + /* For each addrinfo entry (if any), validate it by trying to connect to + * it. Break out of the loop with first entry we can connect with. */ + for (next = servinfo; next != NULL; next = next->ai_next) { + /* We're only interested in IPv4 or IPv6 entries */ + if (next->ai_family == AF_INET || next->ai_family == AF_INET6) { + sfd = socket(next->ai_family, next->ai_socktype, next->ai_protocol); + if (sfd == -1) + continue; + + if (connect(sfd, next->ai_addr, next->ai_addrlen) == -1) { + close(sfd); + continue; + } + + /* Connection established. Use this entry. */ + close(sfd); + break; + } + } + + /* Could not connect using any entry returned by getaddrinfo() */ + if (next == NULL) { + freeaddrinfo(servinfo); + return 0; + } + + /* Update addr with the entry we could connect with */ + addr->af = next->ai_family; + switch (next->ai_family) { + case AF_INET: + addr->u.v4.s_addr = (*(struct sockaddr_in *)next->ai_addr).sin_addr.s_addr; + break; + +#ifdef CONFIG_IPV6 + case AF_INET6: + os_memcpy(addr->u.v6.s6_addr, &(*(struct sockaddr_in6 *)next->ai_addr).sin6_addr, + sizeof(struct in6_addr)); + break; +#endif /* CONFIG_IPV6 */ + default: + return 0; + } + + freeaddrinfo(servinfo); + return 1; +} + const char * hostapd_ip_txt(const struct hostapd_ip_addr *addr, char *buf, size_t buflen) { diff --git a/src/utils/ip_addr.h b/src/utils/ip_addr.h index 0670411cc..25d69b544 100644 --- a/src/utils/ip_addr.h +++ b/src/utils/ip_addr.h @@ -24,4 +24,5 @@ const char * hostapd_ip_txt(const struct hostapd_ip_addr *addr, char *buf, size_t buflen); int hostapd_parse_ip_addr(const char *txt, struct hostapd_ip_addr *addr); +int resolve_fqdn(const char *fqdn_addr, struct hostapd_ip_addr *addr); #endif /* IP_ADDR_H */