From 32b9508d066f002e778873edc19266a6d897f922 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 21 Nov 1999 19:59:56 +0000 Subject: implement server-side generation of NTLMv2 session key. YESSS :-) (This used to be commit 1092b4f6fbdf3770c0dab756b982a562def1738e) --- source3/include/proto.h | 11 +++++++++-- source3/lib/md4.c | 4 ++-- source3/libsmb/pwd_cache.c | 17 +++-------------- source3/libsmb/smbencrypt.c | 28 ++++++++++++++++++++++++++++ source3/smbd/password.c | 37 ++++++++++++++++++++++++++----------- source3/smbd/reply.c | 2 +- 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); -- cgit