implement server-side generation of NTLMv2 session key. YESSS :-)
authorLuke Leighton <lkcl@samba.org>
Sun, 21 Nov 1999 19:59:56 +0000 (19:59 +0000)
committerLuke Leighton <lkcl@samba.org>
Sun, 21 Nov 1999 19:59:56 +0000 (19:59 +0000)
(This used to be commit 1092b4f6fbdf3770c0dab756b982a562def1738e)

source3/include/proto.h
source3/lib/md4.c
source3/libsmb/pwd_cache.c
source3/libsmb/smbencrypt.c
source3/smbd/password.c
source3/smbd/reply.c

index ac5022935a47920478c1feec449ce9e511ebb601..a8be8bad9744069a29006b9d1c62bb751c4374ca 100644 (file)
@@ -256,7 +256,7 @@ void initialize_multibyte_vectors( int client_codepage);
 
 /*The following definitions come from  lib/md4.c  */
 
-void mdfour(unsigned char *out, unsigned char *in, int n);
+void mdfour(unsigned char *out, const unsigned char *in, int n);
 
 /*The following definitions come from  lib/md5.c  */
 
@@ -853,6 +853,12 @@ void SMBOWFencrypt_ntv2(const uchar kr[16],
                                const uchar *srv_chal, int srv_chal_len,
                                const uchar *cli_chal, int cli_chal_len,
                                char resp_buf[16]);
+void SMBsesskeygen_ntv2(const uchar kr[16], 
+                               const uchar *nt_resp, 
+                               char sess_key[16]);
+void SMBsesskeygen_ntv1(const uchar kr[16], 
+                               const uchar *nt_resp, 
+                               char sess_key[16]);
 void SMBgenclientchals(char *lm_cli_chal,
                                char *nt_cli_chal, int *nt_cli_chal_len,
                                const char *srv, const char *dom);
@@ -4016,7 +4022,8 @@ void add_session_user(char *user);
 BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8],
                                const char *user, const char *domain,
                                uchar *lm_pass, size_t lm_pwd_len,
-                               uchar *nt_pass, size_t nt_pwd_len);
+                               uchar *nt_pass, size_t nt_pwd_len,
+                               uchar sess_key[16]);
 BOOL pass_check_smb(struct smb_passwd *smb_pass, char *domain, uchar *chal,
                uchar *lm_pwd, size_t lm_pwd_len,
                uchar *nt_pwd, size_t nt_pwd_len,
index 30f2b6b8c6b6848f354b4a8458d1537da60010b3..56c9e02ffbef0c63e10f5eb97a899801e68acd78 100644 (file)
@@ -101,7 +101,7 @@ static void mdfour64(uint32 *M)
                X[j] = 0;
 }
 
-static void copy64(uint32 *M, unsigned char *in)
+static void copy64(uint32 *M, const unsigned char *in)
 {
        int i;
 
@@ -119,7 +119,7 @@ static void copy4(unsigned char *out,uint32 x)
 }
 
 /* produce a md4 message digest from data of length n bytes */
-void mdfour(unsigned char *out, unsigned char *in, int n)
+void mdfour(unsigned char *out, const unsigned char *in, int n)
 {
        unsigned char buf[128];
        uint32 M[16];
index c404ccb83f3edf3ce321ba0db004c02d5afaefc3..b360dbd1996064e4edae87afb916f4798cfc1c7d 100644 (file)
@@ -203,8 +203,6 @@ void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
                const char *user, const char *server, const char *domain)
 {
        uchar kr[16];
-       struct MD5Context ctx5;
-       HMACMD5Context ctx;
 
        DEBUG(10,("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n",
                user, server, domain));
@@ -233,14 +231,7 @@ void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
        memcpy(&pwd->smb_nt_owf[16], pwd->nt_cli_chal, pwd->nt_cli_chal_len);
        pwd->nt_owf_len = pwd->nt_cli_chal_len + 16;
 
-       hmac_md5_init_limK_to_64(kr, 16, &ctx);
-       hmac_md5_update(pwd->smb_nt_owf, 16, &ctx);
-       hmac_md5_final(pwd->sess_key, &ctx);
-#if 0
-        MD5Init(&ctx5);
-        MD5Update(&ctx5, pwd->smb_nt_owf, 16);  
-        MD5Final(pwd->sess_key, &ctx5);          
-#endif
+       SMBsesskeygen_ntv2(kr, pwd->smb_nt_owf, pwd->sess_key);
 
 #if DEBUG_PASSWORD
 #endif
@@ -288,15 +279,13 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
        }
        pwd_deobfuscate(pwd);
 
