From: Alan T. DeKok Date: Wed, 30 Aug 2023 15:10:27 +0000 (-0400) Subject: move CHAP encode to src/lib/util X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c380933062bfac135ffe72e2b437484f5d19fe2;p=thirdparty%2Ffreeradius-server.git move CHAP encode to src/lib/util because it's no longer a RADIUS protocol function --- diff --git a/src/bin/radclient.c b/src/bin/radclient.c index 6efb74fb601..97067071155 100644 --- a/src/bin/radclient.c +++ b/src/bin/radclient.c @@ -34,6 +34,7 @@ RCSID("$Id$") #include #include #include +#include #ifdef HAVE_OPENSSL_SSL_H #include #endif @@ -1051,10 +1052,10 @@ static int send_one_packet(rc_request_t *request) vector = request->packet->vector; } - fr_radius_encode_chap_password(buffer, - fr_rand() & 0xff, vector, RADIUS_AUTH_VECTOR_LENGTH, - request->password->vp_strvalue, - request->password->vp_length); + fr_chap_encode(buffer, + fr_rand() & 0xff, vector, RADIUS_AUTH_VECTOR_LENGTH, + request->password->vp_strvalue, + request->password->vp_length); fr_pair_value_memdup(vp, buffer, sizeof(buffer), false); } else if (fr_pair_find_by_da_nested(&request->request_pairs, NULL, attr_ms_chap_password) != NULL) { diff --git a/src/lib/util/chap.c b/src/lib/util/chap.c new file mode 100644 index 00000000000..729fe652c3c --- /dev/null +++ b/src/lib/util/chap.c @@ -0,0 +1,52 @@ +/* + * This program is is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 of the + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** Functions for parsing raw network packets + * + * @file src/lib/util/chap.c + * + * @author Alan DeKok (aland@networkradius.com) + * @copyright 2023 Network RADIUS SAS (legal@networkradius.com) + */ +#include + +/** Encode a CHAP password + * + * @param[out] out An output buffer of 17 bytes (id + MD5 digest). + * @param[in] id CHAP ID, a random ID for request/response matching. + * @param[in] challenge the CHAP challenge + * @param[in] challenge_len Length of the challenge. + * @param[in] password Input password to hash. + * @param[in] password_len Length of input password. + */ +void fr_chap_encode(uint8_t out[static 1 + FR_CHAP_CHALLENGE_LENGTH], + uint8_t id, uint8_t const *challenge, size_t challenge_len, + char const *password, size_t password_len) +{ + fr_md5_ctx_t *md5_ctx; + + md5_ctx = fr_md5_ctx_alloc_from_list(); + + /* + * First ingest the ID and the password. + */ + fr_md5_update(md5_ctx, (uint8_t const *)&id, 1); + fr_md5_update(md5_ctx, (uint8_t const *)password, password_len); + + fr_md5_update(md5_ctx, challenge, challenge_len); + out[0] = id; + fr_md5_final(out + 1, md5_ctx); + fr_md5_ctx_free_from_list(&md5_ctx); +} diff --git a/src/lib/util/chap.h b/src/lib/util/chap.h new file mode 100644 index 00000000000..6fb829eefd0 --- /dev/null +++ b/src/lib/util/chap.h @@ -0,0 +1,41 @@ +#pragma once +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** Structures and functions for parsing raw network packets + * + * @file src/lib/util/chap.h + * + * @author Alan DeKok (aland@networkradius.com) + * @copyright 2023 Network RADIUS SAS (legal@networkradius.com) + */ +RCSIDH(chap_h, "$Id$") + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define FR_CHAP_CHALLENGE_LENGTH (MD5_DIGEST_LENGTH) + +void fr_chap_encode(uint8_t out[static 1 + FR_CHAP_CHALLENGE_LENGTH], + uint8_t id, uint8_t const *challenge, size_t challenge_len, + char const *password, size_t password_len); + +#ifdef __cplusplus +} +#endif diff --git a/src/lib/util/libfreeradius-util.mk b/src/lib/util/libfreeradius-util.mk index 5d4e3a6a7fb..02ab91b4694 100644 --- a/src/lib/util/libfreeradius-util.mk +++ b/src/lib/util/libfreeradius-util.mk @@ -17,6 +17,7 @@ SOURCES := \ base64.c \ calc.c \ cap.c \ + chap.c \ dbuff.c \ debug.c \ decode.c \ diff --git a/src/modules/rlm_chap/all.mk b/src/modules/rlm_chap/all.mk index e716d22c956..d7e5d76f212 100644 --- a/src/modules/rlm_chap/all.mk +++ b/src/modules/rlm_chap/all.mk @@ -3,5 +3,5 @@ TARGETNAME := rlm_chap TARGET := $(TARGETNAME)$(L) SOURCES := $(TARGETNAME).c -TGT_PREREQS := libfreeradius-radius$(L) +TGT_PREREQS := libfreeradius-util$(L) LOG_ID_LIB = 4 diff --git a/src/modules/rlm_chap/rlm_chap.c b/src/modules/rlm_chap/rlm_chap.c index 1480d6be9c4..b4074acbcac 100644 --- a/src/modules/rlm_chap/rlm_chap.c +++ b/src/modules/rlm_chap/rlm_chap.c @@ -28,7 +28,7 @@ RCSID("$Id$") #include #include #include -#include +#include #include typedef struct { @@ -131,7 +131,7 @@ static xlat_action_t xlat_func_chap_password(TALLOC_CTX *ctx, fr_dcursor_t *out, request_t *request, fr_value_box_list_t *in) { rlm_chap_t const *inst = talloc_get_type_abort_const(xctx->mctx->inst->data, rlm_chap_t); - uint8_t chap_password[1 + RADIUS_CHAP_CHALLENGE_LENGTH]; + uint8_t chap_password[1 + FR_CHAP_CHALLENGE_LENGTH]; fr_value_box_t *vb; uint8_t const *vector; size_t vector_len; @@ -152,7 +152,7 @@ static xlat_action_t xlat_func_chap_password(TALLOC_CTX *ctx, fr_dcursor_t *out, vector = request->packet->vector; vector_len = RADIUS_AUTH_VECTOR_LENGTH; } - fr_radius_encode_chap_password(chap_password, (uint8_t)(fr_rand() & 0xff), vector, vector_len, + fr_chap_encode(chap_password, (uint8_t)(fr_rand() & 0xff), vector, vector_len, in_head->vb_strvalue, in_head->vb_length); MEM(vb = fr_value_box_alloc_null(ctx)); @@ -218,7 +218,7 @@ static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result, { rlm_chap_t const *inst = talloc_get_type_abort_const(mctx->inst->data, rlm_chap_t); fr_pair_t *known_good; - uint8_t pass_str[1 + RADIUS_CHAP_CHALLENGE_LENGTH]; + uint8_t pass_str[1 + FR_CHAP_CHALLENGE_LENGTH]; chap_auth_call_env_t *env_data = talloc_get_type_abort(mctx->env_data, chap_auth_call_env_t); int ret; @@ -245,7 +245,7 @@ static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result, RETURN_MODULE_INVALID; } - if (env_data->chap_password.vb_length != RADIUS_CHAP_CHALLENGE_LENGTH + 1) { + if (env_data->chap_password.vb_length != FR_CHAP_CHALLENGE_LENGTH + 1) { REDEBUG("&request.CHAP-Password has invalid length"); RETURN_MODULE_INVALID; } @@ -282,8 +282,8 @@ static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result, vector = request->packet->vector; vector_len = RADIUS_AUTH_VECTOR_LENGTH; } - fr_radius_encode_chap_password(pass_str, env_data->chap_password.vb_octets[0], vector, vector_len, - known_good->vp_strvalue, known_good->vp_length); + fr_chap_encode(pass_str, env_data->chap_password.vb_octets[0], vector, vector_len, + known_good->vp_strvalue, known_good->vp_length); /* * The password_find function already emits @@ -307,8 +307,8 @@ static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result, RINDENT(); RDEBUG3("CHAP challenge : %pH", fr_box_octets(p, length)); RDEBUG3("Client sent : %pH", fr_box_octets(env_data->chap_password.vb_octets + 1, - RADIUS_CHAP_CHALLENGE_LENGTH)); - RDEBUG3("We calculated : %pH", fr_box_octets(pass_str + 1, RADIUS_CHAP_CHALLENGE_LENGTH)); + FR_CHAP_CHALLENGE_LENGTH)); + RDEBUG3("We calculated : %pH", fr_box_octets(pass_str + 1, FR_CHAP_CHALLENGE_LENGTH)); REXDENT(); } @@ -316,7 +316,7 @@ static unlang_action_t CC_HINT(nonnull) mod_authenticate(rlm_rcode_t *p_result, * Skip the id field at the beginning of the * password and chap response. */ - ret = fr_digest_cmp(pass_str + 1, env_data->chap_password.vb_octets + 1, RADIUS_CHAP_CHALLENGE_LENGTH); + ret = fr_digest_cmp(pass_str + 1, env_data->chap_password.vb_octets + 1, FR_CHAP_CHALLENGE_LENGTH); if (ephemeral) TALLOC_FREE(known_good); if (ret != 0) { REDEBUG("Password comparison failed: password is incorrect"); diff --git a/src/protocols/radius/encode.c b/src/protocols/radius/encode.c index b6c813e2715..0c3d89ef0e5 100644 --- a/src/protocols/radius/encode.c +++ b/src/protocols/radius/encode.c @@ -41,34 +41,6 @@ static ssize_t encode_child(fr_dbuff_t *dbuff, fr_da_stack_t *da_stack, unsigned int depth, fr_dcursor_t *cursor, void *encode_ctx); -/** Encode a CHAP password - * - * @param[out] out An output buffer of 17 bytes (id + digest). - * @param[in] id CHAP ID, a random ID for request/response matching. - * @param[in] vector from the original packet or challenge attribute. - * @param[in] vector_len Length of the vector. - * @param[in] password Input password to hash. - * @param[in] password_len Length of input password. - */ -void fr_radius_encode_chap_password(uint8_t out[static 1 + RADIUS_CHAP_CHALLENGE_LENGTH], - uint8_t id, uint8_t const *vector, size_t vector_len, - char const *password, size_t password_len) -{ - fr_md5_ctx_t *md5_ctx; - - md5_ctx = fr_md5_ctx_alloc_from_list(); - - /* - * First ingest the ID and the password. - */ - fr_md5_update(md5_ctx, (uint8_t const *)&id, 1); - fr_md5_update(md5_ctx, (uint8_t const *)password, password_len); - - fr_md5_update(md5_ctx, vector, vector_len); - out[0] = id; - fr_md5_final(out + 1, md5_ctx); - fr_md5_ctx_free_from_list(&md5_ctx); -} /** "encrypt" a password RADIUS style * diff --git a/src/protocols/radius/radius.h b/src/protocols/radius/radius.h index 11817b969ab..7a897230ad7 100644 --- a/src/protocols/radius/radius.h +++ b/src/protocols/radius/radius.h @@ -34,7 +34,6 @@ #define RADIUS_MAX_STRING_LENGTH 253 #define RADIUS_MAX_TUNNEL_PASSWORD_LENGTH 249 #define RADIUS_AUTH_VECTOR_LENGTH 16 -#define RADIUS_CHAP_CHALLENGE_LENGTH 16 #define RADIUS_MESSAGE_AUTHENTICATOR_LENGTH 16 #define RADIUS_MAX_PASS_LENGTH 128 #define RADIUS_MAX_ATTRIBUTES 255 @@ -190,10 +189,6 @@ ssize_t fr_radius_decode_abinary(fr_pair_t *vp, uint8_t const *data, size_t dat /* * protocols/radius/encode.c */ -void fr_radius_encode_chap_password(uint8_t out[static 1 + RADIUS_CHAP_CHALLENGE_LENGTH], - uint8_t id, uint8_t const *vector, size_t vector_len, - char const *password, size_t password_len) CC_HINT(nonnull(1,3,5)); - ssize_t fr_radius_encode_pair(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *encode_ctx); /*