Complete Yocto mirror with license table for TQMa6UL (2038-compliance)

- 264 license table entries with exact download URLs (224/264 resolved)
- Complete sources/ directory with all BitBake recipes
- Build configuration: tqma6ul-multi-mba6ulx, spaetzle (musl)
- Full traceability for Softwarefreigabeantrag
- GCC 13.4.0, Linux 6.6.102, U-Boot 2023.04, musl 1.2.4
- License distribution: GPL-2.0 (24), MIT (23), GPL-2.0+ (18), BSD-3 (16)
This commit is contained in:
Siggi (OpenClaw Agent)
2026-03-01 20:58:18 +00:00
commit 16accb6b24
15086 changed files with 1292356 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
From 364c2da8741f0979dae497551e70b94c0e6c8636 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Sun, 7 Jul 2024 11:46:49 +0300
Subject: [PATCH 1/3] SAE: Check for invalid Rejected Groups element length
explicitly
Instead of practically ignoring an odd octet at the end of the element,
check for such invalid case explicitly. This is needed to avoid a
potential group downgrade attack.
Signed-off-by: Jouni Malinen <j@w1.fi>
CVE: CVE-2024-3596
Upstream-Status: Backport [https://w1.fi/cgit/hostap/commit/?id=364c2da8741f0979dae497551e70b94c0e6c8636]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
src/ap/ieee802_11.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index db4104928..1a62e30cc 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -1258,7 +1258,7 @@ static int check_sae_rejected_groups(struct hostapd_data *hapd,
struct sae_data *sae)
{
const struct wpabuf *groups;
- size_t i, count;
+ size_t i, count, len;
const u8 *pos;
if (!sae->tmp)
@@ -1268,7 +1268,15 @@ static int check_sae_rejected_groups(struct hostapd_data *hapd,
return 0;
pos = wpabuf_head(groups);
- count = wpabuf_len(groups) / 2;
+ len = wpabuf_len(groups);
+ if (len & 1) {
+ wpa_printf(MSG_DEBUG,
+ "SAE: Invalid length of the Rejected Groups element payload: %zu",
+ len);
+ return 1;
+ }
+
+ count = len / 2;
for (i = 0; i < count; i++) {
int enabled;
u16 group;
--
2.30.2

View File

@@ -0,0 +1,38 @@
From 9716bf1160beb677e965d9e6475d6c9e162e8374 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Tue, 9 Jul 2024 23:34:34 +0300
Subject: [PATCH 3/3] SAE: Reject invalid Rejected Groups element in the parser
There is no need to depend on all uses (i.e., both hostapd and
wpa_supplicant) to verify that the length of the Rejected Groups field
in the Rejected Groups element is valid (i.e., a multiple of two octets)
since the common parser can reject the message when detecting this.
Signed-off-by: Jouni Malinen <j@w1.fi>
Upstream-Status: Backport [https://w1.fi/cgit/hostap/commit/?id=9716bf1160beb677e965d9e6475d6c9e162e8374]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
src/common/sae.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/common/sae.c b/src/common/sae.c
index c0f154e91..620bdf753 100644
--- a/src/common/sae.c
+++ b/src/common/sae.c
@@ -2076,6 +2076,12 @@ static int sae_parse_rejected_groups(struct sae_data *sae,
return WLAN_STATUS_UNSPECIFIED_FAILURE;
epos++; /* skip ext ID */
len--;
+ if (len & 1) {
+ wpa_printf(MSG_DEBUG,
+ "SAE: Invalid length of the Rejected Groups element payload: %u",
+ len);
+ return WLAN_STATUS_UNSPECIFIED_FAILURE;
+ }
wpabuf_free(sae->tmp->peer_rejected_groups);
sae->tmp->peer_rejected_groups = wpabuf_alloc(len);
--
2.30.2

View File

@@ -0,0 +1,198 @@
From 6c81c2d98dc5a8a6296820bd9f083faae2c788c3 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Sat, 8 Jul 2023 19:55:32 +0300
Subject: [PATCH] PEAP client: Update Phase 2 authentication requirements
The previous PEAP client behavior allowed the server to skip Phase 2
authentication with the expectation that the server was authenticated
during Phase 1 through TLS server certificate validation. Various PEAP
specifications are not exactly clear on what the behavior on this front
is supposed to be and as such, this ended up being more flexible than
the TTLS/FAST/TEAP cases. However, this is not really ideal when
unfortunately common misconfiguration of PEAP is used in deployed
devices where the server trust root (ca_cert) is not configured or the
user has an easy option for allowing this validation step to be skipped.
Change the default PEAP client behavior to be to require Phase 2
authentication to be successfully completed for cases where TLS session
resumption is not used and the client certificate has not been
configured. Those two exceptions are the main cases where a deployed
authentication server might skip Phase 2 and as such, where a more
strict default behavior could result in undesired interoperability
issues. Requiring Phase 2 authentication will end up disabling TLS
session resumption automatically to avoid interoperability issues.
Allow Phase 2 authentication behavior to be configured with a new phase1
configuration parameter option:
'phase2_auth' option can be used to control Phase 2 (i.e., within TLS
tunnel) behavior for PEAP:
* 0 = do not require Phase 2 authentication
* 1 = require Phase 2 authentication when client certificate
(private_key/client_cert) is no used and TLS session resumption was
not used (default)
* 2 = require Phase 2 authentication in all cases
Signed-off-by: Jouni Malinen <j@w1.fi>
CVE: CVE-2023-52160
Upstream-Status: Backport
[https://w1.fi/cgit/hostap/commit/?id=8e6485a1bcb0baffdea9e55255a81270b768439c]
Signed-off-by: Yi Zhao <yi.zhao@windriver.com>
---
src/eap_peer/eap_config.h | 8 +++++++
src/eap_peer/eap_peap.c | 40 ++++++++++++++++++++++++++++++++---
src/eap_peer/eap_tls_common.c | 6 ++++++
src/eap_peer/eap_tls_common.h | 5 +++++
4 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/src/eap_peer/eap_config.h b/src/eap_peer/eap_config.h
index 3238f74..047eec2 100644
--- a/src/eap_peer/eap_config.h
+++ b/src/eap_peer/eap_config.h
@@ -469,6 +469,14 @@ struct eap_peer_config {
* 1 = use cryptobinding if server supports it
* 2 = require cryptobinding
*
+ * phase2_auth option can be used to control Phase 2 (i.e., within TLS
+ * tunnel) behavior for PEAP:
+ * 0 = do not require Phase 2 authentication
+ * 1 = require Phase 2 authentication when client certificate
+ * (private_key/client_cert) is no used and TLS session resumption was
+ * not used (default)
+ * 2 = require Phase 2 authentication in all cases
+ *
* EAP-WSC (WPS) uses following options: pin=Device_Password and
* uuid=Device_UUID
*
diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c
index 12e30df..6080697 100644
--- a/src/eap_peer/eap_peap.c
+++ b/src/eap_peer/eap_peap.c
@@ -67,6 +67,7 @@ struct eap_peap_data {
u8 cmk[20];
int soh; /* Whether IF-TNCCS-SOH (Statement of Health; Microsoft NAP)
* is enabled. */
+ enum { NO_AUTH, FOR_INITIAL, ALWAYS } phase2_auth;
};
@@ -114,6 +115,19 @@ static void eap_peap_parse_phase1(struct eap_peap_data *data,
wpa_printf(MSG_DEBUG, "EAP-PEAP: Require cryptobinding");
}
+ if (os_strstr(phase1, "phase2_auth=0")) {
+ data->phase2_auth = NO_AUTH;
+ wpa_printf(MSG_DEBUG,
+ "EAP-PEAP: Do not require Phase 2 authentication");
+ } else if (os_strstr(phase1, "phase2_auth=1")) {
+ data->phase2_auth = FOR_INITIAL;
+ wpa_printf(MSG_DEBUG,
+ "EAP-PEAP: Require Phase 2 authentication for initial connection");
+ } else if (os_strstr(phase1, "phase2_auth=2")) {
+ data->phase2_auth = ALWAYS;
+ wpa_printf(MSG_DEBUG,
+ "EAP-PEAP: Require Phase 2 authentication for all cases");
+ }
#ifdef EAP_TNC
if (os_strstr(phase1, "tnc=soh2")) {
data->soh = 2;
@@ -142,6 +156,7 @@ static void * eap_peap_init(struct eap_sm *sm)
data->force_peap_version = -1;
data->peap_outer_success = 2;
data->crypto_binding = OPTIONAL_BINDING;
+ data->phase2_auth = FOR_INITIAL;
if (config && config->phase1)
eap_peap_parse_phase1(data, config->phase1);
@@ -454,6 +469,20 @@ static int eap_tlv_validate_cryptobinding(struct eap_sm *sm,
}
+static bool peap_phase2_sufficient(struct eap_sm *sm,
+ struct eap_peap_data *data)
+{
+ if ((data->phase2_auth == ALWAYS ||
+ (data->phase2_auth == FOR_INITIAL &&
+ !tls_connection_resumed(sm->ssl_ctx, data->ssl.conn) &&
+ !data->ssl.client_cert_conf) ||
+ data->phase2_eap_started) &&
+ !data->phase2_eap_success)
+ return false;
+ return true;
+}
+
+
/**
* eap_tlv_process - Process a received EAP-TLV message and generate a response
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
@@ -568,6 +597,11 @@ static int eap_tlv_process(struct eap_sm *sm, struct eap_peap_data *data,
" - force failed Phase 2");
resp_status = EAP_TLV_RESULT_FAILURE;
ret->decision = DECISION_FAIL;
+ } else if (!peap_phase2_sufficient(sm, data)) {
+ wpa_printf(MSG_INFO,
+ "EAP-PEAP: Server indicated Phase 2 success, but sufficient Phase 2 authentication has not been completed");
+ resp_status = EAP_TLV_RESULT_FAILURE;
+ ret->decision = DECISION_FAIL;
} else {
resp_status = EAP_TLV_RESULT_SUCCESS;
ret->decision = DECISION_UNCOND_SUCC;
@@ -887,8 +921,7 @@ continue_req:
/* EAP-Success within TLS tunnel is used to indicate
* shutdown of the TLS channel. The authentication has
* been completed. */
- if (data->phase2_eap_started &&
- !data->phase2_eap_success) {
+ if (!peap_phase2_sufficient(sm, data)) {
wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 "
"Success used to indicate success, "
"but Phase 2 EAP was not yet "
@@ -1199,8 +1232,9 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
static bool eap_peap_has_reauth_data(struct eap_sm *sm, void *priv)
{
struct eap_peap_data *data = priv;
+
return tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
- data->phase2_success;
+ data->phase2_success && data->phase2_auth != ALWAYS;
}
diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c
index c1837db..a53eeb1 100644
--- a/src/eap_peer/eap_tls_common.c
+++ b/src/eap_peer/eap_tls_common.c
@@ -239,6 +239,12 @@ static int eap_tls_params_from_conf(struct eap_sm *sm,
sm->ext_cert_check = !!(params->flags & TLS_CONN_EXT_CERT_CHECK);
+ if (!phase2)
+ data->client_cert_conf = params->client_cert ||
+ params->client_cert_blob ||
+ params->private_key ||
+ params->private_key_blob;
+
return 0;
}
diff --git a/src/eap_peer/eap_tls_common.h b/src/eap_peer/eap_tls_common.h
index 9ac0012..3348634 100644
--- a/src/eap_peer/eap_tls_common.h
+++ b/src/eap_peer/eap_tls_common.h
@@ -79,6 +79,11 @@ struct eap_ssl_data {
* tls_v13 - Whether TLS v1.3 or newer is used
*/
int tls_v13;
+
+ /**
+ * client_cert_conf: Whether client certificate has been configured
+ */
+ bool client_cert_conf;
};
--
2.25.1

View File

@@ -0,0 +1,83 @@
From 945acf3ef06a6c312927da4fa055693dbac432d1 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Sat, 2 Apr 2022 16:28:12 +0300
Subject: [PATCH 1/9] ieee802_11_auth: Coding style cleanup - no string
constant splitting
Signed-off-by: Jouni Malinen <j@w1.fi>
CVE: CVE-2024-3596
Upstream-Status: Backport [https://w1.fi/cgit/hostap/commit/?id=945acf3ef06a6c312927da4fa055693dbac432d1]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
src/ap/ieee802_11_auth.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c
index 783ee6dea..47cc625be 100644
--- a/src/ap/ieee802_11_auth.c
+++ b/src/ap/ieee802_11_auth.c
@@ -267,16 +267,16 @@ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr,
os_get_reltime(&query->timestamp);
os_memcpy(query->addr, addr, ETH_ALEN);
if (hostapd_radius_acl_query(hapd, addr, query)) {
- wpa_printf(MSG_DEBUG, "Failed to send Access-Request "
- "for ACL query.");
+ wpa_printf(MSG_DEBUG,
+ "Failed to send Access-Request for ACL query.");
hostapd_acl_query_free(query);
return HOSTAPD_ACL_REJECT;
}
query->auth_msg = os_memdup(msg, len);
if (query->auth_msg == NULL) {
- wpa_printf(MSG_ERROR, "Failed to allocate memory for "
- "auth frame.");
+ wpa_printf(MSG_ERROR,
+ "Failed to allocate memory for auth frame.");
hostapd_acl_query_free(query);
return HOSTAPD_ACL_REJECT;
}
@@ -467,19 +467,21 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
if (query == NULL)
return RADIUS_RX_UNKNOWN;
- wpa_printf(MSG_DEBUG, "Found matching Access-Request for RADIUS "
- "message (id=%d)", query->radius_id);
+ wpa_printf(MSG_DEBUG,
+ "Found matching Access-Request for RADIUS message (id=%d)",
+ query->radius_id);
if (radius_msg_verify(msg, shared_secret, shared_secret_len, req, 0)) {
- wpa_printf(MSG_INFO, "Incoming RADIUS packet did not have "
- "correct authenticator - dropped\n");
+ wpa_printf(MSG_INFO,
+ "Incoming RADIUS packet did not have correct authenticator - dropped");
return RADIUS_RX_INVALID_AUTHENTICATOR;
}
if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT &&
hdr->code != RADIUS_CODE_ACCESS_REJECT) {
- wpa_printf(MSG_DEBUG, "Unknown RADIUS message code %d to ACL "
- "query", hdr->code);
+ wpa_printf(MSG_DEBUG,
+ "Unknown RADIUS message code %d to ACL query",
+ hdr->code);
return RADIUS_RX_UNKNOWN;
}
@@ -506,8 +508,9 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL,
&info->acct_interim_interval) == 0 &&
info->acct_interim_interval < 60) {
- wpa_printf(MSG_DEBUG, "Ignored too small "
- "Acct-Interim-Interval %d for STA " MACSTR,
+ wpa_printf(MSG_DEBUG,
+ "Ignored too small Acct-Interim-Interval %d for STA "
+ MACSTR,
info->acct_interim_interval,
MAC2STR(query->addr));
info->acct_interim_interval = 0;
--
2.30.2

View File

@@ -0,0 +1,165 @@
From adac846bd0e258a0aa50750bbd2b411fa0085c46 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Sat, 16 Mar 2024 11:11:44 +0200
Subject: [PATCH 2/9] RADIUS: Allow Message-Authenticator attribute as the
first attribute
If a Message-Authenticator attribute was already added to a RADIUS
message, use that attribute instead of adding a new one when finishing
message building. This allows the Message-Authenticator attribute to be
placed as the first attribute in the message.
Signed-off-by: Jouni Malinen <j@w1.fi>
CVE: CVE-2024-3596
Upstream-Status: Backport [https://w1.fi/cgit/hostap/commit/?id=adac846bd0e258a0aa50750bbd2b411fa0085c46]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
src/radius/radius.c | 85 ++++++++++++++++++++++++++++-----------------
src/radius/radius.h | 1 +
2 files changed, 54 insertions(+), 32 deletions(-)
diff --git a/src/radius/radius.c b/src/radius/radius.c
index be16e27b9..2d2e00b5c 100644
--- a/src/radius/radius.c
+++ b/src/radius/radius.c
@@ -364,25 +364,54 @@ void radius_msg_dump(struct radius_msg *msg)
}
+u8 * radius_msg_add_msg_auth(struct radius_msg *msg)
+{
+ u8 auth[MD5_MAC_LEN];
+ struct radius_attr_hdr *attr;
+
+ os_memset(auth, 0, MD5_MAC_LEN);
+ attr = radius_msg_add_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
+ auth, MD5_MAC_LEN);
+ if (!attr) {
+ wpa_printf(MSG_ERROR,
+ "WARNING: Could not add Message-Authenticator");
+ return NULL;
+ }
+
+ return (u8 *) (attr + 1);
+}
+
+
+static u8 * radius_msg_auth_pos(struct radius_msg *msg)
+{
+ u8 *pos;
+ size_t alen;
+
+ if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
+ &pos, &alen, NULL) == 0 &&
+ alen == MD5_MAC_LEN) {
+ /* Use already added Message-Authenticator attribute */
+ return pos;
+ }
+
+ /* Add a Message-Authenticator attribute */
+ return radius_msg_add_msg_auth(msg);
+}
+
+
int radius_msg_finish(struct radius_msg *msg, const u8 *secret,
size_t secret_len)
{
if (secret) {
- u8 auth[MD5_MAC_LEN];
- struct radius_attr_hdr *attr;
+ u8 *pos;
- os_memset(auth, 0, MD5_MAC_LEN);
- attr = radius_msg_add_attr(msg,
- RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
- auth, MD5_MAC_LEN);
- if (attr == NULL) {
- wpa_printf(MSG_WARNING, "RADIUS: Could not add "
- "Message-Authenticator");
+ pos = radius_msg_auth_pos(msg);
+ if (!pos)
return -1;
- }
msg->hdr->length = host_to_be16(wpabuf_len(msg->buf));
- hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
- wpabuf_len(msg->buf), (u8 *) (attr + 1));
+ if (hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
+ wpabuf_len(msg->buf), pos) < 0)
+ return -1;
} else
msg->hdr->length = host_to_be16(wpabuf_len(msg->buf));
@@ -398,23 +427,19 @@ int radius_msg_finish(struct radius_msg *msg, const u8 *secret,
int radius_msg_finish_srv(struct radius_msg *msg, const u8 *secret,
size_t secret_len, const u8 *req_authenticator)
{
- u8 auth[MD5_MAC_LEN];
- struct radius_attr_hdr *attr;
const u8 *addr[4];
size_t len[4];
+ u8 *pos;
- os_memset(auth, 0, MD5_MAC_LEN);
- attr = radius_msg_add_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
- auth, MD5_MAC_LEN);
- if (attr == NULL) {
- wpa_printf(MSG_ERROR, "WARNING: Could not add Message-Authenticator");
+ pos = radius_msg_auth_pos(msg);
+ if (!pos)
return -1;
- }
msg->hdr->length = host_to_be16(wpabuf_len(msg->buf));
os_memcpy(msg->hdr->authenticator, req_authenticator,
sizeof(msg->hdr->authenticator));
- hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
- wpabuf_len(msg->buf), (u8 *) (attr + 1));
+ if (hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
+ wpabuf_len(msg->buf), pos) < 0)
+ return -1;
/* ResponseAuth = MD5(Code+ID+Length+RequestAuth+Attributes+Secret) */
addr[0] = (u8 *) msg->hdr;
@@ -442,21 +467,17 @@ int radius_msg_finish_das_resp(struct radius_msg *msg, const u8 *secret,
{
const u8 *addr[2];
size_t len[2];
- u8 auth[MD5_MAC_LEN];
- struct radius_attr_hdr *attr;
+ u8 *pos;
- os_memset(auth, 0, MD5_MAC_LEN);
- attr = radius_msg_add_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
- auth, MD5_MAC_LEN);
- if (attr == NULL) {
- wpa_printf(MSG_WARNING, "Could not add Message-Authenticator");
+ pos = radius_msg_auth_pos(msg);
+ if (!pos)
return -1;
- }
msg->hdr->length = host_to_be16(wpabuf_len(msg->buf));
os_memcpy(msg->hdr->authenticator, req_hdr->authenticator, 16);
- hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
- wpabuf_len(msg->buf), (u8 *) (attr + 1));
+ if (hmac_md5(secret, secret_len, wpabuf_head(msg->buf),
+ wpabuf_len(msg->buf), pos) < 0)
+ return -1;
/* ResponseAuth = MD5(Code+ID+Length+RequestAuth+Attributes+Secret) */
addr[0] = wpabuf_head_u8(msg->buf);
diff --git a/src/radius/radius.h b/src/radius/radius.h
index fb8148180..6b9dfbca2 100644
--- a/src/radius/radius.h
+++ b/src/radius/radius.h
@@ -240,6 +240,7 @@ struct wpabuf * radius_msg_get_buf(struct radius_msg *msg);
struct radius_msg * radius_msg_new(u8 code, u8 identifier);
void radius_msg_free(struct radius_msg *msg);
void radius_msg_dump(struct radius_msg *msg);
+u8 * radius_msg_add_msg_auth(struct radius_msg *msg);
int radius_msg_finish(struct radius_msg *msg, const u8 *secret,
size_t secret_len);
int radius_msg_finish_srv(struct radius_msg *msg, const u8 *secret,
--
2.30.2

View File

@@ -0,0 +1,62 @@
From 54abb0d3cf35894e7d86e3f7555e95b106306803 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Sat, 16 Mar 2024 11:13:32 +0200
Subject: [PATCH 3/9] RADIUS server: Place Message-Authenticator attribute as
the first one
Move the Message-Authenticator attribute to be the first attribute in
the RADIUS messages. This mitigates certain MD5 attacks against
RADIUS/UDP.
Signed-off-by: Jouni Malinen <j@w1.fi>
CVE: CVE-2024-3596
Upstream-Status: Backport [https://w1.fi/cgit/hostap/commit/?id=54abb0d3cf35894e7d86e3f7555e95b106306803]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
src/radius/radius_server.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/src/radius/radius_server.c b/src/radius/radius_server.c
index e02c21540..fa3691548 100644
--- a/src/radius/radius_server.c
+++ b/src/radius/radius_server.c
@@ -920,6 +920,11 @@ radius_server_encapsulate_eap(struct radius_server_data *data,
return NULL;
}
+ if (!radius_msg_add_msg_auth(msg)) {
+ radius_msg_free(msg);
+ return NULL;
+ }
+
sess_id = htonl(sess->sess_id);
if (code == RADIUS_CODE_ACCESS_CHALLENGE &&
!radius_msg_add_attr(msg, RADIUS_ATTR_STATE,
@@ -1204,6 +1209,11 @@ radius_server_macacl(struct radius_server_data *data,
return NULL;
}
+ if (!radius_msg_add_msg_auth(msg)) {
+ radius_msg_free(msg);
+ return NULL;
+ }
+
if (radius_msg_copy_attr(msg, request, RADIUS_ATTR_PROXY_STATE) < 0) {
RADIUS_DEBUG("Failed to copy Proxy-State attribute(s)");
radius_msg_free(msg);
@@ -1253,6 +1263,11 @@ static int radius_server_reject(struct radius_server_data *data,
return -1;
}
+ if (!radius_msg_add_msg_auth(msg)) {
+ radius_msg_free(msg);
+ return -1;
+ }
+
os_memset(&eapfail, 0, sizeof(eapfail));
eapfail.code = EAP_CODE_FAILURE;
eapfail.identifier = 0;
--
2.30.2

View File

@@ -0,0 +1,52 @@
From 37fe8e48ab44d44fe3cf5dd8f52cb0a10be0cd17 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Sat, 16 Mar 2024 11:22:43 +0200
Subject: [PATCH 5/9] hostapd: Move Message-Authenticator attribute to be the
first one in req
Even if this is not strictly speaking necessary for mitigating certain
RADIUS protocol attacks, be consistent with the RADIUS server behavior
and move the Message-Authenticator attribute to be the first attribute
in the message from RADIUS client in hostapd.
Signed-off-by: Jouni Malinen <j@w1.fi>
CVE: CVE-2024-3596
Upstream-Status: Backport [https://w1.fi/cgit/hostap/commit/?id=37fe8e48ab44d44fe3cf5dd8f52cb0a10be0cd17]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
src/ap/ieee802_11_auth.c | 3 +++
src/ap/ieee802_1x.c | 3 +++
2 files changed, 6 insertions(+)
diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c
index 47cc625be..2a950cf7f 100644
--- a/src/ap/ieee802_11_auth.c
+++ b/src/ap/ieee802_11_auth.c
@@ -119,6 +119,9 @@ static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
goto fail;
}
+ if (!radius_msg_add_msg_auth(msg))
+ goto fail;
+
os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT, MAC2STR(addr));
if (!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, (u8 *) buf,
os_strlen(buf))) {
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 753c88335..89e3dd30e 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -702,6 +702,9 @@ void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
goto fail;
}
+ if (!radius_msg_add_msg_auth(msg))
+ goto fail;
+
if (sm->identity &&
!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME,
sm->identity, sm->identity_len)) {
--
2.30.2

View File

@@ -0,0 +1,51 @@
From f54157077f799d84ce26bed6ad6b01c4a16e31cf Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Sat, 16 Mar 2024 11:26:58 +0200
Subject: [PATCH 6/9] RADIUS DAS: Move Message-Authenticator attribute to be
the first one
Even if this might not be strictly speaking necessary for mitigating
certain RADIUS protocol attacks, be consistent with the RADIUS server
behavior and move the Message-Authenticator attribute to be the first
attribute in the RADIUS DAS responses from hostapd.
Signed-off-by: Jouni Malinen <j@w1.fi>
CVE: CVE-2024-3596
Upstream-Status: Backport [https://w1.fi/cgit/hostap/commit/?id=f54157077f799d84ce26bed6ad6b01c4a16e31cf]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
src/radius/radius_das.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/radius/radius_das.c b/src/radius/radius_das.c
index aaa3fc267..8d7c9b4c4 100644
--- a/src/radius/radius_das.c
+++ b/src/radius/radius_das.c
@@ -177,6 +177,11 @@ fail:
if (reply == NULL)
return NULL;
+ if (!radius_msg_add_msg_auth(reply)) {
+ radius_msg_free(reply);
+ return NULL;
+ }
+
if (error) {
if (!radius_msg_add_attr_int32(reply, RADIUS_ATTR_ERROR_CAUSE,
error)) {
@@ -368,6 +373,11 @@ fail:
if (!reply)
return NULL;
+ if (!radius_msg_add_msg_auth(reply)) {
+ radius_msg_free(reply);
+ return NULL;
+ }
+
if (error &&
!radius_msg_add_attr_int32(reply, RADIUS_ATTR_ERROR_CAUSE, error)) {
radius_msg_free(reply);
--
2.30.2

View File

@@ -0,0 +1,46 @@
From 934b0c3a45ce0726560ccefbd992a9d385c36385 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Sat, 16 Mar 2024 11:31:37 +0200
Subject: [PATCH 7/9] Require Message-Authenticator in Access-Reject even
without EAP-Message
Do not allow the exception for missing Message-Authenticator in
Access-Reject without EAP-Message. While such exception is allowed in
RADIUS definition, there is no strong reason to maintain this since
Access-Reject is supposed to include EAP-Message and even if it doesn't,
discarding Access-Reject will result in the connection not completing.
Signed-off-by: Jouni Malinen <j@w1.fi>
CVE: CVE-2024-3596
Upstream-Status: Backport [https://w1.fi/cgit/hostap/commit/?id=934b0c3a45ce0726560ccefbd992a9d385c36385]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
src/ap/ieee802_1x.c | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 89e3dd30e..6e7b75128 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -1939,16 +1939,7 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
}
sta = sm->sta;
- /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be
- * present when packet contains an EAP-Message attribute */
- if (hdr->code == RADIUS_CODE_ACCESS_REJECT &&
- radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL,
- 0) < 0 &&
- radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) {
- wpa_printf(MSG_DEBUG,
- "Allowing RADIUS Access-Reject without Message-Authenticator since it does not include EAP-Message");
- } else if (radius_msg_verify(msg, shared_secret, shared_secret_len,
- req, 1)) {
+ if (radius_msg_verify(msg, shared_secret, shared_secret_len, req, 1)) {
wpa_printf(MSG_INFO,
"Incoming RADIUS packet did not have correct Message-Authenticator - dropped");
return RADIUS_RX_INVALID_AUTHENTICATOR;
--
2.30.2

View File

@@ -0,0 +1,105 @@
From 58097123ec5ea6f8276b38cb9b07669ec368a6c1 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Sun, 17 Mar 2024 10:42:56 +0200
Subject: [PATCH 8/9] RADIUS: Require Message-Authenticator attribute in MAC
ACL cases
hostapd required Message-Authenticator attribute to be included in EAP
authentication cases, but that requirement was not in place for MAC ACL
cases. Start requiring Message-Authenticator attribute for MAC ACL by
default. Unlike the EAP case, this can still be disabled with
radius_require_message_authenticator=1 to maintain compatibility with
some RADIUS servers when used in a network where the connection to such
a server is secure.
Signed-off-by: Jouni Malinen <j@w1.fi>
CVE: CVE-2024-3596
Upstream-Status: Backport [https://w1.fi/cgit/hostap/commit/?id=58097123ec5ea6f8276b38cb9b07669ec368a6c1]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
hostapd/config_file.c | 3 +++
hostapd/hostapd.conf | 11 +++++++++++
src/ap/ap_config.c | 1 +
src/ap/ap_config.h | 1 +
src/ap/ieee802_11_auth.c | 4 +++-
5 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index b14728d1b..af1e81d1d 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -2806,6 +2806,9 @@ static int hostapd_config_fill(struct hostapd_config *conf,
bss->radius->acct_server->shared_secret_len = len;
} else if (os_strcmp(buf, "radius_retry_primary_interval") == 0) {
bss->radius->retry_primary_interval = atoi(pos);
+ } else if (os_strcmp(buf,
+ "radius_require_message_authenticator") == 0) {
+ bss->radius_require_message_authenticator = atoi(pos);
} else if (os_strcmp(buf, "radius_acct_interim_interval") == 0) {
bss->acct_interim_interval = atoi(pos);
} else if (os_strcmp(buf, "radius_request_cui") == 0) {
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index 3c2019f73..c055946a6 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -1447,6 +1447,17 @@ own_ip_addr=127.0.0.1
# currently used secondary server is still working.
#radius_retry_primary_interval=600
+# Message-Authenticator attribute requirement for non-EAP cases
+# hostapd requires Message-Authenticator attribute to be included in all cases
+# where RADIUS is used for EAP authentication. This is also required for cases
+# where RADIUS is used for MAC ACL (macaddr_acl=2) by default, but that case
+# can be configured to not require this for compatibility with RADIUS servers
+# that do not include the attribute. This is not recommended due to potential
+# security concerns, but can be used as a temporary workaround in networks where
+# the connection to the RADIUS server is secure.
+# 0 = Do not require Message-Authenticator in MAC ACL response
+# 1 = Require Message-Authenticator in all authentication cases (default)
+#radius_require_message_authenticator=1
# Interim accounting update interval
# If this is set (larger than 0) and acct_server is configured, hostapd will
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 86b6e097c..cf497a180 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -120,6 +120,7 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
#endif /* CONFIG_IEEE80211R_AP */
bss->radius_das_time_window = 300;
+ bss->radius_require_message_authenticator = 1;
bss->anti_clogging_threshold = 5;
bss->sae_sync = 5;
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 49cd3168a..22ad617f4 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -302,6 +302,7 @@ struct hostapd_bss_config {
struct hostapd_ip_addr own_ip_addr;
char *nas_identifier;
struct hostapd_radius_servers *radius;
+ int radius_require_message_authenticator;
int acct_interim_interval;
int radius_request_cui;
struct hostapd_radius_attr *radius_auth_req_attr;
diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c
index 2a950cf7f..dab9bcde3 100644
--- a/src/ap/ieee802_11_auth.c
+++ b/src/ap/ieee802_11_auth.c
@@ -474,7 +474,9 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
"Found matching Access-Request for RADIUS message (id=%d)",
query->radius_id);
- if (radius_msg_verify(msg, shared_secret, shared_secret_len, req, 0)) {
+ if (radius_msg_verify(
+ msg, shared_secret, shared_secret_len, req,
+ hapd->conf->radius_require_message_authenticator)) {
wpa_printf(MSG_INFO,
"Incoming RADIUS packet did not have correct authenticator - dropped");
return RADIUS_RX_INVALID_AUTHENTICATOR;
--
2.30.2

View File

@@ -0,0 +1,47 @@
From f302d9f9646704cce745734af21d540baa0da65f Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Sun, 17 Mar 2024 10:47:58 +0200
Subject: [PATCH 9/9] RADIUS: Check Message-Authenticator if it is present even
if not required
Always check the Message-Authenticator attribute in a received RADIUS
message if it is present. Previously, this would have been skipped if
the attribute was not required to be present.
Signed-off-by: Jouni Malinen <j@w1.fi>
CVE: CVE-2024-3596
Upstream-Status: Backport [https://w1.fi/cgit/hostap/commit/?id=f302d9f9646704cce745734af21d540baa0da65f]
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
src/radius/radius.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/radius/radius.c b/src/radius/radius.c
index 2d2e00b5c..a0e3ce399 100644
--- a/src/radius/radius.c
+++ b/src/radius/radius.c
@@ -879,6 +879,20 @@ int radius_msg_verify(struct radius_msg *msg, const u8 *secret,
return 1;
}
+ if (!auth) {
+ u8 *pos;
+ size_t alen;
+
+ if (radius_msg_get_attr_ptr(msg,
+ RADIUS_ATTR_MESSAGE_AUTHENTICATOR,
+ &pos, &alen, NULL) == 0) {
+ /* Check the Message-Authenticator attribute since it
+ * was included even if we are configured to not
+ * require it. */
+ auth = 1;
+ }
+ }
+
if (auth &&
radius_msg_verify_msg_auth(msg, secret, secret_len,
sent_msg->hdr->authenticator)) {
--
2.30.2

View File

@@ -0,0 +1,148 @@
# Example hostapd build time configuration
#
# This file lists the configuration options that are used when building the
# hostapd binary. All lines starting with # are ignored. Configuration option
# lines must be commented out complete, if they are not to be included, i.e.,
# just setting VARIABLE=n is not disabling that variable.
#
# This file is included in Makefile, so variables like CFLAGS and LIBS can also
# be modified from here. In most cass, these lines should use += in order not
# to override previous values of the variables.
# Driver interface for Host AP driver
CONFIG_DRIVER_HOSTAP=y
# Driver interface for wired authenticator
CONFIG_DRIVER_WIRED=y
# Driver interface for madwifi driver
#CONFIG_DRIVER_MADWIFI=y
#CFLAGS += -I../../madwifi # change to the madwifi source directory
# Driver interface for Prism54 driver
CONFIG_DRIVER_PRISM54=y
# Driver interface for drivers using the nl80211 kernel interface
CONFIG_DRIVER_NL80211=y
CONFIG_LIBNL32=y
# driver_nl80211.c requires a rather new libnl (version 1.1) which may not be
# shipped with your distribution yet. If that is the case, you need to build
# newer libnl version and point the hostapd build to use it.
#LIBNL=/usr/src/libnl
#CFLAGS += -I$(LIBNL)/include
#LIBS += -L$(LIBNL)/lib
# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
#CONFIG_DRIVER_BSD=y
#CFLAGS += -I/usr/local/include
#LIBS += -L/usr/local/lib
# Driver interface for no driver (e.g., RADIUS server only)
#CONFIG_DRIVER_NONE=y
# IEEE 802.11F/IAPP
CONFIG_IAPP=y
# WPA2/IEEE 802.11i RSN pre-authentication
CONFIG_RSN_PREAUTH=y
# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
CONFIG_PEERKEY=y
# IEEE 802.11w (management frame protection)
# This version is an experimental implementation based on IEEE 802.11w/D1.0
# draft and is subject to change since the standard has not yet been finalized.
# Driver support is also needed for IEEE 802.11w.
#CONFIG_IEEE80211W=y
# Integrated EAP server
CONFIG_EAP=y
# EAP-MD5 for the integrated EAP server
CONFIG_EAP_MD5=y
# EAP-TLS for the integrated EAP server
CONFIG_EAP_TLS=y
# EAP-MSCHAPv2 for the integrated EAP server
CONFIG_EAP_MSCHAPV2=y
# EAP-PEAP for the integrated EAP server
CONFIG_EAP_PEAP=y
# EAP-GTC for the integrated EAP server
CONFIG_EAP_GTC=y
# EAP-TTLS for the integrated EAP server
CONFIG_EAP_TTLS=y
# EAP-SIM for the integrated EAP server
#CONFIG_EAP_SIM=y
# EAP-AKA for the integrated EAP server
#CONFIG_EAP_AKA=y
# EAP-AKA' for the integrated EAP server
# This requires CONFIG_EAP_AKA to be enabled, too.
#CONFIG_EAP_AKA_PRIME=y
# EAP-PAX for the integrated EAP server
#CONFIG_EAP_PAX=y
# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
#CONFIG_EAP_PSK=y
# EAP-SAKE for the integrated EAP server
#CONFIG_EAP_SAKE=y
# EAP-GPSK for the integrated EAP server
#CONFIG_EAP_GPSK=y
# Include support for optional SHA256 cipher suite in EAP-GPSK
#CONFIG_EAP_GPSK_SHA256=y
# EAP-FAST for the integrated EAP server
# Note: Default OpenSSL package does not include support for all the
# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
# the OpenSSL library must be patched (openssl-0.9.9-session-ticket.patch)
# to add the needed functions.
#CONFIG_EAP_FAST=y
# Wi-Fi Protected Setup (WPS)
CONFIG_WPS=y
# Enable UPnP support for external WPS Registrars
#CONFIG_WPS_UPNP=y
# EAP-IKEv2
#CONFIG_EAP_IKEV2=y
# Trusted Network Connect (EAP-TNC)
#CONFIG_EAP_TNC=y
# PKCS#12 (PFX) support (used to read private key and certificate file from
# a file that usually has extension .p12 or .pfx)
CONFIG_PKCS12=y
# RADIUS authentication server. This provides access to the integrated EAP
# server from external hosts using RADIUS.
CONFIG_RADIUS_SERVER=y
# Build IPv6 support for RADIUS operations
CONFIG_IPV6=y
# IEEE Std 802.11r-2008 (Fast BSS Transition)
#CONFIG_IEEE80211R=y
# Use the hostapd's IEEE 802.11 authentication (ACL), but without
# the IEEE 802.11 Management capability (e.g., madwifi or FreeBSD/net80211)
CONFIG_DRIVER_RADIUS_ACL=y
# IEEE 802.11n (High Throughput) support
CONFIG_IEEE80211N=y
# IEEE 802.11ac (Very High Throughput) support
CONFIG_IEEE80211AC=y
# Remove debugging code that is printing out debug messages to stdout.
# This can be used to reduce the size of the hostapd considerably if debugging
# code is not needed.
#CONFIG_NO_STDOUT_DEBUG=y

View File

@@ -0,0 +1,11 @@
[Unit]
Description=Hostapd IEEE 802.11 AP, IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator
After=network.target
[Service]
Type=forking
PIDFile=/run/hostapd.pid
ExecStart=@SBINDIR@/hostapd @SYSCONFDIR@/hostapd.conf -P /run/hostapd.pid -B
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,58 @@
#!/bin/sh
DAEMON=/usr/sbin/hostapd
NAME=hostapd
DESC="HOSTAP Daemon"
ARGS="/etc/hostapd.conf -B"
test -f $DAEMON || exit 0
set -e
# source function library
. /etc/init.d/functions
delay_stop() {
count=0
while [ $count -lt 9 ] ; do
if pidof $DAEMON >/dev/null; then
sleep 1
else
return 0
fi
count=`expr $count + 1`
done
echo "Failed to stop $DESC."
return 1
}
case "$1" in
start)
echo -n "Starting $DESC: "
start-stop-daemon -S -x $DAEMON -- $ARGS
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon -K --oknodo -x $DAEMON
echo "$NAME."
;;
restart)
$0 stop
delay_stop && $0 start
;;
reload)
echo -n "Reloading $DESC: "
killall -HUP $(basename ${DAEMON})
echo "$NAME."
;;
status)
status $DAEMON
exit $?
;;
*)
echo "Usage: $0 {start|stop|restart|reload|status}"
exit 1
;;
esac
exit 0

View File

@@ -0,0 +1,59 @@
SUMMARY = "User space daemon for extended IEEE 802.11 management"
HOMEPAGE = "http://w1.fi/hostapd/"
SECTION = "kernel/userland"
LICENSE = "BSD-3-Clause"
LIC_FILES_CHKSUM = "file://hostapd/README;beginline=5;endline=47;md5=aa03b8bd6216d1a7ca01fd4b89863073"
DEPENDS = "libnl openssl"
SRC_URI = " \
http://w1.fi/releases/hostapd-${PV}.tar.gz \
file://defconfig \
file://init \
file://hostapd.service \
file://CVE-2024-3596_00.patch \
file://CVE-2024-3596_01.patch \
file://CVE-2024-3596_02.patch \
file://CVE-2024-3596_04.patch \
file://CVE-2024-3596_05.patch \
file://CVE-2024-3596_06.patch \
file://CVE-2024-3596_07.patch \
file://CVE-2024-3596_08.patch \
file://0001-SAE-Check-for-invalid-Rejected-Groups-element-length.patch \
file://0003-SAE-Reject-invalid-Rejected-Groups-element-in-the-pa.patch \
file://CVE-2023-52160.patch \
"
SRC_URI[sha256sum] = "206e7c799b678572c2e3d12030238784bc4a9f82323b0156b4c9466f1498915d"
inherit update-rc.d systemd pkgconfig features_check
CONFLICT_DISTRO_FEATURES = "openssl-no-weak-ciphers"
INITSCRIPT_NAME = "hostapd"
SYSTEMD_SERVICE:${PN} = "hostapd.service"
SYSTEMD_AUTO_ENABLE:${PN} = "disable"
do_configure:append() {
install -m 0644 ${WORKDIR}/defconfig ${B}/hostapd/.config
}
do_compile() {
export CFLAGS="-MMD -O2 -Wall -g"
export EXTRA_CFLAGS="${CFLAGS}"
make -C hostapd V=1
}
do_install() {
install -d ${D}${sbindir} ${D}${sysconfdir}/init.d ${D}${systemd_unitdir}/system/
install -m 0644 ${B}/hostapd/hostapd.conf ${D}${sysconfdir}
install -m 0755 ${B}/hostapd/hostapd ${D}${sbindir}
install -m 0755 ${B}/hostapd/hostapd_cli ${D}${sbindir}
install -m 755 ${WORKDIR}/init ${D}${sysconfdir}/init.d/hostapd
install -m 0644 ${WORKDIR}/hostapd.service ${D}${systemd_unitdir}/system/
sed -i -e 's,@SBINDIR@,${sbindir},g' -e 's,@SYSCONFDIR@,${sysconfdir},g' ${D}${systemd_unitdir}/system/hostapd.service
}
CONFFILES:${PN} += "${sysconfdir}/hostapd.conf"