-       /* generate session key */
-       mdfour(pwd->sess_key, pwd->smb_nt_pwd, 16);
-
        /* generate 24-byte hashes */
-
        SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf);
        SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf);
        pwd->nt_owf_len = 24;
 
+       SMBsesskeygen_ntv1(pwd->smb_nt_pwd, pwd->smb_nt_owf, pwd->sess_key);
+
 #ifdef DEBUG_PASSWORD
        DEBUG(100,("client cryptkey: "));
        dump_data(100, cryptkey, 8);
index 6bc0e71f6f4cd5ff17a7de337ceb1257310bb704..3227caaa9542984ae16adb15ebeae0284949a38d 100644 (file)
@@ -283,6 +283,34 @@ void SMBOWFencrypt_ntv2(const uchar kr[16],
 #endif
 }
 
+void SMBsesskeygen_ntv2(const uchar kr[16], 
+                               const uchar *nt_resp, 
+                               char sess_key[16])
+{
+       HMACMD5Context ctx;
+
+       hmac_md5_init_limK_to_64(kr, 16, &ctx);
+       hmac_md5_update(nt_resp, 16, &ctx);
+       hmac_md5_final(sess_key, &ctx);
+
+#ifdef DEBUG_PASSWORD
+       DEBUG(100,("SMBsesskeygen_ntv2:\n"));
+       dump_data(100, sess_key, 16);
+#endif
+}
+
+void SMBsesskeygen_ntv1(const uchar kr[16], 
+                               const uchar *nt_resp, 
+                               char sess_key[16])
+{
+       mdfour(sess_key, kr, 16);
+
+#ifdef DEBUG_PASSWORD
+       DEBUG(100,("SMBsesskeygen_ntv2:\n"));
+       dump_data(100, sess_key, 16);
+#endif
+}
+
 void SMBgenclientchals(char *lm_cli_chal,
                                char *nt_cli_chal, int *nt_cli_chal_len,
                                const char *srv, const char *dom)
