1/* 2 Unix SMB/CIFS implementation. 3 SMB parameters and setup 4 Copyright (C) Andrew Tridgell 1992-1998 5 Modified by Jeremy Allison 1995. 6 Copyright (C) Jeremy Allison 1995-2000. 7 Copyright (C) Luke Kennethc Casson Leighton 1996-2000. 8 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003 9 10 This program is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 3 of the License, or 13 (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program. If not, see <http://www.gnu.org/licenses/>. 22*/ 23 24#include "includes.h" 25#include "system/time.h" 26#include "../libcli/auth/msrpc_parse.h" 27#include "../lib/crypto/crypto.h" 28#include "../libcli/auth/libcli_auth.h" 29#include "../librpc/gen_ndr/ntlmssp.h" 30 31void SMBencrypt_hash(const uint8_t lm_hash[16], const uint8_t *c8, uint8_t p24[24]) 32{ 33 uint8_t p21[21]; 34 35 memset(p21,'\0',21); 36 memcpy(p21, lm_hash, 16); 37 38 SMBOWFencrypt(p21, c8, p24); 39 40#ifdef DEBUG_PASSWORD 41 DEBUG(100,("SMBencrypt_hash: lm#, challenge, response\n")); 42 dump_data(100, p21, 16); 43 dump_data(100, c8, 8); 44 dump_data(100, p24, 24); 45#endif 46} 47 48/* 49 This implements the X/Open SMB password encryption 50 It takes a password ('unix' string), a 8 byte "crypt key" 51 and puts 24 bytes of encrypted password into p24 52 53 Returns False if password must have been truncated to create LM hash 54*/ 55 56bool SMBencrypt(const char *passwd, const uint8_t *c8, uint8_t p24[24]) 57{ 58 bool ret; 59 uint8_t lm_hash[16]; 60 61 ret = E_deshash(passwd, lm_hash); 62 SMBencrypt_hash(lm_hash, c8, p24); 63 return ret; 64} 65 66/** 67 * Creates the MD4 Hash of the users password in NT UNICODE. 68 * @param passwd password in 'unix' charset. 69 * @param p16 return password hashed with md4, caller allocated 16 byte buffer 70 */ 71 72bool E_md4hash(const char *passwd, uint8_t p16[16]) 73{ 74 size_t len; 75 smb_ucs2_t *wpwd; 76 bool ret; 77 78 ret = push_ucs2_talloc(NULL, &wpwd, passwd, &len); 79 if (!ret || len < 2) { 80 /* We don't want to return fixed data, as most callers 81 * don't check */ 82 mdfour(p16, (const uint8_t *)passwd, strlen(passwd)); 83 return false; 84 } 85 86 len -= 2; 87 mdfour(p16, (const uint8_t *)wpwd, len); 88 89 talloc_free(wpwd); 90 return true; 91} 92 93/** 94 * Creates the MD5 Hash of a combination of 16 byte salt and 16 byte NT hash. 95 * @param 16 byte salt. 96 * @param 16 byte NT hash. 97 * @param 16 byte return hashed with md5, caller allocated 16 byte buffer 98 */ 99 100void E_md5hash(const uint8_t salt[16], const uint8_t nthash[16], uint8_t hash_out[16]) 101{ 102 struct MD5Context tctx; 103 MD5Init(&tctx); 104 MD5Update(&tctx, salt, 16); 105 MD5Update(&tctx, nthash, 16); 106 MD5Final(hash_out, &tctx); 107} 108 109/** 110 * Creates the DES forward-only Hash of the users password in DOS ASCII charset 111 * @param passwd password in 'unix' charset. 112 * @param p16 return password hashed with DES, caller allocated 16 byte buffer 113 * @return false if password was > 14 characters, and therefore may be incorrect, otherwise true 114 * @note p16 is filled in regardless 115 */ 116 117bool E_deshash(const char *passwd, uint8_t p16[16]) 118{ 119 bool ret = true; 120 char dospwd[256]; 121 ZERO_STRUCT(dospwd); 122 123 /* Password must be converted to DOS charset - null terminated, uppercase. */ 124 push_string(dospwd, passwd, sizeof(dospwd), STR_ASCII|STR_UPPER|STR_TERMINATE); 125 126 /* Only the first 14 chars are considered, password need not be null terminated. */ 127 E_P16((const uint8_t *)dospwd, p16); 128 129 if (strlen(dospwd) > 14) { 130 ret = false; 131 } 132 133 ZERO_STRUCT(dospwd); 134 135 return ret; 136} 137 138/** 139 * Creates the MD4 and DES (LM) Hash of the users password. 140 * MD4 is of the NT Unicode, DES is of the DOS UPPERCASE password. 141 * @param passwd password in 'unix' charset. 142 * @param nt_p16 return password hashed with md4, caller allocated 16 byte buffer 143 * @param p16 return password hashed with des, caller allocated 16 byte buffer 144 */ 145 146/* Does both the NT and LM owfs of a user's password */ 147void nt_lm_owf_gen(const char *pwd, uint8_t nt_p16[16], uint8_t p16[16]) 148{ 149 /* Calculate the MD4 hash (NT compatible) of the password */ 150 memset(nt_p16, '\0', 16); 151 E_md4hash(pwd, nt_p16); 152 153#ifdef DEBUG_PASSWORD 154 DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n")); 155 dump_data(120, (const uint8_t *)pwd, strlen(pwd)); 156 dump_data(100, nt_p16, 16); 157#endif 158 159 E_deshash(pwd, (uint8_t *)p16); 160 161#ifdef DEBUG_PASSWORD 162 DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); 163 dump_data(120, (const uint8_t *)pwd, strlen(pwd)); 164 dump_data(100, p16, 16); 165#endif 166} 167 168/* Does both the NTLMv2 owfs of a user's password */ 169bool ntv2_owf_gen(const uint8_t owf[16], 170 const char *user_in, const char *domain_in, 171 bool upper_case_domain, /* Transform the domain into UPPER case */ 172 uint8_t kr_buf[16]) 173{ 174 smb_ucs2_t *user; 175 smb_ucs2_t *domain; 176 size_t user_byte_len; 177 size_t domain_byte_len; 178 bool ret; 179 180 HMACMD5Context ctx; 181 TALLOC_CTX *mem_ctx = talloc_init("ntv2_owf_gen for %s\\%s", domain_in, user_in); 182 183 if (!mem_ctx) { 184 return false; 185 } 186 187 if (!user_in) { 188 user_in = ""; 189 } 190 191 if (!domain_in) { 192 domain_in = ""; 193 } 194 195 user_in = strupper_talloc(mem_ctx, user_in); 196 if (user_in == NULL) { 197 talloc_free(mem_ctx); 198 return false; 199 } 200 201 if (upper_case_domain) { 202 domain_in = strupper_talloc(mem_ctx, domain_in); 203 if (domain_in == NULL) { 204 talloc_free(mem_ctx); 205 return false; 206 } 207 } 208 209 ret = push_ucs2_talloc(mem_ctx, &user, user_in, &user_byte_len ); 210 if (!ret) { 211 DEBUG(0, ("push_uss2_talloc() for user failed)\n")); 212 talloc_free(mem_ctx); 213 return false; 214 } 215 216 ret = push_ucs2_talloc(mem_ctx, &domain, domain_in, &domain_byte_len); 217 if (!ret) { 218 DEBUG(0, ("push_ucs2_talloc() for domain failed\n")); 219 talloc_free(mem_ctx); 220 return false; 221 } 222 223 SMB_ASSERT(user_byte_len >= 2); 224 SMB_ASSERT(domain_byte_len >= 2); 225 226 /* We don't want null termination */ 227 user_byte_len = user_byte_len - 2; 228 domain_byte_len = domain_byte_len - 2; 229 230 hmac_md5_init_limK_to_64(owf, 16, &ctx); 231 hmac_md5_update((uint8_t *)user, user_byte_len, &ctx); 232 hmac_md5_update((uint8_t *)domain, domain_byte_len, &ctx); 233 hmac_md5_final(kr_buf, &ctx); 234 235#ifdef DEBUG_PASSWORD 236 DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n")); 237 dump_data(100, (uint8_t *)user, user_byte_len); 238 dump_data(100, (uint8_t *)domain, domain_byte_len); 239 dump_data(100, owf, 16); 240 dump_data(100, kr_buf, 16); 241#endif 242 243 talloc_free(mem_ctx); 244 return true; 245} 246 247/* Does the des encryption from the NT or LM MD4 hash. */ 248void SMBOWFencrypt(const uint8_t passwd[16], const uint8_t *c8, uint8_t p24[24]) 249{ 250 uint8_t p21[21]; 251 252 ZERO_STRUCT(p21); 253 254 memcpy(p21, passwd, 16); 255 E_P24(p21, c8, p24); 256} 257 258/* Does the des encryption. */ 259 260void SMBNTencrypt_hash(const uint8_t nt_hash[16], uint8_t *c8, uint8_t *p24) 261{ 262 uint8_t p21[21]; 263 264 memset(p21,'\0',21); 265 memcpy(p21, nt_hash, 16); 266 SMBOWFencrypt(p21, c8, p24); 267 268#ifdef DEBUG_PASSWORD 269 DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n")); 270 dump_data(100, p21, 16); 271 dump_data(100, c8, 8); 272 dump_data(100, p24, 24); 273#endif 274} 275 276/* Does the NT MD4 hash then des encryption. Plaintext version of the above. */ 277 278void SMBNTencrypt(const char *passwd, uint8_t *c8, uint8_t *p24) 279{ 280 uint8_t nt_hash[16]; 281 E_md4hash(passwd, nt_hash); 282 SMBNTencrypt_hash(nt_hash, c8, p24); 283} 284 285 286/* Does the md5 encryption from the Key Response for NTLMv2. */ 287void SMBOWFencrypt_ntv2(const uint8_t kr[16], 288 const DATA_BLOB *srv_chal, 289 const DATA_BLOB *smbcli_chal, 290 uint8_t resp_buf[16]) 291{ 292 HMACMD5Context ctx; 293 294 hmac_md5_init_limK_to_64(kr, 16, &ctx); 295 hmac_md5_update(srv_chal->data, srv_chal->length, &ctx); 296 hmac_md5_update(smbcli_chal->data, smbcli_chal->length, &ctx); 297 hmac_md5_final(resp_buf, &ctx); 298 299#ifdef DEBUG_PASSWORD 300 DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, smbcli_chal, resp_buf\n")); 301 dump_data(100, srv_chal->data, srv_chal->length); 302 dump_data(100, smbcli_chal->data, smbcli_chal->length); 303 dump_data(100, resp_buf, 16); 304#endif 305} 306 307void SMBsesskeygen_ntv2(const uint8_t kr[16], 308 const uint8_t * nt_resp, uint8_t sess_key[16]) 309{ 310 /* a very nice, 128 bit, variable session key */ 311 312 HMACMD5Context ctx; 313 314 hmac_md5_init_limK_to_64(kr, 16, &ctx); 315 hmac_md5_update(nt_resp, 16, &ctx); 316 hmac_md5_final((uint8_t *)sess_key, &ctx); 317 318#ifdef DEBUG_PASSWORD 319 DEBUG(100, ("SMBsesskeygen_ntv2:\n")); 320 dump_data(100, sess_key, 16); 321#endif 322} 323 324void SMBsesskeygen_ntv1(const uint8_t kr[16], uint8_t sess_key[16]) 325{ 326 /* yes, this session key does not change - yes, this 327 is a problem - but it is 128 bits */ 328 329 mdfour((uint8_t *)sess_key, kr, 16); 330 331#ifdef DEBUG_PASSWORD 332 DEBUG(100, ("SMBsesskeygen_ntv1:\n")); 333 dump_data(100, sess_key, 16); 334#endif 335} 336 337void SMBsesskeygen_lm_sess_key(const uint8_t lm_hash[16], 338 const uint8_t lm_resp[24], /* only uses 8 */ 339 uint8_t sess_key[16]) 340{ 341 /* Calculate the LM session key (effective length 40 bits, 342 but changes with each session) */ 343 uint8_t p24[24]; 344 uint8_t partial_lm_hash[14]; 345 346 memcpy(partial_lm_hash, lm_hash, 8); 347 memset(partial_lm_hash + 8, 0xbd, 6); 348 349 des_crypt56(p24, lm_resp, partial_lm_hash, 1); 350 des_crypt56(p24+8, lm_resp, partial_lm_hash + 7, 1); 351 352 memcpy(sess_key, p24, 16); 353 354#ifdef DEBUG_PASSWORD 355 DEBUG(100, ("SMBsesskeygen_lm_sess_key: \n")); 356 dump_data(100, sess_key, 16); 357#endif 358} 359 360DATA_BLOB NTLMv2_generate_names_blob(TALLOC_CTX *mem_ctx, 361 const char *hostname, 362 const char *domain) 363{ 364 DATA_BLOB names_blob = data_blob_talloc(mem_ctx, NULL, 0); 365 366 msrpc_gen(mem_ctx, &names_blob, 367 "aaa", 368 MsvAvNbDomainName, domain, 369 MsvAvNbComputerName, hostname, 370 MsvAvEOL, ""); 371 return names_blob; 372} 373 374static DATA_BLOB NTLMv2_generate_client_data(TALLOC_CTX *mem_ctx, const DATA_BLOB *names_blob) 375{ 376 uint8_t client_chal[8]; 377 DATA_BLOB response = data_blob(NULL, 0); 378 uint8_t long_date[8]; 379 NTTIME nttime; 380 381 unix_to_nt_time(&nttime, time(NULL)); 382 383 generate_random_buffer(client_chal, sizeof(client_chal)); 384 385 push_nttime(long_date, 0, nttime); 386 387 /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */ 388 389 msrpc_gen(mem_ctx, &response, "ddbbdb", 390 0x00000101, /* Header */ 391 0, /* 'Reserved' */ 392 long_date, 8, /* Timestamp */ 393 client_chal, 8, /* client challenge */ 394 0, /* Unknown */ 395 names_blob->data, names_blob->length); /* End of name list */ 396 397 return response; 398} 399 400static DATA_BLOB NTLMv2_generate_response(TALLOC_CTX *out_mem_ctx, 401 const uint8_t ntlm_v2_hash[16], 402 const DATA_BLOB *server_chal, 403 const DATA_BLOB *names_blob) 404{ 405 uint8_t ntlmv2_response[16]; 406 DATA_BLOB ntlmv2_client_data; 407 DATA_BLOB final_response; 408 409 TALLOC_CTX *mem_ctx = talloc_named(out_mem_ctx, 0, 410 "NTLMv2_generate_response internal context"); 411 412 if (!mem_ctx) { 413 return data_blob(NULL, 0); 414 } 415 416 /* NTLMv2 */ 417 /* generate some data to pass into the response function - including 418 the hostname and domain name of the server */ 419 ntlmv2_client_data = NTLMv2_generate_client_data(mem_ctx, names_blob); 420 421 /* Given that data, and the challenge from the server, generate a response */ 422 SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response); 423 424 final_response = data_blob_talloc(out_mem_ctx, NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length); 425 426 memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response)); 427 428 memcpy(final_response.data+sizeof(ntlmv2_response), 429 ntlmv2_client_data.data, ntlmv2_client_data.length); 430 431 talloc_free(mem_ctx); 432 433 return final_response; 434} 435 436static DATA_BLOB LMv2_generate_response(TALLOC_CTX *mem_ctx, 437 const uint8_t ntlm_v2_hash[16], 438 const DATA_BLOB *server_chal) 439{ 440 uint8_t lmv2_response[16]; 441 DATA_BLOB lmv2_client_data = data_blob_talloc(mem_ctx, NULL, 8); 442 DATA_BLOB final_response = data_blob_talloc(mem_ctx, NULL,24); 443 444 /* LMv2 */ 445 /* client-supplied random data */ 446 generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length); 447 448 /* Given that data, and the challenge from the server, generate a response */ 449 SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response); 450 memcpy(final_response.data, lmv2_response, sizeof(lmv2_response)); 451 452 /* after the first 16 bytes is the random data we generated above, 453 so the server can verify us with it */ 454 memcpy(final_response.data+sizeof(lmv2_response), 455 lmv2_client_data.data, lmv2_client_data.length); 456 457 data_blob_free(&lmv2_client_data); 458 459 return final_response; 460} 461 462bool SMBNTLMv2encrypt_hash(TALLOC_CTX *mem_ctx, 463 const char *user, const char *domain, const uint8_t nt_hash[16], 464 const DATA_BLOB *server_chal, 465 const DATA_BLOB *names_blob, 466 DATA_BLOB *lm_response, DATA_BLOB *nt_response, 467 DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) 468{ 469 uint8_t ntlm_v2_hash[16]; 470 471 /* We don't use the NT# directly. Instead we use it mashed up with 472 the username and domain. 473 This prevents username swapping during the auth exchange 474 */ 475 if (!ntv2_owf_gen(nt_hash, user, domain, true, ntlm_v2_hash)) { 476 return false; 477 } 478 479 if (nt_response) { 480 *nt_response = NTLMv2_generate_response(mem_ctx, 481 ntlm_v2_hash, server_chal, 482 names_blob); 483 if (user_session_key) { 484 *user_session_key = data_blob_talloc(mem_ctx, NULL, 16); 485 486 /* The NTLMv2 calculations also provide a session key, for signing etc later */ 487 /* use only the first 16 bytes of nt_response for session key */ 488 SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, user_session_key->data); 489 } 490 } 491 492 /* LMv2 */ 493 494 if (lm_response) { 495 *lm_response = LMv2_generate_response(mem_ctx, 496 ntlm_v2_hash, server_chal); 497 if (lm_session_key) { 498 *lm_session_key = data_blob_talloc(mem_ctx, NULL, 16); 499 500 /* The NTLMv2 calculations also provide a session key, for signing etc later */ 501 /* use only the first 16 bytes of lm_response for session key */ 502 SMBsesskeygen_ntv2(ntlm_v2_hash, lm_response->data, lm_session_key->data); 503 } 504 } 505 506 return true; 507} 508 509bool SMBNTLMv2encrypt(TALLOC_CTX *mem_ctx, 510 const char *user, const char *domain, 511 const char *password, 512 const DATA_BLOB *server_chal, 513 const DATA_BLOB *names_blob, 514 DATA_BLOB *lm_response, DATA_BLOB *nt_response, 515 DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) 516{ 517 uint8_t nt_hash[16]; 518 E_md4hash(password, nt_hash); 519 520 return SMBNTLMv2encrypt_hash(mem_ctx, 521 user, domain, nt_hash, server_chal, names_blob, 522 lm_response, nt_response, lm_session_key, user_session_key); 523} 524 525/*********************************************************** 526 encode a password buffer with a unicode password. The buffer 527 is filled with random data to make it harder to attack. 528************************************************************/ 529bool encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flags) 530{ 531 uint8_t new_pw[512]; 532 size_t new_pw_len; 533 534 /* the incoming buffer can be any alignment. */ 535 string_flags |= STR_NOALIGN; 536 537 new_pw_len = push_string(new_pw, 538 password, 539 sizeof(new_pw), string_flags); 540 541 memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len); 542 543 generate_random_buffer(buffer, 512 - new_pw_len); 544 545 /* 546 * The length of the new password is in the last 4 bytes of 547 * the data buffer. 548 */ 549 SIVAL(buffer, 512, new_pw_len); 550 ZERO_STRUCT(new_pw); 551 return true; 552} 553 554 555/*********************************************************** 556 decode a password buffer 557 *new_pw_len is the length in bytes of the possibly mulitbyte 558 returned password including termination. 559************************************************************/ 560 561bool decode_pw_buffer(TALLOC_CTX *ctx, 562 uint8_t in_buffer[516], 563 char **pp_new_pwrd, 564 size_t *new_pw_len, 565 charset_t string_charset) 566{ 567 int byte_len=0; 568 569 *pp_new_pwrd = NULL; 570 *new_pw_len = 0; 571 572 /* 573 Warning !!! : This function is called from some rpc call. 574 The password IN the buffer may be a UNICODE string. 575 The password IN new_pwrd is an ASCII string 576 If you reuse that code somewhere else check first. 577 */ 578 579 /* The length of the new password is in the last 4 bytes of the data buffer. */ 580 581 byte_len = IVAL(in_buffer, 512); 582 583#ifdef DEBUG_PASSWORD 584 dump_data(100, in_buffer, 516); 585#endif 586 587 /* Password cannot be longer than the size of the password buffer */ 588 if ( (byte_len < 0) || (byte_len > 512)) { 589 DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len)); 590 DEBUG(0, ("decode_pw_buffer: check that 'encrypt passwords = yes'\n")); 591 return false; 592 } 593 594 /* decode into the return buffer. */ 595 if (!convert_string_talloc(ctx, string_charset, CH_UNIX, 596 &in_buffer[512 - byte_len], 597 byte_len, 598 (void *)pp_new_pwrd, 599 new_pw_len, 600 false)) { 601 DEBUG(0, ("decode_pw_buffer: failed to convert incoming password\n")); 602 return false; 603 } 604 605#ifdef DEBUG_PASSWORD 606 DEBUG(100,("decode_pw_buffer: new_pwrd: ")); 607 dump_data(100, (uint8_t *)*pp_new_pwrd, *new_pw_len); 608 DEBUG(100,("multibyte len:%lu\n", (unsigned long int)*new_pw_len)); 609 DEBUG(100,("original char len:%d\n", byte_len/2)); 610#endif 611 612 return true; 613} 614 615/*********************************************************** 616 Decode an arc4 encrypted password change buffer. 617************************************************************/ 618 619void encode_or_decode_arc4_passwd_buffer(unsigned char pw_buf[532], const DATA_BLOB *psession_key) 620{ 621 struct MD5Context tctx; 622 unsigned char key_out[16]; 623 624 /* Confounder is last 16 bytes. */ 625 626 MD5Init(&tctx); 627 MD5Update(&tctx, &pw_buf[516], 16); 628 MD5Update(&tctx, psession_key->data, psession_key->length); 629 MD5Final(key_out, &tctx); 630 /* arc4 with key_out. */ 631 arcfour_crypt(pw_buf, key_out, 516); 632} 633 634/*********************************************************** 635 encode a password buffer with an already unicode password. The 636 rest of the buffer is filled with random data to make it harder to attack. 637************************************************************/ 638bool set_pw_in_buffer(uint8_t buffer[516], DATA_BLOB *password) 639{ 640 if (password->length > 512) { 641 return false; 642 } 643 644 memcpy(&buffer[512 - password->length], password->data, password->length); 645 646 generate_random_buffer(buffer, 512 - password->length); 647 648 /* 649 * The length of the new password is in the last 4 bytes of 650 * the data buffer. 651 */ 652 SIVAL(buffer, 512, password->length); 653 return true; 654} 655 656/*********************************************************** 657 decode a password buffer 658 *new_pw_size is the length in bytes of the extracted unicode password 659************************************************************/ 660bool extract_pw_from_buffer(TALLOC_CTX *mem_ctx, 661 uint8_t in_buffer[516], DATA_BLOB *new_pass) 662{ 663 int byte_len=0; 664 665 /* The length of the new password is in the last 4 bytes of the data buffer. */ 666 667 byte_len = IVAL(in_buffer, 512); 668 669#ifdef DEBUG_PASSWORD 670 dump_data(100, in_buffer, 516); 671#endif 672 673 /* Password cannot be longer than the size of the password buffer */ 674 if ( (byte_len < 0) || (byte_len > 512)) { 675 return false; 676 } 677 678 *new_pass = data_blob_talloc(mem_ctx, &in_buffer[512 - byte_len], byte_len); 679 680 if (!new_pass->data) { 681 return false; 682 } 683 684 return true; 685} 686 687 688/* encode a wkssvc_PasswordBuffer: 689 * 690 * similar to samr_CryptPasswordEx. Different: 8byte confounder (instead of 691 * 16byte), confounder in front of the 516 byte buffer (instead of after that 692 * buffer), calling MD5Update() first with session_key and then with confounder 693 * (vice versa in samr) - Guenther */ 694 695void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, 696 const char *pwd, 697 DATA_BLOB *session_key, 698 struct wkssvc_PasswordBuffer **pwd_buf) 699{ 700 uint8_t buffer[516]; 701 struct MD5Context ctx; 702 struct wkssvc_PasswordBuffer *my_pwd_buf = NULL; 703 DATA_BLOB confounded_session_key; 704 int confounder_len = 8; 705 uint8_t confounder[8]; 706 707 my_pwd_buf = talloc_zero(mem_ctx, struct wkssvc_PasswordBuffer); 708 if (!my_pwd_buf) { 709 return; 710 } 711 712 confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); 713 714 encode_pw_buffer(buffer, pwd, STR_UNICODE); 715 716 generate_random_buffer((uint8_t *)confounder, confounder_len); 717 718 MD5Init(&ctx); 719 MD5Update(&ctx, session_key->data, session_key->length); 720 MD5Update(&ctx, confounder, confounder_len); 721 MD5Final(confounded_session_key.data, &ctx); 722 723 arcfour_crypt_blob(buffer, 516, &confounded_session_key); 724 725 memcpy(&my_pwd_buf->data[0], confounder, confounder_len); 726 memcpy(&my_pwd_buf->data[8], buffer, 516); 727 728 data_blob_free(&confounded_session_key); 729 730 *pwd_buf = my_pwd_buf; 731} 732 733WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, 734 struct wkssvc_PasswordBuffer *pwd_buf, 735 DATA_BLOB *session_key, 736 char **pwd) 737{ 738 uint8_t buffer[516]; 739 struct MD5Context ctx; 740 size_t pwd_len; 741 742 DATA_BLOB confounded_session_key; 743 744 int confounder_len = 8; 745 uint8_t confounder[8]; 746 747 *pwd = NULL; 748 749 if (!pwd_buf) { 750 return WERR_BAD_PASSWORD; 751 } 752 753 if (session_key->length != 16) { 754 DEBUG(10,("invalid session key\n")); 755 return WERR_BAD_PASSWORD; 756 } 757 758 confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); 759 760 memcpy(&confounder, &pwd_buf->data[0], confounder_len); 761 memcpy(&buffer, &pwd_buf->data[8], 516); 762 763 MD5Init(&ctx); 764 MD5Update(&ctx, session_key->data, session_key->length); 765 MD5Update(&ctx, confounder, confounder_len); 766 MD5Final(confounded_session_key.data, &ctx); 767 768 arcfour_crypt_blob(buffer, 516, &confounded_session_key); 769 770 if (!decode_pw_buffer(mem_ctx, buffer, pwd, &pwd_len, CH_UTF16)) { 771 data_blob_free(&confounded_session_key); 772 return WERR_BAD_PASSWORD; 773 } 774 775 data_blob_free(&confounded_session_key); 776 777 return WERR_OK; 778} 779 780