Update some of the LM hash code to better respect the seperation between
authorAndrew Bartlett <abartlet@samba.org>
Sat, 25 May 2002 08:24:24 +0000 (08:24 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Sat, 25 May 2002 08:24:24 +0000 (08:24 +0000)
unix and DOS strings.

This pushes all the 'have to uppercase, must be 14 chars' stuff behind the
the interface.

Andrew Bartlett
(This used to be commit dec650efa8ab1466114c2e6d469320a319499ea0)

source3/libsmb/cliconnect.c
source3/libsmb/clirap.c
source3/libsmb/smbencrypt.c

index 0b6436b50803dcddcbf333b299db961fdece6399..8129618fda74a0773e86f309b4a245021e0f3b24 100644 (file)
@@ -63,8 +63,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user,
        if (passlen > 0 && (cli->sec_mode & 2) && passlen != 24) {
                /* Encrypted mode needed, and non encrypted password supplied. */
                passlen = 24;
-               clistr_push(cli, pword, pass, -1, STR_TERMINATE);
-               SMBencrypt((uchar *)pword,cli->secblob.data,(uchar *)pword);
+               SMBencrypt(pass,cli->secblob.data,(uchar *)pword);
        } else if ((cli->sec_mode & 2) && passlen == 24) {
                /* Encrypted mode needed, and encrypted password supplied. */
                memcpy(pword, pass, passlen);
@@ -241,9 +240,15 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user,
 }
 
 
-/****************************************************************************
-do a NT1 NTLM/LM encrypted session setup
-****************************************************************************/
+/**
+   do a NT1 NTLM/LM encrypted session setup
+   @param cli client state to create do session setup on
+   @param user username
+   @param pass *either* cleartext password (passlen !=24) or LM response.
+   @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
+   @param workgroup The user's domain.
+*/
+
 static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, 
                                  char *pass, int passlen,
                                  char *ntpass, int ntpasslen,
@@ -261,12 +266,8 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user,
                /* non encrypted password supplied. Ignore ntpass. */
                passlen = 24;
                ntpasslen = 24;
-               clistr_push(cli, pword, 
-                           pass?pass:"", sizeof(pword), STR_TERMINATE|STR_ASCII);
-               clistr_push(cli, ntpword, 
-                           pass?pass:"", sizeof(ntpword), STR_TERMINATE|STR_ASCII);
-               SMBencrypt((uchar *)pword,cli->secblob.data,(uchar *)pword);
-               SMBNTencrypt((uchar *)ntpword,cli->secblob.data,(uchar *)ntpword);
+               SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword);
+               SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword);
        } else {
                memcpy(pword, pass, passlen);
                memcpy(ntpword, ntpass, ntpasslen);
@@ -611,8 +612,8 @@ BOOL cli_session_setup(struct cli_state *cli,
                return cli_session_setup_plaintext(cli, user, "", workgroup);
        }
 
-       /* if the server doesn't support encryption then we have to use plaintext. The 
-          second password is ignored */
+       /* if the server doesn't support encryption then we have to use 
+          plaintext. The second password is ignored */
        if ((cli->sec_mode & 2) == 0) {
                return cli_session_setup_plaintext(cli, user, pass, workgroup);
        }
index a2b6c8bb8b4a957e08b49ec58c2e6ea1e7b4ccc0..3eb9586a675178dbf7d28e1cce139cb66b7c8d98 100644 (file)
@@ -283,8 +283,6 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
   char param[16+sizeof(fstring)];
   char data[532];
   char *p = param;
-  fstring upper_case_old_pw;
-  fstring upper_case_new_pw;
   unsigned char old_pw_hash[16];
   unsigned char new_pw_hash[16];
   int data_len;
@@ -316,9 +314,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
    * Get the Lanman hash of the old password, we
    * use this as the key to make_oem_passwd_hash().
    */
-  memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw));
-  clistr_push(cli, upper_case_old_pw, old_password, -1,STR_TERMINATE|STR_UPPER|STR_ASCII);
-  E_P16((uchar *)upper_case_old_pw, old_pw_hash);
+  E_deshash(old_password, old_pw_hash);
 
   clistr_push(cli, dos_new_password, new_password, -1, STR_TERMINATE|STR_ASCII);
 
@@ -328,10 +324,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
   /* 
    * Now place the old password hash in the data.
    */
-  memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw));
-  clistr_push(cli, upper_case_new_pw, new_password, -1, STR_TERMINATE|STR_UPPER|STR_ASCII);
-
-  E_P16((uchar *)upper_case_new_pw, new_pw_hash);
+  E_deshash(new_password, new_pw_hash);
 
   E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]);
 