index 3d7a35fac8ae19bab97b6a7e0fa693da8d93015a..010272b80731b32e33c07d63a64578db0e851752 100644 (file)
@@ -294,7 +294,8 @@ static BOOL update_smbpassword_file(char *user, char *password)
 core of smb password checking routine.
 ****************************************************************************/
 static BOOL smb_pwd_check_ntlmv1(char *password, unsigned char *part_passwd,
-                               unsigned char *c8)
+                               unsigned char *c8,
+                               uchar sess_key[16])
 {
   /* Finish the encryption of part_passwd. */
   unsigned char p24[24];
@@ -306,6 +307,11 @@ static BOOL smb_pwd_check_ntlmv1(char *password, unsigned char *part_passwd,
     return True;
 
   SMBOWFencrypt(part_passwd, c8, p24);
+       if (sess_key != NULL)
+       {
+               SMBsesskeygen_ntv1(part_passwd, NULL, sess_key);
+       }
+
 #if DEBUG_PASSWORD
        DEBUG(100,("Part password (P16) was |"));
        dump_data(100, part_passwd, 16);
@@ -325,10 +331,12 @@ core of smb password checking routine.
 static BOOL smb_pwd_check_ntlmv2(char *password, size_t pwd_len,
                                unsigned char *part_passwd,
                                unsigned char const *c8,
-                               const char *user, const char *domain)
+                               const char *user, const char *domain,
+                               char *sess_key)
 {
        /* Finish the encryption of part_passwd. */
        unsigned char kr[16];
+       unsigned char resp[16];
 
        if (part_passwd == NULL)
        {
@@ -341,7 +349,11 @@ static BOOL smb_pwd_check_ntlmv2(char *password, size_t pwd_len,
        }
 
        ntv2_owf_gen(part_passwd, user, domain, kr);
-       SMBOWFencrypt_ntv2(kr, c8, 8, password+16, pwd_len-16, kr);
+       SMBOWFencrypt_ntv2(kr, c8, 8, password+16, pwd_len-16, resp);
+       if (sess_key != NULL)
+       {
+               SMBsesskeygen_ntv2(kr, resp, sess_key);
+       }
 
 #if DEBUG_PASSWORD
        DEBUG(100,("Part password (P16) was |"));
@@ -351,10 +363,10 @@ static BOOL smb_pwd_check_ntlmv2(char *password, size_t pwd_len,
        DEBUG(100,("Given challenge was |"));
        dump_data(100, c8, 8);
        DEBUG(100,("Value from encryption was |"));
-       dump_data(100, kr, 16);
+       dump_data(100, resp, 16);
 #endif
 
-       return (memcmp(kr, password, 16) == 0);
+       return (memcmp(resp, password, 16) == 0);
 }
 
 /****************************************************************************
@@ -364,7 +376,8 @@ static BOOL smb_pwd_check_ntlmv2(char *password, size_t pwd_len,
 BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8],
                                const char *user, const char *domain,
                                uchar *lm_pass, size_t lm_pwd_len,
-                               uchar *nt_pass, size_t nt_pwd_len)
+                               uchar *nt_pass, size_t nt_pwd_len,
+                               uchar sess_key[16])
 {
        uchar challenge[8];
 
@@ -408,7 +421,8 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8],
                        DEBUG(4,("smb_password_ok: Check NTLMv2 password\n"));
                        if (smb_pwd_check_ntlmv2(nt_pass, nt_pwd_len,
                                       (uchar *)smb_pass->smb_nt_passwd, 
-                                       challenge, user, domain))
+                                       challenge, user, domain,
+                                       sess_key))
                        {
                                return True;
                        }
@@ -418,7 +432,8 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8],
                        DEBUG(4,("smb_password_ok: Check NT MD4 password\n"));
                        if (smb_pwd_check_ntlmv1((char *)nt_pass, 
                                       (uchar *)smb_pass->smb_nt_passwd, 
-                                      challenge))
+                                      challenge,
+                                      sess_key))
                        {
                                DEBUG(4,("NT MD4 password check succeeded\n"));
                                return True;
@@ -449,7 +464,7 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8],
        if ((smb_pass->smb_passwd != NULL) && 
           smb_pwd_check_ntlmv1((char *)lm_pass, 
                              (uchar *)smb_pass->smb_passwd,
-                               challenge))
+                               challenge, NULL))
        {
                DEBUG(4,("LM MD4 password check succeeded\n"));
                return(True);
@@ -527,11 +542,11 @@ BOOL pass_check_smb(struct smb_passwd *smb_pass, char *domain, uchar *chal,
 
        if (smb_password_ok(smb_pass, chal, user, domain,
                                            lm_pwd, lm_pwd_len,
-                                           nt_pwd, nt_pwd_len))
+                                           nt_pwd, nt_pwd_len,
+                                           user_sess_key))
        {
                if (user_sess_key != NULL)
                {
-                       mdfour(user_sess_key, smb_pass->smb_nt_passwd, 16);
 #ifdef DEBUG_PASSWORD
                DEBUG(100,("user session key: "));
                dump_data(100, user_sess_key, 16);
index da72c9f3b58a907fd37d35482e945c51cc117d39..d5d0884436f101c244a8faf939d423bd77e8052e 100644 (file)
@@ -444,7 +444,7 @@ static int session_trust_account(connection_struct *conn, char *inbuf, char *out
 
     if (!smb_password_ok(smb_trust_acct, NULL, NULL, NULL,
        (unsigned char *)smb_passwd, smb_passlen,
-       (unsigned char *)smb_nt_passwd, smb_nt_passlen))
+       (unsigned char *)smb_nt_passwd, smb_nt_passlen, NULL))
     {
       DEBUG(0,("session_trust_account: Trust Account %s - password failed\n", user));
       SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);