summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>1999-11-21 19:59:56 +0000
committerLuke Leighton <lkcl@samba.org>1999-11-21 19:59:56 +0000
commit32b9508d066f002e778873edc19266a6d897f922 (patch)
treec15477a812fad192ff43b2296ed3da3e46eb2a75
parentdab1a1227873f1a88dc7a4b8f63edcccd60ada85 (diff)
downloadsamba-32b9508d066f002e778873edc19266a6d897f922.tar.gz
samba-32b9508d066f002e778873edc19266a6d897f922.tar.bz2
samba-32b9508d066f002e778873edc19266a6d897f922.zip
implement server-side generation of NTLMv2 session key. YESSS :-)
(This used to be commit 1092b4f6fbdf3770c0dab756b982a562def1738e)
-rw-r--r--source3/include/proto.h11
-rw-r--r--source3/lib/md4.c4
-rw-r--r--source3/libsmb/pwd_cache.c17
-rw-r--r--source3/libsmb/smbencrypt.c28
-rw-r--r--source3/smbd/password.c37
-rw-r--r--source3/smbd/reply.c2
6 files changed, 69 insertions, 30 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index ac5022935a..a8be8bad97 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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,
diff --git a/source3/lib/md4.c b/source3/lib/md4.c
index 30f2b6b8c6..56c9e02ffb 100644
--- a/source3/lib/md4.c
+++ b/source3/lib/md4.c
@@ -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];
diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c
index c404ccb83f..b360dbd199 100644
--- a/source3/libsmb/pwd_cache.c
+++ b/source3/libsmb/pwd_cache.c
@@ -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);
diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c
index 6bc0e71f6f..3227caaa95 100644
--- a/source3/libsmb/smbencrypt.c
+++ b/source3/libsmb/smbencrypt.c
@@ -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)
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index 3d7a35fac8..010272b807 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -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);
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index da72c9f3b5..d5d0884436 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -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);