From 006a08d99c7bf984e1680019458bb87e35aee5df Mon Sep 17 00:00:00 2001 From: yasuoka Date: Mon, 26 Feb 2024 08:47:28 +0000 Subject: [PATCH] Put the RADIUS message authenticator in the Access-Request and check the message authenticators of any received messages from servers only if they include a message authenticator. --- usr.sbin/npppd/npppd/chap.c | 9 +++++++-- usr.sbin/npppd/npppd/npppd_radius.c | 5 +---- usr.sbin/npppd/npppd/pap.c | 9 +++++++-- usr.sbin/npppd/npppd/radius_req.c | 31 +++++++++++++++++------------ usr.sbin/npppd/npppd/radius_req.h | 11 +++++++++- 5 files changed, 43 insertions(+), 22 deletions(-) diff --git a/usr.sbin/npppd/npppd/chap.c b/usr.sbin/npppd/npppd/chap.c index e0c7efae39b..9668d059a65 100644 --- a/usr.sbin/npppd/npppd/chap.c +++ b/usr.sbin/npppd/npppd/chap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: chap.c,v 1.17 2021/03/29 03:54:39 yasuoka Exp $ */ +/* $OpenBSD: chap.c,v 1.18 2024/02/26 08:47:28 yasuoka Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -36,7 +36,7 @@ *

*/ /* RFC 1994, 2433 */ -/* $Id: chap.c,v 1.17 2021/03/29 03:54:39 yasuoka Exp $ */ +/* $Id: chap.c,v 1.18 2024/02/26 08:47:28 yasuoka Exp $ */ #include #include #include @@ -862,6 +862,11 @@ chap_radius_response(void *context, RADIUS_PACKET *pkt, int flags, reason="bad_authenticator"; goto auth_failed; } + if ((flags & RADIUS_REQUEST_CHECK_MSG_AUTHENTICATOR_OK) == 0 && + (flags & RADIUS_REQUEST_CHECK_NO_MSG_AUTHENTICATOR) == 0) { + reason="bad_msg_authenticator"; + goto auth_failed; + } /* * Authentication OK */ diff --git a/usr.sbin/npppd/npppd/npppd_radius.c b/usr.sbin/npppd/npppd/npppd_radius.c index c15e42cb058..d9d67893f27 100644 --- a/usr.sbin/npppd/npppd/npppd_radius.c +++ b/usr.sbin/npppd/npppd/npppd_radius.c @@ -1,4 +1,4 @@ -/* $Id: npppd_radius.c,v 1.8 2015/07/23 09:04:06 yasuoka Exp $ */ +/* $Id: npppd_radius.c,v 1.9 2024/02/26 08:47:28 yasuoka Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. * All rights reserved. @@ -301,9 +301,6 @@ radius_acct_request(npppd *pppd, npppd_ppp *ppp, int stop) ppp->obytes >> 32); } - radius_set_accounting_request_authenticator(radpkt, - radius_get_server_secret(radctx)); - /* Send the request */ radius_request(radctx, radpkt); diff --git a/usr.sbin/npppd/npppd/pap.c b/usr.sbin/npppd/npppd/pap.c index 86c58f227a3..0d43f72af80 100644 --- a/usr.sbin/npppd/npppd/pap.c +++ b/usr.sbin/npppd/npppd/pap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pap.c,v 1.12 2021/03/29 03:54:39 yasuoka Exp $ */ +/* $OpenBSD: pap.c,v 1.13 2024/02/26 08:47:28 yasuoka Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -/* $Id: pap.c,v 1.12 2021/03/29 03:54:39 yasuoka Exp $ */ +/* $Id: pap.c,v 1.13 2024/02/26 08:47:28 yasuoka Exp $ */ /**@file * This file provides Password Authentication Protocol (PAP) handlers. * @author Yasuoka Masahiko @@ -501,6 +501,11 @@ pap_radius_response(void *context, RADIUS_PACKET *pkt, int flags, reason="bad_authenticator"; goto auth_failed; } + if ((flags & RADIUS_REQUEST_CHECK_MSG_AUTHENTICATOR_OK) == 0 && + (flags & RADIUS_REQUEST_CHECK_NO_MSG_AUTHENTICATOR) == 0) { + reason="bad_authenticator"; + goto auth_failed; + } /* Authentication succeeded */ pap_response(_this, 1, DEFAULT_SUCCESS_MESSAGE); ppp_process_radius_framed_ip(_this->ppp, pkt); diff --git a/usr.sbin/npppd/npppd/radius_req.c b/usr.sbin/npppd/npppd/radius_req.c index c1693c87398..359eb95871c 100644 --- a/usr.sbin/npppd/npppd/radius_req.c +++ b/usr.sbin/npppd/npppd/radius_req.c @@ -1,4 +1,4 @@ -/* $OpenBSD: radius_req.c,v 1.11 2015/12/05 18:43:36 mmcc Exp $ */ +/* $OpenBSD: radius_req.c,v 1.12 2024/02/26 08:47:28 yasuoka Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -28,7 +28,7 @@ /**@file * This file provides functions for RADIUS request using radius(3) and event(3). * @author Yasuoka Masahiko - * $Id: radius_req.c,v 1.11 2015/12/05 18:43:36 mmcc Exp $ + * $Id: radius_req.c,v 1.12 2024/02/26 08:47:28 yasuoka Exp $ */ #include #include @@ -68,7 +68,7 @@ struct overlapped { radius_req_setting *setting; }; -static int radius_request0 (struct overlapped *, int); +static int radius_request0(struct overlapped *); static int radius_prepare_socket(struct overlapped *); static void radius_request_io_event (int, short, void *); static void radius_on_response(RADIUS_REQUEST_CTX, RADIUS_PACKET *, int, int); @@ -107,7 +107,7 @@ radius_request(RADIUS_REQUEST_CTX ctx, RADIUS_PACKET *pkt) if (radius_get_uint32_attr(pkt, RADIUS_TYPE_ACCT_DELAY_TIME, &ival) == 0) lap->acct_delay_time = 1; - radius_request0(lap, 0); + radius_request0(lap); } /** @@ -207,7 +207,7 @@ radius_request_failover(RADIUS_REQUEST_CTX ctx) if (radius_prepare_socket(lap) != 0) return -1; - if (radius_request0(lap, 1) != 0) + if (radius_request0(lap) != 0) return -1; lap->failovers++; @@ -359,7 +359,7 @@ radius_get_server_address(RADIUS_REQUEST_CTX ctx) } static int -radius_request0(struct overlapped *lap, int new_message) +radius_request0(struct overlapped *lap) { struct timeval tv0; @@ -378,16 +378,16 @@ radius_request0(struct overlapped *lap, int new_message) else { timespecsub(&curr, &lap->req_time, &delta); if (radius_set_uint32_attr(lap->pkt, - RADIUS_TYPE_ACCT_DELAY_TIME, delta.tv_sec) == 0) { + RADIUS_TYPE_ACCT_DELAY_TIME, delta.tv_sec) == 0) radius_update_id(lap->pkt); - new_message = 1; - } } } - if (new_message) { + if (radius_get_code(lap->pkt) == RADIUS_CODE_ACCOUNTING_REQUEST) radius_set_accounting_request_authenticator(lap->pkt, radius_get_server_secret(lap)); - } + else + radius_put_message_authenticator(lap->pkt, + radius_get_server_secret(lap)); lap->ntry--; if (radius_send(lap->socket, lap->pkt, 0) != 0) { @@ -440,12 +440,17 @@ radius_request_io_event(int fd, short evmask, void *context) } flags |= RADIUS_REQUEST_ERROR; } else if (lap->secret[0] == '\0') { - flags |= RADIUS_REQUEST_CHECK_AUTHENTICATOR_NO_CHECK; + flags |= RADIUS_REQUEST_CHECK_AUTHENTICATOR_NO_CHECK + | RADIUS_REQUEST_CHECK_MSG_AUTHENTICATOR_NO_CHECK; } else { radius_set_request_packet(respkt, lap->pkt); if (!radius_check_response_authenticator(respkt, lap->secret)) flags |= RADIUS_REQUEST_CHECK_AUTHENTICATOR_OK; + if (!radius_has_attr(respkt, RADIUS_TYPE_MESSAGE_AUTHENTICATOR)) + flags |= RADIUS_REQUEST_CHECK_NO_MSG_AUTHENTICATOR; + else if (radius_check_message_authenticator(respkt, lap->secret) == 0) + flags |= RADIUS_REQUEST_CHECK_MSG_AUTHENTICATOR_OK; } radius_on_response(lap, respkt, flags, 0); radius_delete_packet(respkt); @@ -453,7 +458,7 @@ radius_request_io_event(int fd, short evmask, void *context) if (lap->ntry > 0) { RADIUS_REQ_DBG((LOG_DEBUG, "%s() timed out retry", __func__)); - radius_request0(lap, 0); + radius_request0(lap); return; } RADIUS_REQ_DBG((LOG_DEBUG, "%s() timed out", __func__)); diff --git a/usr.sbin/npppd/npppd/radius_req.h b/usr.sbin/npppd/npppd/radius_req.h index bd4dd0aa53a..4287c172fdb 100644 --- a/usr.sbin/npppd/npppd/radius_req.h +++ b/usr.sbin/npppd/npppd/radius_req.h @@ -1,4 +1,4 @@ -/* $OpenBSD: radius_req.h,v 1.7 2015/07/23 09:04:06 yasuoka Exp $ */ +/* $OpenBSD: radius_req.h,v 1.8 2024/02/26 08:47:28 yasuoka Exp $ */ /*- * Copyright (c) 2009 Internet Initiative Japan Inc. @@ -51,6 +51,15 @@ /** authenticator is not checked */ #define RADIUS_REQUEST_CHECK_AUTHENTICATOR_NO_CHECK 0x0020 +/** no message authenticator */ +#define RADIUS_REQUEST_CHECK_NO_MSG_AUTHENTICATOR 0x0040 + +/** has valid message authenticator */ +#define RADIUS_REQUEST_CHECK_MSG_AUTHENTICATOR_OK 0x0080 + +/** message authenticator is not checked*/ +#define RADIUS_REQUEST_CHECK_MSG_AUTHENTICATOR_NO_CHECK 0x0100 + /** type for context to handle RADIUS request / response */ typedef void * RADIUS_REQUEST_CTX; -- 2.20.1