1/* 2 Unix SMB/CIFS implementation. 3 SMB Signing Code 4 Copyright (C) Jeremy Allison 2003. 5 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20*/ 21 22#include "includes.h" 23 24/* Lookup a packet's MID (multiplex id) and figure out it's sequence number */ 25struct outstanding_packet_lookup { 26 uint16 mid; 27 uint32 reply_seq_num; 28 struct outstanding_packet_lookup *prev, *next; 29}; 30 31/* Store the data for an ongoing trans/trans2/nttrans operation. */ 32struct trans_info_context { 33 uint16 mid; 34 uint32 send_seq_num; 35 uint32 reply_seq_num; 36}; 37 38struct smb_basic_signing_context { 39 DATA_BLOB mac_key; 40 uint32 send_seq_num; 41 struct trans_info_context *trans_info; 42 struct outstanding_packet_lookup *outstanding_packet_list; 43}; 44 45static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list, 46 uint16 mid, uint32 reply_seq_num) 47{ 48 struct outstanding_packet_lookup *t; 49 50 /* Ensure we only add a mid once. */ 51 for (t = *list; t; t = t->next) { 52 if (t->mid == mid) { 53 return False; 54 } 55 } 56 57 t = SMB_XMALLOC_P(struct outstanding_packet_lookup); 58 ZERO_STRUCTP(t); 59 60 t->mid = mid; 61 t->reply_seq_num = reply_seq_num; 62 63 /* 64 * Add to the *start* of the list not the end of the list. 65 * This ensures that the *last* send sequence with this mid 66 * is returned by preference. 67 * This can happen if the mid wraps and one of the early 68 * mid numbers didn't get a reply and is still lurking on 69 * the list. JRA. Found by Fran Fabrizio <fran@cis.uab.edu>. 70 */ 71 72 DLIST_ADD(*list, t); 73 DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", 74 (unsigned int)reply_seq_num, (unsigned int)mid )); 75 return True; 76} 77 78static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, 79 uint16 mid, uint32 *reply_seq_num) 80{ 81 struct outstanding_packet_lookup *t; 82 83 for (t = *list; t; t = t->next) { 84 if (t->mid == mid) { 85 *reply_seq_num = t->reply_seq_num; 86 DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", 87 (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); 88 DLIST_REMOVE(*list, t); 89 SAFE_FREE(t); 90 return True; 91 } 92 } 93 return False; 94} 95 96/*********************************************************** 97 SMB signing - Common code before we set a new signing implementation 98************************************************************/ 99 100static BOOL cli_set_smb_signing_common(struct cli_state *cli) 101{ 102 if (!cli->sign_info.negotiated_smb_signing 103 && !cli->sign_info.mandatory_signing) { 104 return False; 105 } 106 107 if (cli->sign_info.doing_signing) { 108 return False; 109 } 110 111 if (cli->sign_info.free_signing_context) 112 cli->sign_info.free_signing_context(&cli->sign_info); 113 114 /* These calls are INCOMPATIBLE with SMB signing */ 115 cli->readbraw_supported = False; 116 cli->writebraw_supported = False; 117 118 return True; 119} 120 121/*********************************************************** 122 SMB signing - Common code for 'real' implementations 123************************************************************/ 124 125static BOOL set_smb_signing_real_common(struct smb_sign_info *si) 126{ 127 if (si->mandatory_signing) { 128 DEBUG(5, ("Mandatory SMB signing enabled!\n")); 129 } 130 131 si->doing_signing = True; 132 DEBUG(5, ("SMB signing enabled!\n")); 133 134 return True; 135} 136 137static void mark_packet_signed(char *outbuf) 138{ 139 uint16 flags2; 140 flags2 = SVAL(outbuf,smb_flg2); 141 flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; 142 SSVAL(outbuf,smb_flg2, flags2); 143} 144 145/*********************************************************** 146 SMB signing - NULL implementation - calculate a MAC to send. 147************************************************************/ 148 149static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) 150{ 151 /* we can't zero out the sig, as we might be trying to send a 152 session request - which is NBT-level, not SMB level and doesn't 153 have the field */ 154 return; 155} 156 157/*********************************************************** 158 SMB signing - NULL implementation - check a MAC sent by server. 159************************************************************/ 160 161static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) 162{ 163 return True; 164} 165 166/*********************************************************** 167 SMB signing - NULL implementation - free signing context 168************************************************************/ 169 170static void null_free_signing_context(struct smb_sign_info *si) 171{ 172 return; 173} 174 175/** 176 SMB signing - NULL implementation - setup the MAC key. 177 178 @note Used as an initialisation only - it will not correctly 179 shut down a real signing mechanism 180*/ 181 182static BOOL null_set_signing(struct smb_sign_info *si) 183{ 184 si->signing_context = NULL; 185 186 si->sign_outgoing_message = null_sign_outgoing_message; 187 si->check_incoming_message = null_check_incoming_message; 188 si->free_signing_context = null_free_signing_context; 189 190 return True; 191} 192 193/** 194 * Free the signing context 195 */ 196 197static void free_signing_context(struct smb_sign_info *si) 198{ 199 if (si->free_signing_context) { 200 si->free_signing_context(si); 201 si->signing_context = NULL; 202 } 203 204 null_set_signing(si); 205} 206 207 208static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq, BOOL must_be_ok) 209{ 210 if (good) { 211 212 if (!si->doing_signing) { 213 si->doing_signing = True; 214 } 215 216 if (!si->seen_valid) { 217 si->seen_valid = True; 218 } 219 220 } else { 221 if (!si->mandatory_signing && !si->seen_valid) { 222 223 if (!must_be_ok) { 224 return True; 225 } 226 /* Non-mandatory signing - just turn off if this is the first bad packet.. */ 227 DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and peer\n" 228 "isn't sending correct signatures. Turning off.\n")); 229 si->negotiated_smb_signing = False; 230 si->allow_smb_signing = False; 231 si->doing_signing = False; 232 free_signing_context(si); 233 return True; 234 } else if (!must_be_ok) { 235 /* This packet is known to be unsigned */ 236 return True; 237 } else { 238 /* Mandatory signing or bad packet after signing started - fail and disconnect. */ 239 if (seq) 240 DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq)); 241 return False; 242 } 243 } 244 return True; 245} 246 247/*********************************************************** 248 SMB signing - Simple implementation - calculate a MAC on the packet 249************************************************************/ 250 251static void simple_packet_signature(struct smb_basic_signing_context *data, 252 const uchar *buf, uint32 seq_number, 253 unsigned char calc_md5_mac[16]) 254{ 255 const size_t offset_end_of_sig = (smb_ss_field + 8); 256 unsigned char sequence_buf[8]; 257 struct MD5Context md5_ctx; 258 unsigned char key_buf[16]; 259 260 /* 261 * Firstly put the sequence number into the first 4 bytes. 262 * and zero out the next 4 bytes. 263 * 264 * We do this here, to avoid modifying the packet. 265 */ 266 267 DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number )); 268 269 SIVAL(sequence_buf, 0, seq_number); 270 SIVAL(sequence_buf, 4, 0); 271 272 /* Calculate the 16 byte MAC - but don't alter the data in the 273 incoming packet. 274 275 This makes for a bit of fussing about, but it's not too bad. 276 */ 277 MD5Init(&md5_ctx); 278 279 /* intialise with the key */ 280 MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); 281#if 0 282 /* JRA - apparently this is incorrect. */ 283 /* NB. When making and verifying SMB signatures, Windows apparently 284 zero-pads the key to 128 bits if it isn't long enough. 285 From Nalin Dahyabhai <nalin@redhat.com> */ 286 if (data->mac_key.length < sizeof(key_buf)) { 287 memset(key_buf, 0, sizeof(key_buf)); 288 MD5Update(&md5_ctx, key_buf, sizeof(key_buf) - data->mac_key.length); 289 } 290#endif 291 292 /* copy in the first bit of the SMB header */ 293 MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4); 294 295 /* copy in the sequence number, instead of the signature */ 296 MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); 297 298 /* copy in the rest of the packet in, skipping the signature */ 299 MD5Update(&md5_ctx, buf + offset_end_of_sig, 300 smb_len(buf) - (offset_end_of_sig - 4)); 301 302 /* calculate the MD5 sig */ 303 MD5Final(calc_md5_mac, &md5_ctx); 304} 305 306 307/*********************************************************** 308 SMB signing - Client implementation - send the MAC. 309************************************************************/ 310 311static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) 312{ 313 unsigned char calc_md5_mac[16]; 314 struct smb_basic_signing_context *data = si->signing_context; 315 uint32 send_seq_num; 316 317 if (!si->doing_signing) 318 return; 319 320 /* JRA Paranioa test - we should be able to get rid of this... */ 321 if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { 322 DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n", 323 smb_len(outbuf) )); 324 abort(); 325 } 326 327 /* mark the packet as signed - BEFORE we sign it...*/ 328 mark_packet_signed(outbuf); 329 330 if (data->trans_info) 331 send_seq_num = data->trans_info->send_seq_num; 332 else 333 send_seq_num = data->send_seq_num; 334 335 simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_num, calc_md5_mac); 336 337 DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n")); 338 dump_data(10, (const char *)calc_md5_mac, 8); 339 340 memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); 341 342/* cli->outbuf[smb_ss_field+2]=0; 343 Uncomment this to test if the remote server actually verifies signatures...*/ 344 345 if (data->trans_info) 346 return; 347 348 data->send_seq_num++; 349 store_sequence_for_reply(&data->outstanding_packet_list, 350 SVAL(outbuf,smb_mid), data->send_seq_num); 351 data->send_seq_num++; 352} 353 354/*********************************************************** 355 SMB signing - Client implementation - check a MAC sent by server. 356************************************************************/ 357 358static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) 359{ 360 BOOL good; 361 uint32 reply_seq_number; 362 uint32 saved_seq; 363 unsigned char calc_md5_mac[16]; 364 unsigned char *server_sent_mac; 365 366 struct smb_basic_signing_context *data = si->signing_context; 367 368 if (!si->doing_signing) 369 return True; 370 371 if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { 372 DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); 373 return False; 374 } 375 376 if (data->trans_info) { 377 reply_seq_number = data->trans_info->reply_seq_num; 378 } else if (!get_sequence_for_reply(&data->outstanding_packet_list, 379 SVAL(inbuf, smb_mid), &reply_seq_number)) { 380 DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n", 381 (unsigned int) SVAL(inbuf, smb_mid) )); 382 return False; 383 } 384 385 saved_seq = reply_seq_number; 386 simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); 387 388 server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; 389 good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); 390 391 if (!good) { 392 DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n")); 393 dump_data(5, (const char *)calc_md5_mac, 8); 394 395 DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); 396 dump_data(5, (const char *)server_sent_mac, 8); 397#if 1 /* JRATEST */ 398 { 399 int i; 400 reply_seq_number -= 5; 401 for (i = 0; i < 10; i++, reply_seq_number++) { 402 simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); 403 if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { 404 DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \ 405We were expecting seq %u\n", reply_seq_number, saved_seq )); 406 break; 407 } 408 } 409 } 410#endif /* JRATEST */ 411 412 } else { 413 DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); 414 dump_data(10, (const char *)server_sent_mac, 8); 415 } 416 return signing_good(inbuf, si, good, saved_seq, must_be_ok); 417} 418 419/*********************************************************** 420 SMB signing - Simple implementation - free signing context 421************************************************************/ 422 423static void simple_free_signing_context(struct smb_sign_info *si) 424{ 425 struct smb_basic_signing_context *data = si->signing_context; 426 struct outstanding_packet_lookup *list = data->outstanding_packet_list; 427 428 while (list) { 429 struct outstanding_packet_lookup *old_head = list; 430 DLIST_REMOVE(list, list); 431 SAFE_FREE(old_head); 432 } 433 434 data_blob_free(&data->mac_key); 435 436 if (data->trans_info) 437 SAFE_FREE(data->trans_info); 438 439 SAFE_FREE(si->signing_context); 440 441 return; 442} 443 444/*********************************************************** 445 SMB signing - Simple implementation - setup the MAC key. 446************************************************************/ 447 448BOOL cli_simple_set_signing(struct cli_state *cli, 449 const DATA_BLOB user_session_key, 450 const DATA_BLOB response) 451{ 452 struct smb_basic_signing_context *data; 453 454 if (!user_session_key.length) 455 return False; 456 457 if (!cli_set_smb_signing_common(cli)) { 458 return False; 459 } 460 461 if (!set_smb_signing_real_common(&cli->sign_info)) { 462 return False; 463 } 464 465 data = SMB_XMALLOC_P(struct smb_basic_signing_context); 466 memset(data, '\0', sizeof(*data)); 467 468 cli->sign_info.signing_context = data; 469 470 data->mac_key = data_blob(NULL, response.length + user_session_key.length); 471 472 memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); 473 474 DEBUG(10, ("cli_simple_set_signing: user_session_key\n")); 475 dump_data(10, (const char *)user_session_key.data, user_session_key.length); 476 477 if (response.length) { 478 memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); 479 DEBUG(10, ("cli_simple_set_signing: response_data\n")); 480 dump_data(10, (const char *)response.data, response.length); 481 } else { 482 DEBUG(10, ("cli_simple_set_signing: NULL response_data\n")); 483 } 484 485 dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); 486 487 /* Initialise the sequence number */ 488 data->send_seq_num = 0; 489 490 /* Initialise the list of outstanding packets */ 491 data->outstanding_packet_list = NULL; 492 493 cli->sign_info.sign_outgoing_message = client_sign_outgoing_message; 494 cli->sign_info.check_incoming_message = client_check_incoming_message; 495 cli->sign_info.free_signing_context = simple_free_signing_context; 496 497 return True; 498} 499 500/*********************************************************** 501 Tell client code we are in a multiple trans reply state. 502 We call this after the last outgoing trans2 packet (which 503 has incremented the sequence numbers), so we must save the 504 current mid and sequence number -2. 505************************************************************/ 506 507void cli_signing_trans_start(struct cli_state *cli, uint16 mid) 508{ 509 struct smb_basic_signing_context *data = cli->sign_info.signing_context; 510 uint32 reply_seq_num; 511 512 if (!cli->sign_info.doing_signing || !data) 513 return; 514 515 data->trans_info = SMB_XMALLOC_P(struct trans_info_context); 516 ZERO_STRUCTP(data->trans_info); 517 518 /* This ensures the sequence is pulled off the outstanding packet list */ 519 if (!get_sequence_for_reply(&data->outstanding_packet_list, 520 mid, &reply_seq_num)) { 521 DEBUG(1, ("get_sequence_for_reply failed - did we enter the trans signing state without sending a packet?\n")); 522 return; 523 } 524 525 data->trans_info->send_seq_num = reply_seq_num - 1; 526 data->trans_info->mid = mid; 527 data->trans_info->reply_seq_num = reply_seq_num; 528 529 DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ 530data->send_seq_num = %u\n", 531 (unsigned int)data->trans_info->mid, 532 (unsigned int)data->trans_info->reply_seq_num, 533 (unsigned int)data->trans_info->send_seq_num, 534 (unsigned int)data->send_seq_num )); 535} 536 537/*********************************************************** 538 Tell client code we are out of a multiple trans reply state. 539************************************************************/ 540 541void cli_signing_trans_stop(struct cli_state *cli) 542{ 543 struct smb_basic_signing_context *data = cli->sign_info.signing_context; 544 545 if (!cli->sign_info.doing_signing || !data) 546 return; 547 548 DEBUG(10,("cli_signing_trans_stop: freeing mid = %u, reply_seq_num = %u, send_seq_num = %u \ 549data->send_seq_num = %u\n", 550 (unsigned int)data->trans_info->mid, 551 (unsigned int)data->trans_info->reply_seq_num, 552 (unsigned int)data->trans_info->send_seq_num, 553 (unsigned int)data->send_seq_num )); 554 555 SAFE_FREE(data->trans_info); 556 data->trans_info = NULL; 557} 558 559/*********************************************************** 560 SMB signing - TEMP implementation - calculate a MAC to send. 561************************************************************/ 562 563static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) 564{ 565 /* mark the packet as signed - BEFORE we sign it...*/ 566 mark_packet_signed(outbuf); 567 568 /* I wonder what BSRSPYL stands for - but this is what MS 569 actually sends! */ 570 memcpy(&outbuf[smb_ss_field], "BSRSPYL ", 8); 571 return; 572} 573 574/*********************************************************** 575 SMB signing - TEMP implementation - check a MAC sent by server. 576************************************************************/ 577 578static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL foo) 579{ 580 return True; 581} 582 583/*********************************************************** 584 SMB signing - TEMP implementation - free signing context 585************************************************************/ 586 587static void temp_free_signing_context(struct smb_sign_info *si) 588{ 589 return; 590} 591 592/*********************************************************** 593 SMB signing - NULL implementation - setup the MAC key. 594************************************************************/ 595 596BOOL cli_null_set_signing(struct cli_state *cli) 597{ 598 return null_set_signing(&cli->sign_info); 599} 600 601/*********************************************************** 602 SMB signing - temp implementation - setup the MAC key. 603************************************************************/ 604 605BOOL cli_temp_set_signing(struct cli_state *cli) 606{ 607 if (!cli_set_smb_signing_common(cli)) { 608 return False; 609 } 610 611 cli->sign_info.signing_context = NULL; 612 613 cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message; 614 cli->sign_info.check_incoming_message = temp_check_incoming_message; 615 cli->sign_info.free_signing_context = temp_free_signing_context; 616 617 return True; 618} 619 620void cli_free_signing_context(struct cli_state *cli) 621{ 622 free_signing_context(&cli->sign_info); 623} 624 625/** 626 * Sign a packet with the current mechanism 627 */ 628 629void cli_calculate_sign_mac(struct cli_state *cli) 630{ 631 cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info); 632} 633 634/** 635 * Check a packet with the current mechanism 636 * @return False if we had an established signing connection 637 * which had a bad checksum, True otherwise. 638 */ 639 640BOOL cli_check_sign_mac(struct cli_state *cli) 641{ 642 if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) { 643 free_signing_context(&cli->sign_info); 644 return False; 645 } 646 return True; 647} 648 649/*********************************************************** 650 SMB signing - Server implementation - send the MAC. 651************************************************************/ 652 653static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) 654{ 655 unsigned char calc_md5_mac[16]; 656 struct smb_basic_signing_context *data = si->signing_context; 657 uint32 send_seq_number = data->send_seq_num; 658 BOOL was_deferred_packet = False; 659 uint16 mid; 660 661 if (!si->doing_signing) { 662 return; 663 } 664 665 /* JRA Paranioa test - we should be able to get rid of this... */ 666 if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { 667 DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n", 668 smb_len(outbuf) )); 669 abort(); 670 } 671 672 /* mark the packet as signed - BEFORE we sign it...*/ 673 mark_packet_signed(outbuf); 674 675 mid = SVAL(outbuf, smb_mid); 676 677 /* See if this is a reply for a deferred packet. */ 678 was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); 679 680 if (data->trans_info && (data->trans_info->mid == mid)) { 681 /* This is a reply in a trans stream. Use the sequence 682 * number associated with the stream mid. */ 683 send_seq_number = data->trans_info->send_seq_num; 684 } 685 686 simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac); 687 688 DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number)); 689 dump_data(10, (const char *)calc_md5_mac, 8); 690 691 memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); 692 693/* cli->outbuf[smb_ss_field+2]=0; 694 Uncomment this to test if the remote client actually verifies signatures...*/ 695 696 /* Don't mess with the sequence number for a deferred packet. */ 697 if (was_deferred_packet) { 698 return; 699 } 700 701 if (!data->trans_info) { 702 /* Always increment if not in a trans stream. */ 703 data->send_seq_num++; 704 } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) { 705 /* Increment if this is the first reply in a trans stream or a 706 * packet that doesn't belong to this stream (different mid). */ 707 data->send_seq_num++; 708 } 709} 710 711/*********************************************************** 712 Is an incoming packet an oplock break reply ? 713************************************************************/ 714 715static BOOL is_oplock_break(char *inbuf) 716{ 717 if (CVAL(inbuf,smb_com) != SMBlockingX) 718 return False; 719 720 if (!(CVAL(inbuf,smb_vwv3) & LOCKING_ANDX_OPLOCK_RELEASE)) 721 return False; 722 723 DEBUG(10,("is_oplock_break: Packet is oplock break\n")); 724 return True; 725} 726 727/*********************************************************** 728 SMB signing - Server implementation - check a MAC sent by server. 729************************************************************/ 730 731static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) 732{ 733 BOOL good; 734 struct smb_basic_signing_context *data = si->signing_context; 735 uint32 reply_seq_number = data->send_seq_num; 736 uint32 saved_seq; 737 unsigned char calc_md5_mac[16]; 738 unsigned char *server_sent_mac; 739 uint mid; 740 741 if (!si->doing_signing) 742 return True; 743 744 if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { 745 DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); 746 return False; 747 } 748 749 mid = SVAL(inbuf, smb_mid); 750 751 /* Is this part of a trans stream ? */ 752 if (data->trans_info && (data->trans_info->mid == mid)) { 753 /* If so we don't increment the sequence. */ 754 reply_seq_number = data->trans_info->reply_seq_num; 755 } else { 756 /* We always increment the sequence number. */ 757 data->send_seq_num++; 758 759 /* If we get an asynchronous oplock break reply and there 760 * isn't a reply pending we need to re-sync the sequence 761 * number. 762 */ 763 if (is_oplock_break(inbuf)) { 764 DEBUG(10,("srv_check_incoming_message: oplock break at seq num %u\n", data->send_seq_num)); 765 data->send_seq_num++; 766 } 767 } 768 769 saved_seq = reply_seq_number; 770 simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); 771 772 server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; 773 good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); 774 775 if (!good) { 776 777 if (saved_seq) { 778 DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", 779 (unsigned int)saved_seq)); 780 dump_data(5, (const char *)calc_md5_mac, 8); 781 782 DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", 783 (unsigned int)reply_seq_number)); 784 dump_data(5, (const char *)server_sent_mac, 8); 785 } 786 787#if 1 /* JRATEST */ 788 { 789 int i; 790 reply_seq_number -= 5; 791 for (i = 0; i < 10; i++, reply_seq_number++) { 792 simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); 793 if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { 794 DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \ 795We were expecting seq %u\n", reply_seq_number, saved_seq )); 796 break; 797 } 798 } 799 } 800#endif /* JRATEST */ 801 802 } else { 803 DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num)); 804 dump_data(10, (const char *)server_sent_mac, 8); 805 } 806 807 return (signing_good(inbuf, si, good, saved_seq, must_be_ok)); 808} 809 810/*********************************************************** 811 SMB signing - server API's. 812************************************************************/ 813 814static struct smb_sign_info srv_sign_info = { 815 null_sign_outgoing_message, 816 null_check_incoming_message, 817 null_free_signing_context, 818 NULL, 819 False, 820 False, 821 False, 822 False 823}; 824 825/*********************************************************** 826 Turn signing off or on for oplock break code. 827************************************************************/ 828 829BOOL srv_oplock_set_signing(BOOL onoff) 830{ 831 BOOL ret = srv_sign_info.doing_signing; 832 srv_sign_info.doing_signing = onoff; 833 return ret; 834} 835 836/*********************************************************** 837 Called to validate an incoming packet from the client. 838************************************************************/ 839 840BOOL srv_check_sign_mac(char *inbuf, BOOL must_be_ok) 841{ 842 /* Check if it's a session keepalive. */ 843 if(CVAL(inbuf,0) == SMBkeepalive) 844 return True; 845 846 return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok); 847} 848 849/*********************************************************** 850 Called to sign an outgoing packet to the client. 851************************************************************/ 852 853void srv_calculate_sign_mac(char *outbuf) 854{ 855 /* Check if it's a session keepalive. */ 856 /* JRA Paranioa test - do we ever generate these in the server ? */ 857 if(CVAL(outbuf,0) == SMBkeepalive) 858 return; 859 860 srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info); 861} 862 863/*********************************************************** 864 Called by server to defer an outgoing packet. 865************************************************************/ 866 867void srv_defer_sign_response(uint16 mid) 868{ 869 struct smb_basic_signing_context *data; 870 871 if (!srv_sign_info.doing_signing) 872 return; 873 874 data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; 875 876 if (!data) 877 return; 878 879 /* 880 * Ensure we only store this mid reply once... 881 */ 882 883 if (store_sequence_for_reply(&data->outstanding_packet_list, mid, data->send_seq_num)) { 884 data->send_seq_num++; 885 } 886} 887 888/*********************************************************** 889 Called to remove sequence records when a deferred packet is 890 cancelled by mid. This should never find one.... 891************************************************************/ 892 893void srv_cancel_sign_response(uint16 mid) 894{ 895 struct smb_basic_signing_context *data; 896 uint32 dummy_seq; 897 898 if (!srv_sign_info.doing_signing) 899 return; 900 901 data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; 902 903 if (!data) 904 return; 905 906 DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid )); 907 908 while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq)) 909 ; 910} 911 912/*********************************************************** 913 Called by server negprot when signing has been negotiated. 914************************************************************/ 915 916void srv_set_signing_negotiated(void) 917{ 918 srv_sign_info.allow_smb_signing = True; 919 srv_sign_info.negotiated_smb_signing = True; 920 if (lp_server_signing() == Required) 921 srv_sign_info.mandatory_signing = True; 922 923 srv_sign_info.sign_outgoing_message = temp_sign_outgoing_message; 924 srv_sign_info.check_incoming_message = temp_check_incoming_message; 925 srv_sign_info.free_signing_context = temp_free_signing_context; 926} 927 928/*********************************************************** 929 Returns whether signing is active. We can't use sendfile or raw 930 reads/writes if it is. 931************************************************************/ 932 933BOOL srv_is_signing_active(void) 934{ 935 return srv_sign_info.doing_signing; 936} 937 938 939/*********************************************************** 940 Returns whether signing is negotiated. We can't use it unless it was 941 in the negprot. 942************************************************************/ 943 944BOOL srv_is_signing_negotiated(void) 945{ 946 return srv_sign_info.negotiated_smb_signing; 947} 948 949/*********************************************************** 950 Returns whether signing is actually happening 951************************************************************/ 952 953BOOL srv_signing_started(void) 954{ 955 struct smb_basic_signing_context *data; 956 957 if (!srv_sign_info.doing_signing) { 958 return False; 959 } 960 961 data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; 962 if (!data) 963 return False; 964 965 if (data->send_seq_num == 0) { 966 return False; 967 } 968 969 return True; 970} 971 972 973/*********************************************************** 974 Tell server code we are in a multiple trans reply state. 975************************************************************/ 976 977void srv_signing_trans_start(uint16 mid) 978{ 979 struct smb_basic_signing_context *data; 980 981 if (!srv_sign_info.doing_signing) 982 return; 983 984 data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; 985 if (!data) 986 return; 987 988 data->trans_info = SMB_XMALLOC_P(struct trans_info_context); 989 ZERO_STRUCTP(data->trans_info); 990 991 data->trans_info->reply_seq_num = data->send_seq_num-1; 992 data->trans_info->mid = mid; 993 data->trans_info->send_seq_num = data->send_seq_num; 994 995 DEBUG(10,("srv_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ 996data->send_seq_num = %u\n", 997 (unsigned int)mid, 998 (unsigned int)data->trans_info->reply_seq_num, 999 (unsigned int)data->trans_info->send_seq_num, 1000 (unsigned int)data->send_seq_num )); 1001} 1002 1003/*********************************************************** 1004 Tell server code we are out of a multiple trans reply state. 1005************************************************************/ 1006 1007void srv_signing_trans_stop(void) 1008{ 1009 struct smb_basic_signing_context *data; 1010 1011 if (!srv_sign_info.doing_signing) 1012 return; 1013 1014 data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; 1015 if (!data || !data->trans_info) 1016 return; 1017 1018 DEBUG(10,("srv_signing_trans_stop: removing mid = %u, reply_seq_num = %u, send_seq_num = %u \ 1019data->send_seq_num = %u\n", 1020 (unsigned int)data->trans_info->mid, 1021 (unsigned int)data->trans_info->reply_seq_num, 1022 (unsigned int)data->trans_info->send_seq_num, 1023 (unsigned int)data->send_seq_num )); 1024 1025 SAFE_FREE(data->trans_info); 1026 data->trans_info = NULL; 1027} 1028 1029/*********************************************************** 1030 Turn on signing from this packet onwards. 1031************************************************************/ 1032 1033void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response) 1034{ 1035 struct smb_basic_signing_context *data; 1036 1037 if (!user_session_key.length) 1038 return; 1039 1040 if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) { 1041 DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n", 1042 (unsigned int)srv_sign_info.negotiated_smb_signing, 1043 (unsigned int)srv_sign_info.mandatory_signing )); 1044 return; 1045 } 1046 1047 /* Once we've turned on, ignore any more sessionsetups. */ 1048 if (srv_sign_info.doing_signing) { 1049 return; 1050 } 1051 1052 if (srv_sign_info.free_signing_context) 1053 srv_sign_info.free_signing_context(&srv_sign_info); 1054 1055 srv_sign_info.doing_signing = True; 1056 1057 data = SMB_XMALLOC_P(struct smb_basic_signing_context); 1058 memset(data, '\0', sizeof(*data)); 1059 1060 srv_sign_info.signing_context = data; 1061 1062 data->mac_key = data_blob(NULL, response.length + user_session_key.length); 1063 1064 memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); 1065 if (response.length) 1066 memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); 1067 1068 dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); 1069 1070 DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n", 1071 BOOLSTR(srv_sign_info.negotiated_smb_signing), 1072 BOOLSTR(srv_sign_info.mandatory_signing) )); 1073 1074 /* Initialise the sequence number */ 1075 data->send_seq_num = 0; 1076 1077 /* Initialise the list of outstanding packets */ 1078 data->outstanding_packet_list = NULL; 1079 1080 srv_sign_info.sign_outgoing_message = srv_sign_outgoing_message; 1081 srv_sign_info.check_incoming_message = srv_check_incoming_message; 1082 srv_sign_info.free_signing_context = simple_free_signing_context; 1083} 1084