Patch: UTF-8 for rlm_mschap

Josh Howlett josh.howlett at bristol.ac.uk
Wed Aug 2 10:27:25 CEST 2006


Please find below a patch to enable support UTF-8 encoded passwords.

It also adds a single configuration option to enable or disable this.

josh.

--- ../../../../freeradius-1.1.2/src/modules/rlm_mschap/rlm_mschap.c
2006-04-13 17:28:30.000000000 +0100
+++ rlm_mschap.c        2006-07-26 10:55:42.000000000 +0100
@@ -187,21 +187,80 @@
    *     ntpwdhash converts Unicode password to 16-byte NT hash
    *     with MD4
    */
-static void ntpwdhash (unsigned char *szHash, const char *szPassword)
+static void ntpwdhash (unsigned char *szHash, const char *szPassword,
int utf8_password)
   {
          char szUnicodePass[513];
          int nPasswordLen;
          int i;

+       if (utf8_password) {
+
+               /*
+                * We've been told to expect a UTF-8 password.
+                * Use iconv() to perform UTF-8 to Unicode conversion.
+                */
+
+               DEBUG2("  rlm_mschap: using UTF-8 to Unicode conversion");
+
+               iconv_t cd;
+               const char *fptr;
+               char *tptr;
+               size_t ileft,oleft;
+               fptr=szPassword;
+               tptr=szUnicodePass;
+
+               cd=iconv_open("UCS-2LE", "UTF-8");
+
+               if (cd == (iconv_t)-1) {
+                       DEBUG2("  rlm_mschap: iconv failed; trying the
7-bit conversion");
+                       /*
+                        * Skip to the 7-bit password conversion
+                        */
+                       goto sevenbit;
+               }
+
+               ileft=strlen(szPassword);
+               oleft=512;
+               if (iconv(cd,&fptr, &ileft, &tptr, &oleft) != (size_t)-1) {
+                       iconv_close(cd);
+                       nPasswordLen = strlen(szUnicodePass);
+                       nPasswordLen=512-oleft;
+                       /* Encrypt Unicode password to a 16-byte MD4 hash */
+                       md4_calc(szHash, szUnicodePass, nPasswordLen );
+                       return;
+               }
+
+               /*
+                * We encountered a problem. Recovery isn't possible,
+                * so log the problem and optimistically try the 7-bit
conversion.
+                */
+
+               if (errno == EINVAL) {
+                       DEBUG2("  rlm_mschap: An incomplete multibyte
sequence has been encountered in the password");
+                        } else if (errno == E2BIG) {
+                       DEBUG2("  rlm_mschap: password too big to convert");
+               } else if (errno == EILSEQ) {
+                       DEBUG2("  rlm_mschap: an invalid multibyte
sequence has been encountered in the password");
+               } else {
+                       DEBUG2("  rlm_mschap: unknown iconv error");
+               }
+               DEBUG2("  rlm_mschap: trying the 7-bit conversion instead");
+               iconv_close(cd);
+       }
+
          /*
-        *      NT passwords are unicode.  Convert plain text password
-        *      to unicode by inserting a zero every other byte
+        * 7-bit password conversion
           */
+
+       sevenbit:
+
+       DEBUG2("  rlm_mschap: using 7-bit to Unicode conversion");
+
          nPasswordLen = strlen(szPassword);
          for (i = 0; i < nPasswordLen; i++) {
                  szUnicodePass[i << 1] = szPassword[i];
                  szUnicodePass[(i << 1) + 1] = 0;
-       }
+       }

          /* Encrypt Unicode password to a 16-byte MD4 hash */
          md4_calc(szHash, szUnicodePass, (nPasswordLen<<1) );
@@ -290,6 +349,7 @@
          char *xlat_name;
          char *ntlm_auth;
          char *auth_type;
+       int utf8_password;
   } rlm_mschap_t;


@@ -602,6 +662,8 @@
            offsetof(rlm_mschap_t, passwd_file), NULL,  NULL },
          { "ntlm_auth",   PW_TYPE_STRING_PTR,
            offsetof(rlm_mschap_t, ntlm_auth), NULL,  NULL },
+       { "utf8_password",    PW_TYPE_BOOLEAN,
+         offsetof(rlm_mschap_t,utf8_password), NULL, "yes" },

          { NULL, -1, 0, NULL, NULL }             /* end the list */
   };
@@ -1121,7 +1183,7 @@
                          radlog(L_ERR, "No memory");
                          return RLM_MODULE_FAIL;
                  } else {
-                       ntpwdhash(nt_password->strvalue,
password->strvalue);
+                       ntpwdhash(nt_password->strvalue,
password->strvalue, inst->utf8_password);
                          nt_password->length = 16;
                          pairadd(&request->config_items, nt_password);
                  }
--- ../../../../freeradius-1.1.2/raddb/radiusd.conf.in  2006-04-20
19:40:29.000000000 +0100
+++ ../../../raddb/radiusd.conf.in      2006-07-26 10:57:29.000000000 +0100
@@ -707,6 +707,10 @@
                  # Be VERY careful when editing the following line!
                  #
                  #ntlm_auth = "/path/to/ntlm_auth --request-nt-key
--username=%{Stripped-User-Name:-%{User-Name:-None}}
--challenge=%{mschap:Challenge:-00} --nt-response=%{mschap:NT-Response:-00}"
+
+               # Use UTF-8 encoded passwords.
+               #
+               utf8_password = yes
          }

          # Lightweight Directory Access Protocol (LDAP)



More information about the Freeradius-Devel mailing list