index bac64c2e508dd0f6916334181dce589fec5524c0..c298616220c43d2db8756af79f990880bb578d52 100644 (file)
 
 /*
    This implements the X/Open SMB password encryption
-   It takes a password, a 8 byte "crypt key" and puts 24 bytes of 
-   encrypted password into p24 */
+   It takes a password ('unix' string), a 8 byte "crypt key" 
+   and puts 24 bytes of encrypted password into p24 */
 void SMBencrypt(const uchar *passwd, const uchar *c8, uchar *p24)
 {
-       uchar p14[15], p21[21];
+       uchar p21[21];
 
        memset(p21,'\0',21);
-       memset(p14,'\0',14);
-       StrnCpy((char *)p14,(const char *)passwd,14);
-
-       strupper((char *)p14);
-       E_P16(p14, p21); 
+       E_deshash(passwd, p21); 
 
        SMBOWFencrypt(p21, c8, p24);
 
@@ -49,61 +45,74 @@ void SMBencrypt(const uchar *passwd, const uchar *c8, uchar *p24)
 #endif
 }
 
-/* 
+/**
  * Creates the MD4 Hash of the users password in NT UNICODE.
+ * @param passwd password in 'unix' charset.
+ * @param p16 return password hashed with md4, caller allocated 16 byte buffer
  */
  
-void E_md4hash(const uchar *passwd, uchar *p16)
+void E_md4hash(const char *passwd, uchar p16[16])
 {
        int len;
        smb_ucs2_t wpwd[129];
        
-       /* Password cannot be longer than 128 characters */
-       len = strlen((const char *)passwd);
-       if(len > 128)
-               len = 128;
        /* Password must be converted to NT unicode - null terminated. */
        push_ucs2(NULL, wpwd, (const char *)passwd, 256, STR_UNICODE|STR_NOALIGN|STR_TERMINATE);
        /* Calculate length in bytes */
        len = strlen_w(wpwd) * sizeof(int16);
 
        mdfour(p16, (unsigned char *)wpwd, len);
+       ZERO_STRUCT(wpwd);      
 }
 
-/* Does both the NT and LM owfs of a user's password */
-void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16])
+/**
+ * Creates the MD4 Hash of the users password in NT UNICODE.
+ * @param passwd password in 'unix' charset.
+ * @param p16 return password hashed with md4, caller allocated 16 byte buffer
+ */
+void E_deshash(const char *passwd, uchar p16[16])
 {
-       char passwd[514];
+       uchar dospwd[15]; /* Password must not be > 14 chars long. */
+       ZERO_STRUCT(dospwd);
+       ZERO_STRUCTP(p16);
+       
+       /* Password must be converted to DOS charset - null terminated. */
+       push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE);
 
-       memset(passwd,'\0',514);
-       safe_strcpy( passwd, pwd, sizeof(passwd)-1);
+       E_P16(dospwd, p16);
 
+       ZERO_STRUCT(dospwd);    
+}
+
+/**
+ * Creates the MD4 and DES (LM) Hash of the users password.  
+ * MD4 is of the NT Unicode, DES is of the DOS UPPERCASE password.
+ * @param passwd password in 'unix' charset.
+ * @param nt_p16 return password hashed with md4, caller allocated 16 byte buffer
+ * @param p16 return password hashed with des, caller allocated 16 byte buffer
+ */
+/* Does both the NT and LM owfs of a user's password */
+void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16])
+{
        /* Calculate the MD4 hash (NT compatible) of the password */
        memset(nt_p16, '\0', 16);
-       E_md4hash((uchar *)passwd, nt_p16);
+       E_md4hash(pwd, nt_p16);
 
 #ifdef DEBUG_PASSWORD
        DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n"));
-       dump_data(120, passwd, strlen(passwd));
+       dump_data(120, pwd, strlen(pwd));
        dump_data(100, (char *)nt_p16, 16);
 #endif
 
-       /* Mangle the passwords into Lanman format */
-       passwd[14] = '\0';
-       strupper(passwd);
-
-       /* Calculate the SMB (lanman) hash functions of the password */
-
-       memset(p16, '\0', 16);
-       E_P16((uchar *) passwd, (uchar *)p16);
+       E_deshash(pwd, (uchar *)p16);
 
 #ifdef DEBUG_PASSWORD
        DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n"));
-       dump_data(120, passwd, strlen(passwd));
+       dump_data(120, pwd, strlen(pwd));
        dump_data(100, (char *)p16, 16);
 #endif
-       /* clear out local copy of user's password (just being paranoid). */
-       memset(passwd, '\0', sizeof(passwd));
 }
 
 /* Does both the NTLMv2 owfs of a user's password */