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:
@ -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);
|
||||
|
Reference in New Issue
Block a user