Enable MS-CHAPv1 support in radclient.
authorAlan T. DeKok <aland@freeradius.org>
Wed, 9 Jun 2010 06:38:05 +0000 (08:38 +0200)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 10 Jun 2010 08:38:45 +0000 (10:38 +0200)
share/dictionary.freeradius.internal
src/include/radius.h
src/main/Makefile.in
src/main/radclient.c

index 83ee02e..7a6a635 100644 (file)
@@ -212,6 +212,8 @@ ATTRIBUTE   EAP-EMSK                                1130    octets
 ATTRIBUTE      Recv-CoA-Type                           1131    integer
 ATTRIBUTE      Send-CoA-Type                           1132    integer
 
+ATTRIBUTE      MS-CHAP-Password                        1133    string
+
 #
 #      Range:  1200-1279
 #              EAP-SIM (and other EAP type) weirdness.
index a8be5d3..7816ffc 100644 (file)
 #define PW_HOME_SERVER_POOL            1111
 #define PW_RECV_COA_TYPE               1131
 #define PW_SEND_COA_TYPE               1132
+#define PW_MSCHAP_PASSWORD             1133
 
 /*
  *     Integer Translations
index 118e8ed..6a0b8d3 100644 (file)
@@ -108,10 +108,20 @@ listen.lo: listen.c dhcpd.c command.c
 #
 
 radclient.lo: radclient.c $(INCLUDES)
-       $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c radclient.c
+       $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -I ../modules/rlm_mschap -c radclient.c
 
-radclient: radclient.lo $(LIBRADIUS)
-       $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(LINK_MODE) -o radclient radclient.lo $(LIBRADIUS) $(LIBS)
+MSCHAP_OBJS := ../modules/rlm_mschap/smbdes.lo ../modules/rlm_mschap/mschap.lo 
+
+radclient: radclient.lo $(MSCHAP_OBJS) $(LIBRADIUS)
+       $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(LINK_MODE) -o radclient radclient.lo $(MSCHAP_OBJS) $(LIBRADIUS) $(LIBS)
+
+# These two rules need to be specific in order to supercede the generic
+# "compile C file" rules.
+../modules/rlm_mschap/smbdes.lo: ../modules/rlm_mschap/smbdes.c
+       ${MAKE} -C ../modules/rlm_mschap/
+
+../modules/rlm_mschap/mschap.lo: ../modules/rlm_mschap/mschap.c
+       ${MAKE} -C ../modules/rlm_mschap/
 
 radsniff.lo: radsniff.c $(INCLUDES) ../include/radsniff.h
        $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c radsniff.c
index cb10ba4..24199a5 100644 (file)
@@ -37,6 +37,9 @@ RCSID("$Id$")
 
 #include <assert.h>
 
+#include "smbdes.h"
+#include "mschap.h"
+
 static int success = 0;
 static int retries = 3;
 static float timeout = 5;
@@ -148,6 +151,44 @@ static void radclient_free(radclient_t *radclient)
        free(radclient);
 }
 
+static int mschapv1_encode(VALUE_PAIR **request, const char *password)
+{
+       unsigned int i;
+       VALUE_PAIR *challenge, *response;
+       uint8_t nthash[16];
+
+       challenge = paircreate(PW_MSCHAP_CHALLENGE, VENDORPEC_MICROSOFT, PW_TYPE_OCTETS);
+       if (!challenge) {
+               fprintf(stderr, "GOT IT %d!\n", __LINE__);
+               return 0;
+       }
+
+       pairadd(request, challenge);
+       challenge->length = 8;
+       for (i = 0; i < challenge->length; i++) {
+               challenge->vp_octets[i] = fr_rand();
+       }
+
+       response = paircreate(PW_MSCHAP_RESPONSE, VENDORPEC_MICROSOFT, PW_TYPE_OCTETS);
+       if (!response) {
+               fprintf(stderr, "GOT IT %d!\n", __LINE__);
+               return 0;
+       }
+
+       pairadd(request, response);
+       response->length = 50;
+       memset(response->vp_octets, 0, response->length);
+
+       response->vp_octets[1] = 0x01; /* NT hash */
+
+       mschap_ntpwdhash(nthash, password);
+
+       smbdes_mschap(nthash, challenge->vp_octets,
+                     response->vp_octets + 26);
+       return 1;
+}
+
+
 /*
  *     Initialize a radclient data structure and add it to
  *     the global linked list.
@@ -233,6 +274,10 @@ static int radclient_init(const char *filename)
                } else if ((vp = pairfind(radclient->request->vps, PW_CHAP_PASSWORD, 0)) != NULL) {
                        strlcpy(radclient->password, vp->vp_strvalue,
                                sizeof(radclient->password));
+
+               } else if ((vp = pairfind(radclient->request->vps, PW_MSCHAP_PASSWORD, 0)) != NULL) {
+                       strlcpy(radclient->password, vp->vp_strvalue,
+                               sizeof(radclient->password));
                } else {
                        radclient->password[0] = '\0';
                }
@@ -571,6 +616,12 @@ static int send_one_packet(radclient_t *radclient)
                                                vp->vp_octets,
                                                radclient->request->id, vp);
                                vp->length = 17;
+
+                       } else if ((vp = pairfind(radclient->request->vps, PW_MSCHAP_PASSWORD, 0)) != NULL) {
+                               mschapv1_encode(&radclient->request->vps,
+                                               radclient->password);
+                       } else if (fr_debug_flag) {
+                               printf("WARNING: No password in the request\n");
                        }
                }