#include "config.h"
#endif
-#ifdef CHAPMS
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "magic.h"
#include "mppe.h"
+#ifdef UNIT_TEST
+#undef PPP_WITH_MPPE
+#endif
+
static void ascii2unicode (char[], int, u_char[]);
static void NTPasswordHash (u_char *, int, u_char[MD4_SIGNATURE_SIZE]);
static void ChallengeResponse (u_char *, u_char *, u_char[24]);
static void GenerateAuthenticatorResponsePlain
(char*, int, u_char[24], u_char[16], u_char *,
char *, u_char[41]);
-#ifdef MSLANMAN
+#ifdef PPP_WITH_MSLANMAN
static void ChapMS_LANMan (u_char *, char *, int, u_char *);
#endif
-#ifdef MSLANMAN
+#ifdef PPP_WITH_MSLANMAN
bool ms_lanman = 0; /* Use LanMan password instead of NT */
/* Has meaning only with MS-CHAP challenges */
#endif
-#ifdef MPPE
+#ifdef PPP_WITH_MPPE
#ifdef DEBUGMPPEKEY
/* For MPPE debug */
/* Use "[]|}{?/><,`!2&&(" (sans quotes) for RFC 3079 MS-CHAPv2 test value */
* Command-line options.
*/
static option_t chapms_option_list[] = {
-#ifdef MSLANMAN
+#ifdef PPP_WITH_MSLANMAN
{ "ms-lanman", o_bool, &ms_lanman,
"Use LanMan passwd when using MS-CHAP", 1 },
#endif
if (response_len != MS_CHAP_RESPONSE_LEN)
goto bad;
-#ifndef MSLANMAN
+#ifndef PPP_WITH_MSLANMAN
if (!response[MS_CHAP_USENT]) {
/* Should really propagate this into the error packet. */
notice("Peer request for LANMAN auth not supported");
/* Generate the expected response. */
ChapMS(challenge, (char *)secret, secret_len, md);
-#ifdef MSLANMAN
+#ifdef PPP_WITH_MSLANMAN
/* Determine which part of response to verify against */
if (!response[MS_CHAP_USENT])
diff = memcmp(&response[MS_CHAP_LANMANRESP],
static void
NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE])
{
-#ifdef __NetBSD__
+#if defined(__NetBSD__) || !defined(USE_MD4)
/* NetBSD uses the libc md4 routines which take bytes instead of bits */
int mdlen = secret_len;
#else
MD4_CTX md4Context;
MD4Init(&md4Context);
- /* MD4Update can take at most 64 bytes at a time */
+#if !defined(USE_MD4)
+ /* Internal MD4Update can take at most 64 bytes at a time */
while (mdlen > 512) {
MD4Update(&md4Context, secret, 512);
secret += 64;
mdlen -= 512;
}
+#endif
MD4Update(&md4Context, secret, mdlen);
MD4Final(hash, &md4Context);
ChallengeResponse(Challenge, PasswordHash, NTResponse);
}
-#ifdef MSLANMAN
+#ifdef PPP_WITH_MSLANMAN
static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */
static void
}
-#ifdef MPPE
+#ifdef PPP_WITH_MPPE
/*
* Set mppe_xxxx_key from MS-CHAP credentials. (see RFC 3079)
mppe_set_chapv2(PasswordHashHash, NTResponse, IsServer);
}
-#endif /* MPPE */
+#endif /* PPP_WITH_MPPE */
void
ChapMS_NT(rchallenge, secret, secret_len, &response[MS_CHAP_NTRESP]);
-#ifdef MSLANMAN
+#ifdef PPP_WITH_MSLANMAN
ChapMS_LANMan(rchallenge, secret, secret_len,
&response[MS_CHAP_LANMANRESP]);
response[MS_CHAP_USENT] = 1;
#endif
-#ifdef MPPE
+#ifdef PPP_WITH_MPPE
Set_Start_Key(rchallenge, secret, secret_len);
#endif
}
&response[MS_CHAP2_PEER_CHALLENGE],
rchallenge, user, authResponse);
-#ifdef MPPE
+#ifdef PPP_WITH_MPPE
SetMasterKeys(secret, secret_len,
&response[MS_CHAP2_NTRESP], authenticator);
#endif
chapms_handle_failure,
};
+#ifndef UNIT_TEST
void
chapms_init(void)
{
chap_register_digest(&chapms2_digest);
add_options(chapms_option_list);
}
+#else
+
+#include <time.h>
+
+int debug = 1;
+int error_count = 0;
+int unsuccess = 0;
+
+void random_bytes(unsigned char *bytes, int len)
+{
+ int i = 0;
+ srand(time(NULL));
+ while (i < len) {
+ bytes[i++] = (unsigned char) rand();
+ }
+}
+
+
+int test_chap_v1(void) {
+ char *secret = "TestPassword";
+
+ unsigned char challenge[8] = {
+ 0x6c, 0x8d, 0x4b, 0xa1, 0x2b, 0x5c, 0x13, 0xc3
+ };
+ unsigned char response[MS_CHAP_RESPONSE_LEN] = {
+ };
+ unsigned char result[MS_CHAP_RESPONSE_LEN] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x91, 0x09, 0x61, 0x5a, 0x0c, 0xac, 0xac, 0x55,
+ 0x1f, 0x60, 0xe2, 0x9c, 0x00, 0xac, 0x24, 0xda,
+ 0x6e, 0xa5, 0x7b, 0xdb, 0x1d, 0x6a, 0x17, 0xc5,
+ 0x01
+ };
+
+ ChapMS(challenge, secret, strlen(secret), response);
+ return memcmp(response, result, MS_CHAP_RESPONSE_LEN);
+}
+
+int test_chap_v2(void) {
+ char *secret = "clientPass";
+ char *name = "User";
+
+ char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
+ char *saresult = "407A5589115FD0D6209F510FE9C04566932CDA56";
+
+ unsigned char authenticator[16] = {
+ 0x5B, 0x5D, 0x7C, 0x7D, 0x7B, 0x3F, 0x2F, 0x3E,
+ 0x3C, 0x2C, 0x60, 0x21, 0x32, 0x26, 0x26, 0x28
+ };
+ unsigned char peerchallenge[16] = {
+ 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A,
+ 0x28, 0x29, 0x5F, 0x2B, 0x3A, 0x33, 0x7C, 0x7E
+ };
+ unsigned char result[MS_CHAP_NTRESP_LEN] = {
+ 0x82, 0x30, 0x9E, 0xCD, 0x8D, 0x70, 0x8B, 0x5E,
+ 0xA0, 0x8F, 0xAA, 0x39, 0x81, 0xCD, 0x83, 0x54,
+ 0x42, 0x33, 0x11, 0x4A, 0x3D, 0x85, 0xD6, 0xDF
+ };
+
+ unsigned char response[MS_CHAP2_RESPONSE_LEN] = {
+ };
+
+ ChapMS2(authenticator, peerchallenge, name,
+ secret, strlen(secret), response,
+ (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR);
+
+ return memcmp(&response[MS_CHAP2_NTRESP], result, MS_CHAP2_NTRESP_LEN) ||
+ strncmp(saresponse, saresult, MS_AUTH_RESPONSE_LENGTH);
+}
+
+int main(int argc, char *argv[]) {
+
+ if (test_chap_v1()) {
+ printf("CHAPv1 failed\n");
+ return -1;
+ }
+
+ if (test_chap_v2()) {
+ printf("CHAPv2 failed\n");
+ return -1;
+ }
+
+ printf("Success\n");
+ return 0;
+}
+
+#endif /* UNIT_TEST */
-#endif /* CHAPMS */