1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-04 08:22:08 +03:00

improving authentication code (tidyup).

This commit is contained in:
Luke Leighton
-
parent de9a38b0bc
commit ab1a6aa42d
19 changed files with 725 additions and 271 deletions

View File

@ -32,15 +32,9 @@ extern int DEBUGLEVEL;
encrypted password into p24 */
void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
{
uchar p14[15], p21[21];
memset(p21,'\0',21);
memset(p14,'\0',14);
StrnCpy((char *)p14,(char *)passwd,14);
strupper((char *)p14);
E_P16(p14, p21);
uchar p21[21];
lm_owf_gen(passwd, p21);
SMBOWFencrypt(p21, c8, p24);
#ifdef DEBUG_PASSWORD
@ -51,6 +45,23 @@ void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
#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,("SMBNTencrypt: nt#, challenge, response\n"));
dump_data(100, p21, 16);
dump_data(100, c8, 8);
dump_data(100, p24, 24);
#endif
}
/* Routines for Windows NT MD4 Hash functions. */
static int _my_wcslen(int16 *str)
{
@ -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);