diff options
Diffstat (limited to 'source3/libsmb')
-rw-r--r-- | source3/libsmb/clientgen.c | 259 | ||||
-rw-r--r-- | source3/libsmb/pwd_cache.c | 82 | ||||
-rw-r--r-- | source3/libsmb/smbencrypt.c | 271 |
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); |