#include <freeradius-devel/util/time.h>
#include <freeradius-devel/radius/list.h>
#include <freeradius-devel/radius/radius.h>
+#include <freeradius-devel/util/chap.h>
#ifdef HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h>
#endif
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) {
--- /dev/null
+/*
+ * 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 <freeradius-devel/util/chap.h>
+
+/** 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);
+}
--- /dev/null
+#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 <freeradius-devel/util/md5.h>
+
+#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
base64.c \
calc.c \
cap.c \
+ chap.c \
dbuff.c \
debug.c \
decode.c \
TARGET := $(TARGETNAME)$(L)
SOURCES := $(TARGETNAME).c
-TGT_PREREQS := libfreeradius-radius$(L)
+TGT_PREREQS := libfreeradius-util$(L)
LOG_ID_LIB = 4
#include <freeradius-devel/server/base.h>
#include <freeradius-devel/server/password.h>
#include <freeradius-devel/server/module_rlm.h>
-#include <freeradius-devel/radius/radius.h>
+#include <freeradius-devel/util/chap.h>
#include <freeradius-devel/unlang/xlat_func.h>
typedef struct {
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;
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));
{
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;
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;
}
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
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();
}
* 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");
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
*
#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
/*
* 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);
/*