summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
authorLuke Leighton <lkcl@samba.org>1999-06-29 18:47:06 +0000
committerLuke Leighton <lkcl@samba.org>1999-06-29 18:47:06 +0000
commit73891ca8e4f6cca6aa8bb0ae043f660a64baa056 (patch)
tree9ed22c56d9f3eeac6608f25971e7b29f8006ae79 /source3/libsmb
parent1dc6c6c7ca54578d9e6040a9d4d5e509f1ad3af3 (diff)
downloadsamba-73891ca8e4f6cca6aa8bb0ae043f660a64baa056.tar.gz
samba-73891ca8e4f6cca6aa8bb0ae043f660a64baa056.tar.bz2
samba-73891ca8e4f6cca6aa8bb0ae043f660a64baa056.zip
improving authentication code (tidyup).
(This used to be commit ab1a6aa42db5217f025941fb5107436556bc23b7)
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/clientgen.c259
-rw-r--r--source3/libsmb/pwd_cache.c82
-rw-r--r--source3/libsmb/smbencrypt.c271
3 files changed, 483 insertions, 129 deletions
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 4f73b6e51b..8d3508d98f 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -2,7 +2,8 @@
Unix SMB/Netbios implementation.
Version 1.9.
SMB client generic functions
- Copyright (C) Andrew Tridgell 1994-1998
+ Copyright (C) Andrew Tridgell 1994-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -690,70 +691,25 @@ prots[] =
/****************************************************************************
send a session setup
****************************************************************************/
-BOOL cli_session_setup(struct cli_state *cli,
- char *user,
- char *pass, int passlen,
- char *ntpass, int ntpasslen,
- char *workgroup)
+BOOL cli_session_setup_x(struct cli_state *cli,
+ char *user,
+ char *pass, int passlen,
+ char *ntpass, int ntpasslen,
+ char *user_domain)
{
char *p;
- fstring pword, ntpword;
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("cli_session_setup. pass, ntpass\n"));
+ dump_data(100, pass, passlen);
+ dump_data(100, ntpass, ntpasslen);
+#endif
if (cli->protocol < PROTOCOL_LANMAN1)
{
return True;
}
- if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1)
- {
- return False;
- }
-
- if (!IS_BITS_SET_ALL(cli->sec_mode, 1))
- {
- /* if in share level security then don't send a password now */
- fstrcpy(pword, "");
- passlen=1;
- fstrcpy(ntpword, "");
- ntpasslen=1;
- }
- else if ((passlen == 0 || passlen == 1) && (pass[0] == '\0'))
- {
- /* Null session connect. */
- pword [0] = '\0';
- ntpword[0] = '\0';
- }
- else if (passlen == 24 && ntpasslen == 24)
- {
- if (IS_BITS_SET_ALL(cli->sec_mode, 2))
- {
- /* encrypted password, implicit from 24-byte lengths */
- memcpy(pword , pass , 24);
- memcpy(ntpword, ntpass, 24);
- }
- else
- {
- DEBUG(0,("cli_session_setup: encrypted passwords not supported by server\n"));
- return False;
- }
- }
- else if (ntpasslen == 0 || !IS_BITS_SET_ALL(cli->sec_mode, 2))
- {
- /* plain-text password: server doesn't support encrypted. */
- fstrcpy(pword, pass);
- fstrcpy(ntpword, "");
- ntpasslen = 0;
- }
- else /* passlen != 0 && ntpasslen != 0 && server supports encryption */
- {
- /* plain-text password requesting to be encrypted */
- uchar *key = (uchar *)cli->cryptkey;
- SMBencrypt ((uchar *)pass , key,(uchar *)pword );
- SMBNTencrypt((uchar *)ntpass, key,(uchar *)ntpword);
- passlen = 24;
- ntpasslen = 24;
- }
-
/* send a session setup command */
bzero(cli->outbuf,smb_size);
@@ -770,7 +726,7 @@ BOOL cli_session_setup(struct cli_state *cli,
SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
SSVAL(cli->outbuf,smb_vwv7,passlen);
p = smb_buf(cli->outbuf);
- memcpy(p,pword,passlen);
+ memcpy(p,pass,passlen);
p += passlen;
pstrcpy(p,user);
strupper(p);
@@ -790,17 +746,17 @@ BOOL cli_session_setup(struct cli_state *cli,
SSVAL(cli->outbuf,smb_vwv8,ntpasslen);
SSVAL(cli->outbuf,smb_vwv11,0);
p = smb_buf(cli->outbuf);
- memcpy(p,pword,passlen);
+ memcpy(p,pass,passlen);
p += SVAL(cli->outbuf,smb_vwv7);
- memcpy(p,ntpword,ntpasslen);
+ memcpy(p,ntpass,ntpasslen);
p += SVAL(cli->outbuf,smb_vwv8);
pstrcpy(p,user);
strupper(p);
p = skip_string(p,1);
- pstrcpy(p,workgroup);
- strupper(p);
+ pstrcpy(p,user_domain);
p = skip_string(p,1);
pstrcpy(p,"Unix");p = skip_string(p,1);
+ CVAL(p, 0) = 0; p++;
pstrcpy(p,"Samba");p = skip_string(p,1);
set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False);
}
@@ -833,11 +789,127 @@ BOOL cli_session_setup(struct cli_state *cli,
fstrcpy(cli->server_domain, server_domain);
}
- fstrcpy(cli->user_name, user);
-
return True;
}
+static BOOL cli_calc_session_pwds(struct cli_state *cli,
+ char *pword, char *ntpword,
+ char *pass, int *passlen,
+ char *ntpass, int *ntpasslen,
+ BOOL ntlmv2)
+{
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("cli_calc_session_pwds. pass, ntpass\n"));
+ dump_data(100, pass, *passlen);
+ dump_data(100, ntpass, *ntpasslen);
+#endif
+ if (!IS_BITS_SET_ALL(cli->sec_mode, 1))
+ {
+ /* if in share level security then don't send a password now */
+ fstrcpy(pword, "");
+ *passlen=1;
+ fstrcpy(ntpword, "");
+ *ntpasslen=1;
+ }
+ else if ((*passlen == 0 || *passlen == 1) && (pass[0] == '\0'))
+ {
+ /* Null session connect. */
+ pword [0] = '\0';
+ ntpword[0] = '\0';
+ }
+ else if (*passlen == 24 && *ntpasslen >= 24)
+ {
+ if (IS_BITS_SET_ALL(cli->sec_mode, 2))
+ {
+ /* encrypted password, implicit from 24-byte lengths */
+ memcpy(pword , pass , *passlen);
+ memcpy(ntpword, ntpass, *ntpasslen);
+ }
+ else
+ {
+ DEBUG(0,("cli_session_setup: encrypted passwords not supported by server\n"));
+ return False;
+ }
+ }
+ else if (*ntpasslen == 0 || !IS_BITS_SET_ALL(cli->sec_mode, 2))
+ {
+ /* plain-text password: server doesn't support encrypted. */
+ fstrcpy(pword, pass);
+ fstrcpy(ntpword, "");
+ *ntpasslen = 0;
+ }
+ else /* passlen != 0 && ntpasslen != 0 && server supports encryption */
+ {
+ if (ntlmv2)
+ {
+ /* plain-text password requesting to be encrypted */
+ uchar *srv_key = (uchar *)cli->cryptkey;
+ uchar nt_owf[16];
+ uchar kr[16];
+
+ SMBgenclientchals(cli->lm_cli_chal,
+ cli->nt_cli_chal,
+ &cli->nt_cli_chal_len,
+ cli->calling.name,
+ cli->domain);
+
+ nt_owf_gen(pword, nt_owf);
+ ntv2_owf_gen(nt_owf, cli->user_name, cli->domain, kr);
+
+ /* lm # */
+ memcpy(pword, cli->lm_cli_chal, 8);
+ SMBOWFencrypt_ntv2(kr,
+ srv_key, 8,
+ cli->lm_cli_chal, 8,
+ &pword[8]);
+ *passlen = 24;
+
+ /* nt # */
+ memcpy(ntpword, cli->lm_cli_chal, cli->nt_cli_chal_len);
+ SMBOWFencrypt_ntv2(kr,
+ srv_key, 8,
+ cli->nt_cli_chal, cli->nt_cli_chal_len,
+ &ntpword[cli->nt_cli_chal_len]);
+ *ntpasslen = cli->nt_cli_chal_len + 16;
+ }
+ else
+ {
+ /* plain-text password requesting to be encrypted */
+ uchar *key = (uchar *)cli->cryptkey;
+ SMBencrypt ((uchar *)pass , key,(uchar *)pword );
+ SMBNTencrypt((uchar *)ntpass, key,(uchar *)ntpword);
+ *passlen = 24;
+ *ntpasslen = 24;
+ }
+ }
+ return True;
+}
+
+/****************************************************************************
+send a session setup
+****************************************************************************/
+BOOL cli_session_setup(struct cli_state *cli,
+ char *user,
+ char *pass, int passlen,
+ char *ntpass, int ntpasslen,
+ char *user_domain)
+{
+ fstring pword, ntpword;
+
+ if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1)
+ {
+ return False;
+ }
+
+ fstrcpy(cli->user_name, user);
+
+ return cli_calc_session_pwds(cli, pword, ntpword,
+ pass, &passlen,
+ ntpass, &ntpasslen, cli->use_ntlmv2) &&
+ cli_session_setup_x(cli, user, pass, passlen, ntpass, ntpasslen,
+ user_domain);
+}
+
/****************************************************************************
Send a uloggoff.
*****************************************************************************/
@@ -2614,9 +2686,12 @@ BOOL cli_reestablish_connection(struct cli_state *cli)
if (cli_establish_connection(cli,
dest_host, &cli->dest_ip,
&calling, &called,
- share, dev, False, do_tcon)) {
- if (cli->fd != oldfd) {
- if (dup2(cli->fd, oldfd) == oldfd) {
+ share, dev, False, do_tcon))
+ {
+ if (cli->fd != oldfd)
+ {
+ if (dup2(cli->fd, oldfd) == oldfd)
+ {
close(cli->fd);
}
}
@@ -2640,9 +2715,10 @@ BOOL cli_establish_connection(struct cli_state *cli,
nmb_safe_namestr(calling, callingstr, sizeof(callingstr));
nmb_safe_namestr(called , calledstr , sizeof(calledstr ));
- DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n",
+ DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s] with NTLM%s\n",
callingstr, calledstr, inet_ntoa(*dest_ip),
- cli->user_name, cli->domain));
+ cli->user_name, cli->domain,
+ cli->use_ntlmv2 ? "v2" : "v1"));
/* establish connection */
@@ -2665,7 +2741,9 @@ BOOL cli_establish_connection(struct cli_state *cli,
{
DEBUG(1,("failed session request\n"));
if (do_shutdown)
- cli_shutdown(cli);
+ {
+ cli_shutdown(cli);
+ }
return False;
}
@@ -2673,7 +2751,9 @@ BOOL cli_establish_connection(struct cli_state *cli,
{
DEBUG(1,("failed negprot\n"));
if (do_shutdown)
- cli_shutdown(cli);
+ {
+ cli_shutdown(cli);
+ }
return False;
}
@@ -2725,20 +2805,45 @@ BOOL cli_establish_connection(struct cli_state *cli,
else
{
/* attempt encrypted session */
- unsigned char nt_sess_pwd[24];
unsigned char lm_sess_pwd[24];
+ unsigned char nt_sess_pwd[128];
+ size_t nt_sess_pwd_len;
+ extern pstring global_myname;
+
+ if (cli->use_ntlmv2 != False)
+ {
+ DEBUG(10,("cli_establish_connection: NTLMv2\n"));
+ pwd_make_lm_nt_owf2(&(cli->pwd), cli->cryptkey,
+ cli->user_name, global_myname, cli->domain);
+ }
+ else
+ {
+ DEBUG(10,("cli_establish_connection: NTLMv1\n"));
+ pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey);
+ }
- /* creates (storing a copy of) and then obtains a 24 byte password OWF */
- pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey);
- pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd);
+ pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd,
+ &nt_sess_pwd_len);
/* attempt encrypted session */
- if (!cli_session_setup(cli, cli->user_name,
+ if (!cli_session_setup_x(cli, cli->user_name,
(char*)lm_sess_pwd, sizeof(lm_sess_pwd),
- (char*)nt_sess_pwd, sizeof(nt_sess_pwd),
+ (char*)nt_sess_pwd, nt_sess_pwd_len,
cli->domain))
{
DEBUG(1,("failed session setup\n"));
+
+ if (cli->use_ntlmv2 == Auto)
+ {
+ DEBUG(10,("NTLMv2 failed. Using NTLMv1\n"));
+ cli->use_ntlmv2 = False;
+ return cli_establish_connection(cli,
+ dest_host, dest_ip,
+ calling, called,
+ service, service_type,
+ do_shutdown, do_tcon);
+ }
+
if (do_shutdown)
{
cli_shutdown(cli);
diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c
index bbd5f63d4b..655df5be8a 100644
--- a/source3/libsmb/pwd_cache.c
+++ b/source3/libsmb/pwd_cache.c
@@ -197,27 +197,83 @@ void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr)
/****************************************************************************
makes lm and nt OWF crypts
****************************************************************************/
-void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
+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];
+
+ DEBUG(10,("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n",
+ user, server, domain));
+
pwd_deobfuscate(pwd);
+ SMBgenclientchals(pwd->lm_cli_chal,
+ pwd->nt_cli_chal,
+ &pwd->nt_cli_chal_len,
+ server, domain);
+
+ ntv2_owf_gen(pwd->smb_nt_pwd, user, domain, kr);
+
+ /* lm # */
+ SMBOWFencrypt_ntv2(kr,
+ srv_key, 8,
+ pwd->lm_cli_chal, 8,
+ pwd->smb_lm_owf);
+ memcpy(&pwd->smb_lm_owf[16], pwd->lm_cli_chal, 8);
+
+ /* nt # */
+ SMBOWFencrypt_ntv2(kr,
+ srv_key, 8,
+ pwd->nt_cli_chal, pwd->nt_cli_chal_len,
+ pwd->smb_nt_owf);
+ 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;
+
#ifdef DEBUG_PASSWORD
- DEBUG(100,("client cryptkey: "));
- dump_data(100, cryptkey, 8);
-#endif
+ DEBUG(100,("server cryptkey: "));
+ dump_data(100, srv_key, 8);
- SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf);
+ DEBUG(100,("client lmv2 cryptkey: "));
+ dump_data(100, pwd->lm_cli_chal, 8);
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("nt_owf_passwd: "));
- dump_data(100, pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf));
+ DEBUG(100,("client ntv2 cryptkey: "));
+ dump_data(100, pwd->nt_cli_chal, pwd->nt_cli_chal_len);
+
+ DEBUG(100,("ntv2_owf_passwd: "));
+ dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len);
DEBUG(100,("nt_sess_pwd: "));
dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
+
+ DEBUG(100,("lmv2_owf_passwd: "));
+ dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
+ DEBUG(100,("lm_sess_pwd: "));
+ dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
#endif
+ pwd->crypted = True;
+
+ pwd_obfuscate(pwd);
+}
+
+/****************************************************************************
+ makes lm and nt OWF crypts
+ ****************************************************************************/
+void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
+{
+ pwd_deobfuscate(pwd);
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;
#ifdef DEBUG_PASSWORD
+ DEBUG(100,("client cryptkey: "));
+ dump_data(100, cryptkey, 8);
+
+ DEBUG(100,("nt_owf_passwd: "));
+ dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len);
+ DEBUG(100,("nt_sess_pwd: "));
+ dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
+
DEBUG(100,("lm_owf_passwd: "));
dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
DEBUG(100,("lm_sess_pwd: "));
@@ -232,7 +288,8 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
/****************************************************************************
gets lm and nt crypts
****************************************************************************/
-void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24])
+void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
+ uchar *nt_owf, size_t *nt_owf_len)
{
pwd_deobfuscate(pwd);
if (lm_owf != NULL)
@@ -241,7 +298,12 @@ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24])
}
if (nt_owf != NULL)
{
- memcpy(nt_owf, pwd->smb_nt_owf, 24);
+ memcpy(nt_owf, pwd->smb_nt_owf, pwd->nt_owf_len);
+ }
+ if (nt_owf_len != NULL)
+ {
+ *nt_owf_len = pwd->nt_owf_len;
}
pwd_obfuscate(pwd);
}
+
diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c
index f0bfbd9b84..852e5327cf 100644
--- a/source3/libsmb/smbencrypt.c
+++ b/source3/libsmb/smbencrypt.c
@@ -32,19 +32,30 @@ extern int DEBUGLEVEL;
encrypted password into p24 */
void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
{
- uchar p14[15], p21[21];
+ uchar p21[21];
- memset(p21,'\0',21);
- memset(p14,'\0',14);
- StrnCpy((char *)p14,(char *)passwd,14);
+ lm_owf_gen(passwd, p21);
+ SMBOWFencrypt(p21, c8, p24);
- strupper((char *)p14);
- E_P16(p14, p21);
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("SMBencrypt: lm#, challenge, response\n"));
+ dump_data(100, p21, 16);
+ dump_data(100, c8, 8);
+ dump_data(100, p24, 24);
+#endif
+}
+void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
+{
+ uchar p21[21];
+
+ memset(p21,'\0',21);
+
+ nt_owf_gen(passwd, p21);
SMBOWFencrypt(p21, c8, p24);
#ifdef DEBUG_PASSWORD
- DEBUG(100,("SMBencrypt: lm#, challenge, response\n"));
+ DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n"));
dump_data(100, p21, 16);
dump_data(100, c8, 8);
dump_data(100, p24, 24);
@@ -67,7 +78,23 @@ static int _my_wcslen(int16 *str)
* format.
*/
-static int _my_mbstowcs(int16 *dst, uchar *src, int len)
+static int _my_mbstowcsupper(int16 *dst, const uchar *src, int len)
+{
+ int i;
+ int16 val;
+
+ for(i = 0; i < len; i++) {
+ val = toupper(*src);
+ SSVAL(dst,0,val);
+ dst++;
+ src++;
+ if(val == 0)
+ break;
+ }
+ return i;
+}
+
+static int _my_mbstowcs(int16 *dst, const uchar *src, int len)
{
int i;
int16 val;
@@ -105,27 +132,17 @@ void E_md4hash(uchar *passwd, uchar *p16)
mdfour(p16, (unsigned char *)wpwd, len);
}
-/* 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])
+/* Does the LM owf of a user's password */
+void lm_owf_gen(const char *pwd, uchar p16[16])
{
- char passwd[130];
+ char passwd[15];
- memset(passwd,'\0',130);
+ memset(passwd,'\0',15);
if (pwd != NULL)
{
safe_strcpy( passwd, pwd, sizeof(passwd)-1);
}
- /* Calculate the MD4 hash (NT compatible) of the password */
- memset(nt_p16, '\0', 16);
- E_md4hash((uchar *)passwd, nt_p16);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n"));
- dump_data(120, passwd, strlen(passwd));
- dump_data(100, nt_p16, 16);
-#endif
-
/* Mangle the passwords into Lanman format */
passwd[14] = '\0';
strupper(passwd);
@@ -144,6 +161,37 @@ void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16])
bzero(passwd, sizeof(passwd));
}
+/* Does both the NT and LM owfs of a user's password */
+void nt_owf_gen(const char *pwd, uchar nt_p16[16])
+{
+ char passwd[130];
+
+ memset(passwd,'\0',130);
+ if (pwd != NULL)
+ {
+ safe_strcpy( passwd, pwd, sizeof(passwd)-1);
+ }
+
+ /* Calculate the MD4 hash (NT compatible) of the password */
+ memset(nt_p16, '\0', 16);
+ E_md4hash((uchar *)passwd, nt_p16);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n"));
+ dump_data(120, passwd, strlen(passwd));
+ dump_data(100, nt_p16, 16);
+#endif
+ /* clear out local copy of user's password (just being paranoid). */
+ bzero(passwd, sizeof(passwd));
+}
+
+/* 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 lm_p16[16])
+{
+ nt_owf_gen(pwd, nt_p16);
+ lm_owf_gen(pwd, lm_p16);
+}
+
/* Does the des encryption from the NT or LM MD4 hash. */
void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24])
{
@@ -155,6 +203,165 @@ void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24])
E_P24(p21, c8, p24);
}
+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])
+{
+ HMACMD5Context ctx;
+
+ hmac_md5_init_limK_to_64(kr, 16, &ctx);
+ hmac_md5_update(srv_chal, srv_chal_len, &ctx);
+ hmac_md5_update(cli_chal, cli_chal_len, &ctx);
+ hmac_md5_final(resp_buf, &ctx);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n"));
+ dump_data(100, srv_chal, srv_chal_len);
+ dump_data(100, cli_chal, cli_chal_len);
+ dump_data(100, resp_buf, 16);
+#endif
+}
+
+#if 0
+static char np_cli_chal[58] =
+{
+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf0, 0x20, 0xd0, 0xb6, 0xc2, 0x92, 0xBE, 0x01,
+ 0x05, 0x83, 0x32, 0xec, 0xfa, 0xe4, 0xf3, 0x6d,
+ 0x6f, 0x00, 0x6e, 0x00, 0x02, 0x00, 0x12, 0x00,
+ 0x52, 0x00, 0x4f, 0x00, 0x43, 0x00, 0x4b, 0x00,
+ 0x4e, 0x00, 0x52, 0x00, 0x4f, 0x00, 0x4c, 0x00,
+ 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00,
+ 0x00, 0x00
+};
+#endif
+
+void SMBgenclientchals(char *lm_cli_chal,
+ char *nt_cli_chal, int *nt_cli_chal_len,
+ const char *srv, const char *domain)
+{
+ NTTIME nt_time;
+ int srv_len = strlen(srv);
+ int dom_len = strlen(domain);
+
+ generate_random_buffer(lm_cli_chal, 8, False);
+ unix_to_nt_time(&nt_time, time(NULL));
+
+ CVAL(nt_cli_chal,0) = 0x1;
+ CVAL(nt_cli_chal,1) = 0x1;
+ SSVAL(nt_cli_chal, 2, 0x0);
+ SIVAL(nt_cli_chal, 4, 0x0);
+ SIVAL(nt_cli_chal, 8, nt_time.low);
+ SIVAL(nt_cli_chal, 12, nt_time.high);
+ memcpy(nt_cli_chal+16, lm_cli_chal, 8);
+ /* fill in offset 24, size of structure, later */
+
+ *nt_cli_chal_len = 28;
+
+ SSVAL(nt_cli_chal, *nt_cli_chal_len, 2);
+ *nt_cli_chal_len += 2;
+ SSVAL(nt_cli_chal, *nt_cli_chal_len, dom_len*2);
+ *nt_cli_chal_len += 2;
+ ascii_to_unibuf(nt_cli_chal+(*nt_cli_chal_len), domain, dom_len*2);
+ *nt_cli_chal_len += dom_len*2;
+ *nt_cli_chal_len += 4 - ((*nt_cli_chal_len) % 4);
+
+ SSVAL(nt_cli_chal, *nt_cli_chal_len, 2);
+ *nt_cli_chal_len += 2;
+ SSVAL(nt_cli_chal, 30, srv_len*2);
+ *nt_cli_chal_len += 2;
+ ascii_to_unibuf(nt_cli_chal+(*nt_cli_chal_len), srv, srv_len*2);
+ *nt_cli_chal_len += srv_len*2;
+
+ SSVAL(nt_cli_chal, 24, (*nt_cli_chal_len)+16);
+ SSVAL(nt_cli_chal, 26, (*nt_cli_chal_len)+15);
+
+ DEBUG(100,("SMBgenclientchals: srv %s, dom %s\n", srv, domain));
+ dump_data(100, nt_cli_chal, *nt_cli_chal_len);
+}
+
+void ntv2_owf_gen(const uchar owf[16],
+ const char *user_n,
+ const char *domain_n,
+ uchar kr_buf[16])
+{
+ pstring user_u;
+ pstring dom_u;
+ HMACMD5Context ctx;
+
+ int user_l = strlen(user_n );
+ int domain_l = strlen(domain_n);
+
+ _my_mbstowcsupper((int16*)user_u, user_n , user_l*2 );
+ _my_mbstowcs((int16*)dom_u , domain_n, domain_l*2);
+
+ hmac_md5_init_limK_to_64(owf, 16, &ctx);
+ hmac_md5_update(user_u, user_l*2, &ctx);
+ hmac_md5_update(dom_u, domain_l*2, &ctx);
+ hmac_md5_final(kr_buf, &ctx);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("ntv2_owf_gen: user, domain, owfkey, kr\n"));
+ dump_data(100, user_u, user_l*2);
+ dump_data(100, dom_u, domain_l*2);
+ dump_data(100, owf, 16);
+ dump_data(100, kr_buf, 16);
+#endif
+}
+
+#if 0
+static void main()
+{
+ char *kr;
+ int kr_len;
+ char *cli_chal;
+ int cli_chal_len;
+ char *resp;
+ int resp_len;
+ char *k_x;
+ int k_x_len;
+
+ char k_u[16];
+ int k_u_len = sizeof(k_u);
+
+ char sesk[16];
+ int sesk_len;
+
+ char buf[1024];
+
+ int flgs = NTLMSSP_NP | NTLMSSP_N2;
+
+ gen_client_chal(flgs, "BROOKFIELDS1", "TEST1", &cli_chal, &cli_chal_len);
+ gen_owf(flgs, "test", "ADMINISTRATOR", "BROOKFIELDS1", &kr, &kr_len);
+ gen_resp(flgs, kr, kr_len, srv_chal, 8, cli_chal, cli_chal_len,
+ &resp, &resp_len);
+
+ gen_sesskey(flgs, kr, kr_len, resp, resp_len, &k_x, &k_x_len);
+
+ printf("lm_resp:\n"); dump_data(lm_resp, 16); printf("\n");
+ printf("np_resp:\n"); dump_data(np_resp, 16); printf("\n");
+ printf("resp:\n"); dump_data(resp, 16); printf("\n");
+
+#if 0
+ printf("np_sesk:\n"); dump_data(np_sess_key, 16); printf("\n");
+ if (flgs & NTLMSSP_NP)
+ {
+ oem_hash(k_x, k_x_len, k_u, np_sess_key, k_u_len);
+ sesk_len = k_u_len;
+ }
+ else
+ {
+ memcpy(sesk, k_x, k_x_len);
+ sesk_len = k_x_len;
+ }
+
+ oem_hash(sesk, sesk_len, buf, cli_req, sizeof(cli_req));
+ printf("cli_req:\n"); dump_data(buf, sizeof(cli_req)); printf("\n");
+#endif
+}
+#endif
+
/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24])
{
@@ -173,26 +380,6 @@ void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24])
#endif
}
-
-/* Does the NT MD4 hash then des encryption. */
-
-void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
-{
- uchar p21[21];
-
- memset(p21,'\0',21);
-
- E_md4hash(passwd, p21);
- SMBOWFencrypt(p21, c8, p24);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n"));
- dump_data(100, p21, 16);
- dump_data(100, c8, 8);
- dump_data(100, p24, 24);
-#endif
-}
-
BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode)
{
int new_pw_len = strlen(passwd) * (unicode ? 2 : 1);